Remove ClassVerificationFailureDetector

It is no longer being used. A method that it uses for checking API levels has been deprecated, and it doesn't seem worth reworking the check to work with the new implementation of ApiConstraint.

Bug: 378110980
Test: presubmit
Change-Id: Icd4daaa9b9f999f423bf9010024326d96bb5d48c
diff --git a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt b/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
deleted file mode 100644
index ef3e421..0000000
--- a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
+++ /dev/null
@@ -1,1249 +0,0 @@
-/*
- * Copyright 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.
- */
-
-@file:Suppress("UnstableApiUsage")
-
-package androidx.build.lint
-
-import com.android.SdkConstants.ATTR_VALUE
-import com.android.tools.lint.checks.ApiLookup
-import com.android.tools.lint.checks.ApiLookup.equivalentName
-import com.android.tools.lint.checks.DesugaredMethodLookup
-import com.android.tools.lint.client.api.UElementHandler
-import com.android.tools.lint.detector.api.Category
-import com.android.tools.lint.detector.api.Context
-import com.android.tools.lint.detector.api.Desugaring
-import com.android.tools.lint.detector.api.Detector
-import com.android.tools.lint.detector.api.Implementation
-import com.android.tools.lint.detector.api.Incident
-import com.android.tools.lint.detector.api.Issue
-import com.android.tools.lint.detector.api.JavaContext
-import com.android.tools.lint.detector.api.LintFix
-import com.android.tools.lint.detector.api.Location
-import com.android.tools.lint.detector.api.Scope
-import com.android.tools.lint.detector.api.Severity
-import com.android.tools.lint.detector.api.SourceCodeScanner
-import com.android.tools.lint.detector.api.UastLintUtils.Companion.getLongAttribute
-import com.android.tools.lint.detector.api.VersionChecks
-import com.android.tools.lint.detector.api.VersionChecks.Companion.REQUIRES_API_ANNOTATION
-import com.android.tools.lint.detector.api.getInternalMethodName
-import com.android.tools.lint.detector.api.isKotlin
-import com.android.tools.lint.detector.api.minSdkLessThan
-import com.intellij.psi.PsiAnonymousClass
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiClassType
-import com.intellij.psi.PsiCompiledElement
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiEllipsisType
-import com.intellij.psi.PsiExpressionList
-import com.intellij.psi.PsiMethod
-import com.intellij.psi.PsiMethodCallExpression
-import com.intellij.psi.PsiModifierListOwner
-import com.intellij.psi.PsiParenthesizedExpression
-import com.intellij.psi.PsiSuperExpression
-import com.intellij.psi.PsiType
-import com.intellij.psi.util.PsiTreeUtil
-import com.intellij.psi.util.PsiTypesUtil
-import com.intellij.psi.util.PsiUtil
-import kotlin.math.min
-import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
-import org.jetbrains.kotlin.psi.KtBinaryExpression
-import org.jetbrains.kotlin.psi.KtCallExpression
-import org.jetbrains.kotlin.psi.KtNamedFunction
-import org.jetbrains.kotlin.psi.KtReturnExpression
-import org.jetbrains.kotlin.psi.KtValueArgument
-import org.jetbrains.uast.UBinaryExpression
-import org.jetbrains.uast.UCallExpression
-import org.jetbrains.uast.UClass
-import org.jetbrains.uast.UElement
-import org.jetbrains.uast.UExpression
-import org.jetbrains.uast.UInstanceExpression
-import org.jetbrains.uast.UMethod
-import org.jetbrains.uast.UParenthesizedExpression
-import org.jetbrains.uast.UReturnExpression
-import org.jetbrains.uast.USuperExpression
-import org.jetbrains.uast.UThisExpression
-import org.jetbrains.uast.UastBinaryOperator
-import org.jetbrains.uast.getContainingUClass
-import org.jetbrains.uast.getContainingUMethod
-import org.jetbrains.uast.getParentOfType
-import org.jetbrains.uast.toUElement
-import org.jetbrains.uast.util.isConstructorCall
-import org.jetbrains.uast.util.isMethodCall
-
-/**
- * This check detects references to platform APIs that are likely to cause class verification
- * failures.
- *
- * <p>
- * Specifically, this check looks for references to APIs that were added prior to the library's
- * minSdkVersion and therefore may not exist on the run-time classpath. If the class verifier
- * detects such a reference, e.g. while verifying a class containing the reference, it will abort
- * verification. This will prevent the class from being optimized, resulting in potentially severe
- * performance losses.
- *
- * <p>
- * See Chromium's excellent guide to Class Verification Failures for more information:
- * https://chromium.googlesource.com/chromium/src/+/HEAD/build/android/docs/class_verification_failures.md
- */
-class ClassVerificationFailureDetector : Detector(), SourceCodeScanner {
-    private var apiDatabase: ApiLookup? = null
-
-    /** Copied from ApiDetector.kt */
-    override fun beforeCheckRootProject(context: Context) {
-        if (apiDatabase == null) {
-            apiDatabase = ApiLookup.get(context.client, context.project.buildTarget)
-            // We can't look up the minimum API required by the project here:
-            // The manifest file hasn't been processed yet in the -before- project hook.
-            // For now it's initialized lazily in getMinSdk(Context), but the
-            // lint infrastructure should be fixed to parse manifest file up front.
-        }
-    }
-
-    /** Copied from ApiDetector.kt */
-    private fun getMinSdk(context: Context): Int {
-        val project = if (context.isGlobalAnalysis()) context.mainProject else context.project
-        return if (!project.isAndroidProject) {
-            // Don't flag API checks in non-Android projects
-            Integer.MAX_VALUE
-        } else {
-            project.minSdkVersion.featureLevel
-        }
-    }
-
-    /** Copied from ApiDetector.kt */
-    override fun createUastHandler(context: JavaContext): UElementHandler? {
-        if (apiDatabase == null || context.isTestSource && !context.driver.checkTestSources) {
-            return null
-        }
-        val project = if (context.isGlobalAnalysis()) context.mainProject else context.project
-        return if (project.isAndroidProject) {
-            ApiVisitor(context)
-        } else {
-            null
-        }
-    }
-
-    override fun getApplicableUastTypes() =
-        listOf(UCallExpression::class.java, UExpression::class.java)
-
-    /**
-     * Modified from ApiDetector.kt
-     *
-     * Changes:
-     * - Only the `visitCall` method has been copied over
-     */
-    private inner class ApiVisitor(private val context: JavaContext) : UElementHandler() {
-
-        /**
-         * Checks for instances of potential verification failures in implicit casting -- when an
-         * expression is of one type but used as a different type.
-         *
-         * This is an issue when the expected type exists in an API level but the actual type does
-         * not. The verifier will see an Object used as another type, which isn't valid.
-         *
-         * This can be fixed by adding an explicit cast to the expected type.
-         */
-        override fun visitExpression(node: UExpression) {
-            val psi = node.sourcePsi
-            // Some PsiElements are multiple UElements. Only inspect one to prevent duplicate issues
-            if (psi != null && psi.toUElement() != node) return
-
-            // Get the expression type and expected type based on the expression's usage
-            val actualType = node.getExpressionType() ?: return
-            val actualTypeStr = actualType.canonicalText
-            val actualTypeApi = getMinApiOfClass(actualTypeStr) ?: return
-
-            // Not an issue if this is contained within a class annotated with @RequiresApi
-            if (node.containedInRequiresApiClass(actualTypeApi)) return
-
-            val expectedType = getExpectedTypeByParent(node) ?: return
-            val expectedTypeStr = expectedType.canonicalText
-            val expectedTypeApi = getMinApiOfClass(expectedTypeStr) ?: return
-
-            if (!isInvalidCast(actualTypeStr, expectedTypeStr, actualTypeApi, expectedTypeApi)) {
-                return
-            }
-
-            // This can currently only do an autofix for Java source, not Kotlin.
-            val fix =
-                if (isKotlin(node.lang)) {
-                    null
-                } else {
-                    createCastFix(node, actualType, expectedType, actualTypeApi)
-                }
-
-            val incident =
-                Incident(context)
-                    .issue(IMPLICIT_CAST_ISSUE)
-                    .fix(fix)
-                    .location(context.getLocation(node))
-                    .message(
-                        "This expression has type $actualTypeStr (introduced in API level " +
-                            "$actualTypeApi) but it used as type $expectedTypeStr (introduced in API " +
-                            "level $expectedTypeApi). Run-time class verification will not be able to " +
-                            "validate this implicit cast on devices between these API levels."
-                    )
-                    .scope(node)
-
-            // If the actual type exists at minSdk, this isn't an invalid cast -- report the
-            // incident, conditional on minSdk being lower than the actual type API.
-            // (This needs to be reported provisionally with a constraint instead of manually
-            // looking up the minSdk and comparing because of partial analysis mode.)
-            context.report(incident, minSdkLessThan(actualTypeApi))
-        }
-
-        /**
-         * Modified from ApiDetector.kt
-         *
-         * Changes:
-         * - Replaced the `method == null` conditional block with elvis operator `return`
-         */
-        override fun visitCallExpression(node: UCallExpression) {
-            val method = node.resolve() ?: return
-
-            visitCall(method, node, node)
-        }
-
-        /**
-         * Modified from ApiDetector.kt
-         *
-         * Changes:
-         * - Removed cast checking on parameter list
-         * - Removed PsiCompiledElement check
-         * - Removed special-casing of Support Library
-         * - Removed SimpleDateFormat and Animator checks
-         * - Removed check for suppression
-         * - Removed signature generation
-         * - Removed unused values (signature, desugaring, fqcn)
-         * - Replaced `report` call with a call to `visitNewApiCall`
-         */
-        private fun visitCall(method: PsiMethod, call: UCallExpression, reference: UElement) {
-            val apiDatabase = apiDatabase ?: return
-            val containingClass = method.containingClass ?: return
-
-            // Change: Removed cast checking on parameter list
-
-            // Change: Removed PsiCompiledElement check
-
-            val evaluator = context.evaluator
-            val owner =
-                evaluator.getQualifiedName(containingClass) ?: return // Couldn't resolve type
-
-            // Change: Removed special-casing of Support library
-
-            if (!apiDatabase.containsClass(owner)) {
-                return
-            }
-
-            val name = getInternalMethodName(method)
-            val desc =
-                evaluator.getMethodDescription(
-                    method,
-                    includeName = false,
-                    includeReturn = false
-                ) // Couldn't compute description of method for some reason; probably
-                    // failure to resolve parameter types
-                    ?: return
-
-            // Change: Removed SimpleDateFormat and Animator checks
-            @Suppress("DEPRECATION") // b/262915628
-            var api = apiDatabase.getMethodVersion(owner, name, desc)
-            if (api == -1) {
-                return
-            }
-            val minSdk = getMinSdk(context)
-            if (api <= minSdk) {
-                return
-            }
-
-            val receiver =
-                if (call.isMethodCall()) {
-                    call.receiver
-                } else {
-                    null
-                }
-
-            // The lint API database contains two optimizations:
-            // First, all members that were available in API 1 are omitted from the database,
-            // since that saves about half of the size of the database, and for API check
-            // purposes, we don't need to distinguish between "doesn't exist" and "available
-            // in all versions".
-
-            // Second, all inherited members were inlined into each class, so that it doesn't
-            // have to do a repeated search up the inheritance chain.
-            //
-            // Unfortunately, in this custom PSI detector, we look up the real resolved method,
-            // which can sometimes have a different minimum API.
-            //
-            // For example, SQLiteDatabase had a close() method from API 1. Therefore, calling
-            // SQLiteDatabase is supported in all versions. However, it extends SQLiteClosable,
-            // which in API 16 added "implements Closable". In this detector, if we have the
-            // following code:
-            //     void test(SQLiteDatabase db) { db.close }
-            // here the call expression will be the close method on type SQLiteClosable. And
-            // that will result in an API requirement of API 16, since the close method it now
-            // resolves to is in API 16.
-            //
-            // To work around this, we can now look up the type of the call expression ("db"
-            // in the above, but it could have been more complicated), and if that's a
-            // different type than the type of the method, we look up *that* method from
-            // lint's database instead. Furthermore, it's possible for that method to return
-            // "-1" and we can't tell if that means "doesn't exist" or "present in API 1", we
-            // then check the package prefix to see whether we know it's an API method whose
-            // members should all have been inlined.
-            if (call.isMethodCall()) {
-                if (
-                    receiver != null &&
-                        receiver !is UThisExpression &&
-                        receiver !is PsiSuperExpression
-                ) {
-                    val receiverType = receiver.getExpressionType()
-                    if (receiverType is PsiClassType) {
-                        val containingType = context.evaluator.getClassType(containingClass)
-                        val inheritanceChain = getInheritanceChain(receiverType, containingType)
-                        if (inheritanceChain != null) {
-                            for (type in inheritanceChain) {
-                                val expressionOwner = evaluator.getQualifiedName(type)
-                                if (expressionOwner != null && expressionOwner != owner) {
-                                    @Suppress("DEPRECATION") // b/262915628
-                                    val specificApi =
-                                        apiDatabase.getMethodVersion(expressionOwner, name, desc)
-                                    if (specificApi == -1) {
-                                        if (apiDatabase.isRelevantOwner(expressionOwner)) {
-                                            return
-                                        }
-                                    } else if (specificApi <= minSdk) {
-                                        return
-                                    } else {
-                                        // For example, for Bundle#getString(String,String) the API
-                                        // level
-                                        // is 12, whereas for BaseBundle#getString(String,String)
-                                        // the API
-                                        // level is 21. If the code specified a Bundle instead of
-                                        // a BaseBundle, reported the Bundle level in the error
-                                        // message
-                                        // instead.
-                                        if (specificApi < api) {
-                                            api = specificApi
-                                        }
-                                        api = min(specificApi, api)
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    // Unqualified call; need to search in our super hierarchy
-                    var cls: PsiClass? = null
-                    val receiverType = call.receiverType
-                    if (receiverType is PsiClassType) {
-                        cls = receiverType.resolve()
-                    }
-
-                    if (receiver is UThisExpression || receiver is USuperExpression) {
-                        val pte = receiver as UInstanceExpression
-                        val resolved = pte.resolve()
-                        if (resolved is PsiClass) {
-                            cls = resolved
-                        }
-                    }
-
-                    while (cls != null) {
-                        if (cls is PsiAnonymousClass) {
-                            // If it's an unqualified call in an anonymous class, we need to
-                            // rely on the resolve method to find out whether the method is
-                            // picked up from the anonymous class chain or any outer classes
-                            var found = false
-                            val anonymousBaseType = cls.baseClassType
-                            val anonymousBase = anonymousBaseType.resolve()
-                            if (
-                                anonymousBase != null &&
-                                    anonymousBase.isInheritor(containingClass, true)
-                            ) {
-                                cls = anonymousBase
-                                found = true
-                            } else {
-                                val surroundingBaseType =
-                                    PsiTreeUtil.getParentOfType(cls, PsiClass::class.java, true)
-                                if (
-                                    surroundingBaseType != null &&
-                                        surroundingBaseType.isInheritor(containingClass, true)
-                                ) {
-                                    cls = surroundingBaseType
-                                    found = true
-                                }
-                            }
-                            if (!found) {
-                                break
-                            }
-                        }
-                        val expressionOwner = evaluator.getQualifiedName(cls)
-                        if (
-                            expressionOwner == null ||
-                                equivalentName(expressionOwner, "java/lang/Object")
-                        ) {
-                            break
-                        }
-                        @Suppress("DEPRECATION") // b/262915628
-                        val specificApi = apiDatabase.getMethodVersion(expressionOwner, name, desc)
-                        if (specificApi == -1) {
-                            if (apiDatabase.isRelevantOwner(expressionOwner)) {
-                                break
-                            }
-                        } else if (specificApi <= minSdk) {
-                            return
-                        } else {
-                            if (specificApi < api) {
-                                api = specificApi
-                            }
-                            api = min(specificApi, api)
-                            break
-                        }
-                        cls = cls.superClass
-                    }
-                }
-            }
-
-            // Change: Removed check for suppression
-
-            if (receiver != null || call.isMethodCall()) {
-                var target: PsiClass? = null
-                if (!method.isConstructor) {
-                    if (receiver != null) {
-                        val type = receiver.getExpressionType()
-                        if (type is PsiClassType) {
-                            target = type.resolve()
-                        }
-                    } else {
-                        target = call.getContainingUClass()?.javaPsi
-                    }
-                }
-
-                // Look to see if there's a possible local receiver
-                if (target != null) {
-                    val methods = target.findMethodsBySignature(method, true)
-                    if (methods.size > 1) {
-                        for (m in methods) {
-                            //noinspection LintImplPsiEquals
-                            if (method != m) {
-                                val provider = m.containingClass
-                                if (provider != null) {
-                                    val methodOwner = evaluator.getQualifiedName(provider)
-                                    if (methodOwner != null) {
-                                        @Suppress("DEPRECATION") // b/262915628
-                                        val methodApi =
-                                            apiDatabase.getMethodVersion(methodOwner, name, desc)
-                                        if (methodApi == -1 || methodApi <= minSdk) {
-                                            // Yes, we found another call that doesn't have an API
-                                            // requirement
-                                            return
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                // If you're simply calling super.X from method X, even if method X is in a higher
-                // API level than the minSdk, we're generally safe; that method should only be
-                // called by the framework on the right API levels. (There is a danger of somebody
-                // calling that method locally in other contexts, but this is hopefully unlikely.)
-                if (receiver is USuperExpression) {
-                    val containingMethod = call.getContainingUMethod()?.javaPsi
-                    if (
-                        containingMethod != null &&
-                            name == containingMethod.name &&
-                            evaluator.areSignaturesEqual(method, containingMethod) &&
-                            // We specifically exclude constructors from this check, because we
-                            // do want to flag constructors requiring the new API level; it's
-                            // highly likely that the constructor is called by local code so
-                            // you should specifically investigate this as a developer
-                            !method.isConstructor
-                    ) {
-                        return
-                    }
-                }
-            }
-
-            // Builtin R8 desugaring, such as rewriting compare calls (see b/36390874)
-            if (
-                owner.startsWith("java.") &&
-                    DesugaredMethodLookup.isDesugaredMethod(
-                        owner,
-                        name,
-                        desc,
-                        context.sourceSetType
-                    )
-            ) {
-                return
-            }
-
-            // These methods are not included in the R8 backported list so handle them manually
-            // the way R8 seems to
-            if (
-                api == 19 &&
-                    owner == "java.lang.Throwable" &&
-                    (name == "addSuppressed" && desc == "(Ljava.lang.Throwable;)" ||
-                        name == "getSuppressed" && desc == "()")
-            ) {
-                if (context.project.isDesugaring(Desugaring.TRY_WITH_RESOURCES)) {
-                    return
-                }
-            }
-
-            // Change: Removed signature generation
-
-            val nameIdentifier = call.methodIdentifier
-            val location =
-                if (call.isConstructorCall() && call.classReference != null) {
-                    context.getRangeLocation(call, 0, call.classReference!!, 0)
-                } else if (nameIdentifier != null) {
-                    context.getLocation(nameIdentifier)
-                } else {
-                    context.getLocation(reference)
-                }
-
-            // Change: Replaced `report` call with a call to `visitNewApiCall`
-            visitNewApiCall(call, method, api, reference, location)
-        }
-
-        /**
-         * Walks up the class hierarchy from the element to find if there is any RequiresApi
-         * annotation for [minApi] or higher.
-         */
-        fun UElement.containedInRequiresApiClass(minApi: Int): Boolean {
-            var classUnderInspection: UClass? = this.getContainingUClass() ?: return false
-
-            while (classUnderInspection != null) {
-                val potentialRequiresApiVersion =
-                    getRequiresApiFromAnnotations(classUnderInspection.javaPsi)
-
-                if (potentialRequiresApiVersion >= minApi) {
-                    return true
-                }
-
-                classUnderInspection = classUnderInspection.getContainingUClass()
-            }
-            return false
-        }
-
-        fun visitNewApiCall(
-            call: UCallExpression,
-            method: PsiMethod,
-            api: Int,
-            reference: UElement,
-            location: Location
-        ) {
-            if (call.containedInRequiresApiClass(api)) return
-
-            // call.getContainingUClass()!! refers to the direct parent class of this method
-            val containingClassName = call.getContainingUClass()!!.qualifiedName.toString()
-            val lintFix = createCallFix(method, call, api)
-            val incident =
-                Incident(context)
-                    .fix(lintFix)
-                    .issue(METHOD_CALL_ISSUE)
-                    .location(location)
-                    .message(
-                        "This call references a method added in API level $api; however, the " +
-                            "containing class $containingClassName is reachable from earlier API " +
-                            "levels and will fail run-time class verification."
-                    )
-                    .scope(reference)
-
-            context.report(incident)
-        }
-
-        /**
-         * Attempts to create a [LintFix] for the call to specified method.
-         *
-         * @return a lint fix, or `null` if no fix could be created
-         */
-        private fun createCallFix(method: PsiMethod, call: UCallExpression, api: Int): LintFix? {
-            val callPsi = call.sourcePsi ?: return null
-            if (isKotlin(callPsi.language)) {
-                // We only support Java right now.
-                return null
-            }
-
-            // The host class should never be null if we're looking at Java code.
-            val callContainingClass = call.getContainingUClass() ?: return null
-
-            val (wrapperMethodName, wrapperMethodParams, methodForInsertion) =
-                generateWrapperMethod(
-                    method,
-                    // Find what type the result of this call is used as
-                    getExpectedTypeByParent(call),
-                    call.valueArguments.map { it.getExpressionType() }
-                ) ?: return null
-
-            val (wrapperClassName, insertionPoint, insertionSource) =
-                generateInsertionSource(
-                    api,
-                    callContainingClass,
-                    wrapperMethodName,
-                    wrapperMethodParams,
-                    methodForInsertion
-                )
-
-            val replacementCall =
-                generateWrapperCall(
-                    method,
-                    call.receiver,
-                    call.valueArguments,
-                    wrapperClassName,
-                    wrapperMethodName
-                )
-
-            return createCompositeFix(call, replacementCall, insertionPoint, insertionSource)
-        }
-
-        /**
-         * Creates an autofix for an invalid cast (for Java source only) by creating a method in an
-         * Api[actualTypeApi]Impl static inner class which casts from [actualType] to [expectedType]
-         */
-        private fun createCastFix(
-            node: UExpression,
-            actualType: PsiType,
-            expectedType: PsiType,
-            actualTypeApi: Int
-        ): LintFix? {
-            val (wrapperMethodName, wrapperMethod) = generateCastingMethod(actualType, expectedType)
-            val containingClass = node.getContainingUClass() ?: return null
-            val (wrapperClassName, insertionPoint, insertionSource) =
-                generateInsertionSource(
-                    actualTypeApi,
-                    containingClass,
-                    wrapperMethodName,
-                    listOf(actualType),
-                    wrapperMethod
-                )
-            val wrapperCall = "$wrapperClassName.$wrapperMethodName(${node.asSourceString()})"
-
-            return createCompositeFix(node, wrapperCall, insertionPoint, insertionSource)
-        }
-
-        /**
-         * Creates a [LintFix] which replaces the [node] with the [replacementCall] and adds the
-         * [insertionSource] at the [insertionPoint], if they exist.
-         */
-        fun createCompositeFix(
-            node: UElement,
-            replacementCall: String,
-            insertionPoint: Location?,
-            insertionSource: String?
-        ): LintFix {
-            val fix = fix().name("Extract to static inner class").composite()
-
-            if (insertionPoint != null) {
-                fix.add(
-                    fix()
-                        .replace()
-                        .range(insertionPoint)
-                        .beginning()
-                        .with(insertionSource)
-                        .shortenNames()
-                        .build()
-                )
-            }
-
-            fix.add(
-                fix()
-                    .replace()
-                    .range(context.getLocation(node))
-                    .with(replacementCall)
-                    .shortenNames()
-                    .build()
-            )
-
-            return fix.build()
-        }
-
-        /** Find what type the parent of the element is expecting the element to be. */
-        private fun getExpectedTypeByParent(element: UElement): PsiType? {
-            val psi = element.sourcePsi
-            if (psi == null) {
-                // If there is no psi, test for the one known case where there should be an
-                // expected type, an implicit Kotlin return.
-                if (element is UReturnExpression && isKotlin(element.lang)) {
-                    return (element.getParentOfType<UMethod>())?.returnType
-                }
-                return null
-            }
-
-            // Try using the library method for getting the expected type.
-            val expectedType = PsiTypesUtil.getExpectedTypeByParent(psi)
-            if (expectedType != null) return expectedType
-
-            // PsiTypesUtil didn't know the expected type, but it doesn't handle all cases in Java
-            // and doesn't handle Kotlin. Test for a few known gaps.
-            val (parent, childOfParent) = getParentSkipParens(psi)
-            if (parent is PsiExpressionList) {
-                // Handles the case when the element is an argument in a Java method call.
-                val grandparent = PsiUtil.skipParenthesizedExprUp(parent.parent)
-                if (grandparent is PsiMethodCallExpression) {
-                    val paramIndex = parent.expressions.indexOf(childOfParent)
-                    if (paramIndex < 0) return null
-                    val method = grandparent.resolveMethod() ?: return null
-                    val finalParamIndex = method.parameters.size - 1
-                    // Special case the last arguments to a varargs method
-                    return if (method.isVarArgs && paramIndex >= finalParamIndex) {
-                        (method.parameterList.getParameter(finalParamIndex)?.type
-                                as? PsiEllipsisType)
-                            ?.componentType
-                    } else {
-                        method.parameterList.getParameter(paramIndex)?.type
-                    }
-                }
-            } else if (parent is KtValueArgument) {
-                // Handles the case when the element is an argument in a Kotlin method call.
-                val ktCall = parent.parentOfType<KtCallExpression>()
-                val methodCall = (ktCall.toUElement() as? UCallExpression) ?: return null
-                val method = methodCall.resolve() ?: return null
-                val argMap = context.evaluator.computeArgumentMapping(methodCall, method)
-                return argMap[childOfParent.toUElement()]?.type
-            } else if (parent is KtReturnExpression) {
-                // Handles the case when the element is a returned expression in Kotlin.
-                val containingMethod = parent.parentOfType<KtNamedFunction>() ?: return null
-                return (containingMethod.toUElement() as? UMethod)?.returnType
-            } else if (parent is KtNamedFunction) {
-                // Handles the case when the expression is the entire Kotlin method body, so it is
-                // the return (this is different from the implicit return handled above).
-                return (parent.toUElement() as? UMethod)?.returnType
-            } else if (parent is KtBinaryExpression) {
-                // Handles the case when the expression is the right side of a Kotlin assignment.
-                val uParent = (parent.toUElement() as? UBinaryExpression) ?: return null
-                if (
-                    uParent.operator == UastBinaryOperator.ASSIGN && childOfParent == parent.right
-                ) {
-                    return uParent.leftOperand.getExpressionType()
-                }
-            }
-            // Not a known case, still don't know the expected type (or there isn't one).
-            return null
-        }
-
-        /**
-         * Return the first parent of the element which isn't a PsiParenthesizedExpression, and also
-         * return the direct child element of that parent.
-         */
-        private fun getParentSkipParens(element: PsiElement): Pair<PsiElement, PsiElement> {
-            val parent = element.parent
-            return if (parent is PsiParenthesizedExpression) {
-                getParentSkipParens(parent)
-            } else {
-                Pair(parent, element)
-            }
-        }
-
-        /**
-         * Generates source code for a wrapper method and class (where applicable) and calculates
-         * the insertion point. If the wrapper class already exists, returns source code for the
-         * method body only with an insertion point at the end of the existing wrapper class body.
-         * If the wrapper class and method both already exists, just returns the name of the wrapper
-         * class.
-         *
-         * Source code follows the general format:
-         * ```java
-         * @RequiresApi(21)
-         * static class Api21Impl {
-         *   private Api21Impl() {}
-         *   // Method body here.
-         * }
-         * ```
-         *
-         * @param api API level at which the platform method can be safely called
-         * @param callContainingClass Class containing the call to the platform method
-         * @param wrapperMethodName The name of the wrapper method, used to check if the wrapper
-         *   method already exists
-         * @param wrapperMethodParams List of the types of the wrapper method's parameters, used to
-         *   check if the wrapper method already exists
-         * @param wrapperMethodBody Source code for the wrapper method
-         * @return Triple containing (1) the name of the static wrapper class, (2) the insertion
-         *   point for the generated source code (or null if the wrapper method already exists), and
-         *   (3) generated source code for a static wrapper method, including a static wrapper class
-         *   if necessary (or null if the wrapper method already exists)
-         */
-        private fun generateInsertionSource(
-            api: Int,
-            callContainingClass: UClass,
-            wrapperMethodName: String,
-            wrapperMethodParams: List<PsiType>,
-            wrapperMethodBody: String,
-        ): Triple<String, Location?, String?> {
-            val wrapperClassName = "Api${api}Impl"
-            val implInsertionPoint: Location?
-            val implForInsertion: String?
-
-            val existingWrapperClass =
-                callContainingClass.innerClasses.find { innerClass ->
-                    innerClass.name == wrapperClassName
-                }
-
-            if (existingWrapperClass == null) {
-                implInsertionPoint = context.getLocation(callContainingClass.lastChild)
-                implForInsertion =
-                    """
-                @androidx.annotation.RequiresApi($api)
-                static class $wrapperClassName {
-                    private $wrapperClassName() {
-                        // This class is not instantiable.
-                    }
-                    $wrapperMethodBody
-                }
-
-                """
-                        .trimIndent()
-            } else {
-                val existingWrapperMethod =
-                    existingWrapperClass.methods.find { method ->
-                        method.name == wrapperMethodName &&
-                            wrapperMethodParams == getParameterTypes(method)
-                    }
-                if (existingWrapperMethod == null) {
-                    implInsertionPoint = context.getLocation(existingWrapperClass.lastChild)
-                    // Add a newline to force the `}`s for the class and method onto different lines
-                    implForInsertion = wrapperMethodBody.trimIndent() + "\n"
-                } else {
-                    implInsertionPoint = null
-                    implForInsertion = null
-                }
-            }
-
-            return Triple(wrapperClassName, implInsertionPoint, implForInsertion)
-        }
-
-        /**
-         * Generates source code for a call to the generated wrapper method.
-         *
-         * Source code follows the general format:
-         * ```
-         * WrapperClassName.wrapperMethodName(receiverVar, argumentVar)
-         * ```
-         *
-         * @param method Platform method which is being called
-         * @param callReceiver Receiver of the call to the platform method
-         * @param callValueArguments Arguments of the call to the platform method
-         * @param wrapperClassName Name of the generated wrapper class
-         * @param wrapperMethodName Name of the generated wrapper method
-         * @return Source code for a call to the static wrapper method
-         */
-        private fun generateWrapperCall(
-            method: PsiMethod,
-            callReceiver: UExpression?,
-            callValueArguments: List<UExpression>,
-            wrapperClassName: String,
-            wrapperMethodName: String
-        ): String {
-            val callReceiverStr =
-                when {
-                    // Static method
-                    context.evaluator.isStatic(method) -> null
-                    // Constructor
-                    method.isConstructor -> null
-                    // If there is no call receiver, and the method isn't a constructor or static,
-                    // it must be a call to an instance method using `this` implicitly.
-                    callReceiver == null -> "this"
-                    // Otherwise, use the original call receiver string (removing extra parens)
-                    else -> unwrapExpression(callReceiver).asSourceString()
-                }
-
-            val callValues =
-                if (callValueArguments.isNotEmpty()) {
-                    callValueArguments.joinToString(separator = ", ") { argument ->
-                        argument.asSourceString()
-                    }
-                } else {
-                    null
-                }
-
-            val replacementArgs = listOfNotNull(callReceiverStr, callValues).joinToString(", ")
-
-            return "$wrapperClassName.$wrapperMethodName($replacementArgs)"
-        }
-
-        /**
-         * Remove parentheses from the expression (unwrap the expression until it is no longer a
-         * UParenthesizedExpression).
-         */
-        private fun unwrapExpression(expr: UExpression): UExpression {
-            var unwrappedExpr = expr
-            while (unwrappedExpr is UParenthesizedExpression) {
-                unwrappedExpr = unwrappedExpr.expression
-            }
-            return unwrappedExpr
-        }
-
-        /**
-         * Generates source code for a wrapper method, or `null` if we don't know how to do that.
-         * Currently, this method is capable of handling method and constructor calls from Java
-         * source code.
-         *
-         * Source code follows the general format:
-         * ```
-         * @DoNotInline
-         * static ReturnType methodName(HostType hostType, ParamType paramType) {
-         *   return hostType.methodName(paramType);
-         * }
-         * ```
-         *
-         * @param method Platform method which is being called
-         * @return Pair containing (1) the name of the static wrapper method and (2) generated
-         *   source code for a static wrapper around the platform method
-         */
-        private fun generateWrapperMethod(
-            method: PsiMethod,
-            expectedReturnType: PsiType?,
-            expectedParamTypes: List<PsiType?>
-        ): Triple<String, List<PsiType>, String>? {
-            val evaluator = context.evaluator
-            val isStatic = evaluator.isStatic(method)
-            val isConstructor = method.isConstructor
-
-            // None of these should be null if we're looking at Java code.
-            val containingClass = method.containingClass ?: return null
-            // When referencing the type, use the fully qualified type in case it isn't imported
-            // (shortenTypes will simplify if it is). For the variable name, use just the class name
-            val hostType = containingClass.qualifiedName ?: return null
-            val hostClassName = containingClass.name ?: return null
-            val hostVar = hostClassName[0].lowercaseChar() + hostClassName.substring(1)
-
-            val hostParam =
-                if (isStatic || isConstructor) {
-                    null
-                } else {
-                    "$hostType $hostVar"
-                }
-
-            val typeParamsStr =
-                if (method.typeParameters.isNotEmpty()) {
-                    "<${method.typeParameters.joinToString(", ") { param -> "${param.name}" }}> "
-                } else {
-                    ""
-                }
-
-            val paramsWithTypes =
-                method.parameters.mapIndexed { i, param ->
-                    // It's possible for i to be out of bounds due to varargs
-                    val expectedType = expectedParamTypes.getOrNull(i)
-                    val actualType = (param.type as? PsiType) ?: return null
-                    // If the actual type isn't a PsiEllipsisType (the method is varargs) and
-                    // casting
-                    // from the expected to the actual type would be an invalid implicit cast, use
-                    // the expected type. Otherwise, use the actual type.
-                    val typeToUse =
-                        if (
-                            expectedType != null &&
-                                actualType !is PsiEllipsisType &&
-                                isInvalidCast(expectedType.canonicalText, actualType.canonicalText)
-                        ) {
-                            expectedType
-                        } else {
-                            actualType
-                        }
-                    Pair(typeToUse, param.name)
-                }
-            val paramStrings = paramsWithTypes.map { (type, name) -> "${type.canonicalText} $name" }
-            val typedParamsStr = (listOfNotNull(hostParam) + paramStrings).joinToString(", ")
-
-            val paramTypes =
-                listOf(PsiTypesUtil.getClassType(containingClass)) +
-                    paramsWithTypes.map { (type, _) -> type }
-
-            val namedParamsStr =
-                method.parameters.joinToString(separator = ", ") { param -> "${param.name}" }
-
-            val methodName: String
-            var wrapperMethodName: String
-            var returnTypeStr: String
-            val receiverStr: String
-
-            if (isConstructor) {
-                methodName = hostType
-                wrapperMethodName = "create$hostClassName"
-                returnTypeStr = hostType
-                receiverStr = "new "
-            } else {
-                methodName = method.name
-                wrapperMethodName = methodName
-                // PsiMethod.returnType is only supposed to be null if the method is a constructor,
-                // so something has gone wrong if it's null here.
-                returnTypeStr = method.returnType?.canonicalText ?: return null
-                receiverStr = if (isStatic) "$hostType." else "$hostVar."
-            }
-
-            // If the parent is expecting a different return type, use that type.
-            // This is to prevent a CVF on an implicit cast from a type that isn't available at the
-            // caller's API level to a type that is, which becomes a cast from Object.
-            // The real return type should be the same or a subtype of what the parent is expecting.
-            // Also changes the method name to avoid conflicts if the same method with a different
-            // expected return type is needed elsewhere.
-            if (expectedReturnType != null && expectedReturnType.canonicalText != returnTypeStr) {
-                returnTypeStr = expectedReturnType.canonicalText
-                wrapperMethodName += "Returns${expectedReturnType.presentableText}"
-            } else if (
-                expectedReturnType == null &&
-                    returnTypeStr != "void" &&
-                    !classAvailableAtMinSdk(returnTypeStr)
-            ) {
-                // This method returns a value of a type that isn't available at the min SDK.
-                // The expected return type is null either because the returned value isn't used or
-                // getExpectedTypeByParent didn't know how it is used. In case it is used and is
-                // actually expected to be a different type, don't suggest an autofix to prevent an
-                // invalid implicit cast.
-                return null
-            }
-
-            val returnStmtStr = if ("void" == returnTypeStr) "" else "return "
-
-            return Triple(
-                wrapperMethodName,
-                paramTypes,
-                """
-                    @androidx.annotation.DoNotInline
-                    static $typeParamsStr$returnTypeStr $wrapperMethodName($typedParamsStr) {
-                        $returnStmtStr$receiverStr$methodName($namedParamsStr);
-                    }
-                """
-            )
-        }
-
-        /** Creates a method to cast from [fromType] to [toType]. */
-        private fun generateCastingMethod(
-            fromType: PsiType,
-            toType: PsiType
-        ): Pair<String, String> {
-            val fromTypeStr = fromType.presentableText
-            val toTypeStr = toType.presentableText
-            val varName = fromTypeStr[0].lowercaseChar() + fromTypeStr.substring(1)
-            val methodName = "castTo$toTypeStr"
-            return Pair(
-                methodName,
-                """
-                    @androidx.annotation.DoNotInline
-                    static ${toType.canonicalText} $methodName(${fromType.canonicalText} $varName) {
-                        return $varName;
-                    }
-                """
-            )
-        }
-
-        /**
-         * Checks if a cast from [fromType] to [toType] would be invalid, which is true when there
-         * is an API level where [toType] exists but [fromType] does now.
-         *
-         * Allows optionally passing in [knownFromTypeApi] and [knownToTypeApi], the API levels when
-         * [fromType] and [toType] were introduced, respectively, if that has already been computed.
-         * The values will be looked up if not passed in.
-         */
-        private fun isInvalidCast(
-            fromType: String,
-            toType: String,
-            knownFromTypeApi: Int? = null,
-            knownToTypeApi: Int? = null
-        ): Boolean {
-            // Casting to object is always safe
-            if (toType == "java.lang.Object") return false
-
-            // If the types aren't equal, we are casting from actualType to expectedType implicitly
-            if (fromType == toType) return false
-
-            val fromTypeApi = knownFromTypeApi ?: getMinApiOfClass(fromType) ?: return false
-            val toTypeApi = knownToTypeApi ?: getMinApiOfClass(toType) ?: return false
-
-            // Only an issue if there's an API where expectedType exists but actualType doesn't
-            return fromTypeApi > toTypeApi
-        }
-
-        /** Returns a list of the method's parameter types. */
-        private fun getParameterTypes(method: PsiMethod): List<PsiType> =
-            method.parameterList.parameters.map { it.type }
-
-        /** Check if the specified class is available at the min SDK. */
-        private fun classAvailableAtMinSdk(className: String): Boolean {
-            val apiDatabase = apiDatabase ?: return false
-            val minSdk = getMinSdk(context)
-            @Suppress("DEPRECATION") // b/262915628
-            val version = apiDatabase.getClassVersion(className)
-            return version <= minSdk
-        }
-
-        /** Returns the API level this class was introduced at, or null if unknown. */
-        private fun getMinApiOfClass(className: String): Int? {
-            val apiDatabase = apiDatabase ?: return null
-            if (!apiDatabase.containsClass(className)) return null
-            return apiDatabase.getClassVersions(className).min()
-        }
-
-        private fun getInheritanceChain(
-            derivedClass: PsiClassType,
-            baseClass: PsiClassType?
-        ): List<PsiClassType>? {
-            if (derivedClass == baseClass) {
-                return emptyList()
-            }
-            val chain = getInheritanceChain(derivedClass, baseClass, HashSet(), 0)
-            chain?.reverse()
-            return chain
-        }
-
-        private fun getInheritanceChain(
-            derivedClass: PsiClassType,
-            baseClass: PsiClassType?,
-            visited: HashSet<PsiType>,
-            depth: Int
-        ): MutableList<PsiClassType>? {
-            if (derivedClass == baseClass) {
-                return ArrayList(depth)
-            }
-            for (type in derivedClass.superTypes) {
-                if (visited.add(type) && type is PsiClassType) {
-                    val chain = getInheritanceChain(type, baseClass, visited, depth + 1)
-                    if (chain != null) {
-                        chain.add(derivedClass)
-                        return chain
-                    }
-                }
-            }
-            return null
-        }
-
-        private fun getRequiresApiFromAnnotations(modifierListOwner: PsiModifierListOwner): Int {
-            for (annotation in context.evaluator.getAnnotations(modifierListOwner)) {
-                val qualifiedName = annotation.qualifiedName
-                if (REQUIRES_API_ANNOTATION.isEquals(qualifiedName)) {
-                    var api =
-                        getLongAttribute(
-                                context,
-                                annotation,
-                                ATTR_VALUE,
-                                NO_API_REQUIREMENT.toLong()
-                            )
-                            .toInt()
-                    if (api <= 1) {
-                        // @RequiresApi has two aliasing attributes: api and value
-                        api =
-                            getLongAttribute(
-                                    context,
-                                    annotation,
-                                    "api",
-                                    NO_API_REQUIREMENT.toLong()
-                                )
-                                .toInt()
-                    }
-                    return api
-                } else if (qualifiedName == null) {
-                    // Work around UAST type resolution problems
-                    // Work around bugs in UAST type resolution for file annotations:
-                    // parse the source string instead.
-                    val psiAnnotation = annotation.javaPsi
-                    if (psiAnnotation == null || psiAnnotation is PsiCompiledElement) {
-                        continue
-                    }
-                    val text = psiAnnotation.text
-                    if (text.contains("RequiresApi(")) {
-                        val start = text.indexOf('(')
-                        val end = text.indexOf(')', start + 1)
-                        if (end != -1) {
-                            var name = text.substring(start + 1, end)
-                            // Strip off attribute name and qualifiers, e.g.
-                            //   @RequiresApi(api = Build.VERSION.O) -> O
-                            var index = name.indexOf('=')
-                            if (index != -1) {
-                                name = name.substring(index + 1).trim()
-                            }
-                            index = name.indexOf('.')
-                            if (index != -1) {
-                                name = name.substring(index + 1)
-                            }
-                            if (!name.isEmpty()) {
-                                if (name[0].isDigit()) {
-                                    val api = Integer.parseInt(name)
-                                    if (api > 0) {
-                                        return api
-                                    }
-                                } else {
-                                    return VersionChecks.codeNameToApi(name)
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            return NO_API_REQUIREMENT
-        }
-    }
-
-    companion object {
-        const val NO_API_REQUIREMENT = -1
-        val METHOD_CALL_ISSUE =
-            Issue.create(
-                    "ClassVerificationFailure",
-                    "Even in cases where references to new APIs are gated on SDK_INT " +
-                        "checks, run-time class verification will still fail on references to APIs that " +
-                        "may not be available at run time, including platform APIs introduced after a " +
-                        "library's minSdkVersion.",
-                    """
-                References to APIs added after a library's minSdkVersion -- regardless of
-                any surrounding version checks -- will fail run-time class verification if
-                the API does not exist on the device, leading to reduced run-time performance.
-
-                To prevent class verification failures, references to new APIs must be moved to
-                methods within inner classes that are only initialized inside of an appropriate
-                SDK check. These methods must be paired with the @DoNotInline annotation.
-
-                For more details and an example, see go/androidx-api-guidelines#compat-sdk.
-            """,
-                    Category.CORRECTNESS,
-                    5,
-                    Severity.ERROR,
-                    Implementation(
-                        ClassVerificationFailureDetector::class.java,
-                        Scope.JAVA_FILE_SCOPE
-                    )
-                )
-                .setAndroidSpecific(true)
-
-        val IMPLICIT_CAST_ISSUE =
-            Issue.create(
-                    "ImplicitCastClassVerificationFailure",
-                    "Run-time class verification will fail when a type introduced at an " +
-                        "API level is used as another type which was introduced at a lower API level.",
-                    """
-                When a type does not exist on a device, the verifier treats the type as Object. This
-                is a problem if the new type is implicitly cast to a different type which does exist
-                on the device.
-
-                In general, if A extends B, using an A as a B without an explicit cast is fine.
-                However, if A was introduced at a later API level than B, on devices below that API
-                level, A will be seen as Object. An Object cannot be used as a B without an explicit
-                cast.
-
-                For some examples, see go/androidx-api-guidelines#compat-casting
-            """,
-                    Category.CORRECTNESS,
-                    5,
-                    Severity.ERROR,
-                    Implementation(
-                        ClassVerificationFailureDetector::class.java,
-                        Scope.JAVA_FILE_SCOPE
-                    )
-                )
-                .setAndroidSpecific(true)
-    }
-}
diff --git a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
deleted file mode 100644
index 676096f..0000000
--- a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
+++ /dev/null
@@ -1,904 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-@file:Suppress("UnstableApiUsage")
-
-package androidx.build.lint
-
-import androidx.build.lint.Stubs.Companion.DoNotInline
-import androidx.build.lint.Stubs.Companion.IntRange
-import androidx.build.lint.Stubs.Companion.RequiresApi
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class ClassVerificationFailureDetectorTest :
-    AbstractLintDetectorTest(
-        useDetector = ClassVerificationFailureDetector(),
-        useIssues = listOf(ClassVerificationFailureDetector.METHOD_CALL_ISSUE),
-        stubs =
-            arrayOf(
-                // AndroidManifest with minSdkVersion=14
-                manifest().minSdk(14),
-            ),
-    ) {
-
-    @Test
-    fun `Detection of unsafe references in Java sources`() {
-        val input =
-            arrayOf(javaSample("androidx.ClassVerificationFailureFromJava"), RequiresApi, IntRange)
-
-        val expected =
-            """
-src/androidx/ClassVerificationFailureFromJava.java:37: Error: This call references a method added in API level 21; however, the containing class androidx.ClassVerificationFailureFromJava is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            view.setBackgroundTintList(tint);
-                 ~~~~~~~~~~~~~~~~~~~~~
-src/androidx/ClassVerificationFailureFromJava.java:46: Error: This call references a method added in API level 17; however, the containing class androidx.ClassVerificationFailureFromJava is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            return View.generateViewId();
-                        ~~~~~~~~~~~~~~
-src/androidx/ClassVerificationFailureFromJava.java:56: Error: This call references a method added in API level 23; however, the containing class androidx.ClassVerificationFailureFromJava is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return view.getAccessibilityClassName();
-                    ~~~~~~~~~~~~~~~~~~~~~~~~~
-3 errors, 0 warnings
-        """
-                .trimIndent()
-
-        check(*input).expect(expected)
-    }
-
-    @Test
-    fun `Detection and auto-fix of unsafe references in real-world Java sources`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.sample.core.widget.ListViewCompat"),
-            )
-
-        val expected =
-            """
-src/androidx/sample/core/widget/ListViewCompat.java:39: Error: This call references a method added in API level 19; however, the containing class androidx.sample.core.widget.ListViewCompat is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            listView.scrollListBy(y);
-                     ~~~~~~~~~~~~
-src/androidx/sample/core/widget/ListViewCompat.java:69: Error: This call references a method added in API level 19; however, the containing class androidx.sample.core.widget.ListViewCompat is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            return listView.canScrollList(direction);
-                            ~~~~~~~~~~~~~
-2 errors, 0 warnings
-        """
-                .trimIndent()
-
-        val expectedFix =
-            """
-Fix for src/androidx/sample/core/widget/ListViewCompat.java line 39: Extract to static inner class:
-@@ -39 +39
--             listView.scrollListBy(y);
-+             Api19Impl.scrollListBy(listView, y);
-@@ -91 +91
-+ @androidx.annotation.RequiresApi(19)
-+ static class Api19Impl {
-+     private Api19Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static void scrollListBy(android.widget.AbsListView absListView, int y) {
-+         absListView.scrollListBy(y);
-+     }
-+
-@@ -92 +103
-+ }
-Fix for src/androidx/sample/core/widget/ListViewCompat.java line 69: Extract to static inner class:
-@@ -69 +69
--             return listView.canScrollList(direction);
-+             return Api19Impl.canScrollList(listView, direction);
-@@ -91 +91
-+ @androidx.annotation.RequiresApi(19)
-+ static class Api19Impl {
-+     private Api19Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static boolean canScrollList(android.widget.AbsListView absListView, int direction) {
-+         return absListView.canScrollList(direction);
-+     }
-+
-@@ -92 +103
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Detection and auto-fix of unsafe references in real-world Kotlin sources`() {
-        val input =
-            arrayOf(
-                ktSample("androidx.sample.core.widget.ListViewCompatKotlin"),
-            )
-
-        val expected =
-            """
-src/androidx/sample/core/widget/ListViewCompatKotlin.kt:33: Error: This call references a method added in API level 19; however, the containing class androidx.sample.core.widget.ListViewCompatKotlin is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            listView.scrollListBy(y)
-                     ~~~~~~~~~~~~
-src/androidx/sample/core/widget/ListViewCompatKotlin.kt:56: Error: This call references a method added in API level 19; however, the containing class androidx.sample.core.widget.ListViewCompatKotlin is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            listView.canScrollList(direction)
-                     ~~~~~~~~~~~~~
-2 errors, 0 warnings
-        """
-                .trimIndent()
-
-        check(*input).expect(expected)
-    }
-
-    @Test
-    fun `Detection of RequiresApi annotation in outer class in Java source`() {
-        val input = arrayOf(javaSample("androidx.RequiresApiJava"), RequiresApi)
-
-        val expected =
-            """
-No warnings.
-        """
-                .trimIndent()
-
-        check(*input).expect(expected)
-    }
-
-    @Test
-    fun `Detection of RequiresApi annotation in outer class in Kotlin source`() {
-        val input = arrayOf(ktSample("androidx.RequiresApiKotlin"), RequiresApi)
-
-        val expected =
-            """
-src/androidx/RequiresApiKotlinOuter19Passes.kt:67: Error: This call references a method added in API level 19; however, the containing class androidx.RequiresApiKotlinNoAnnotationFails.MyStaticClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            Character.isSurrogate(c)
-                      ~~~~~~~~~~~
-src/androidx/RequiresApiKotlinOuter19Passes.kt:77: Error: This call references a method added in API level 19; however, the containing class androidx.RequiresApiKotlinOuter16Fails.MyStaticClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            Character.isSurrogate(c)
-                      ~~~~~~~~~~~
-src/androidx/RequiresApiKotlinOuter19Passes.kt:87: Error: This call references a method added in API level 19; however, the containing class androidx.RequiresApiKotlinInner16Fails.MyStaticClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            Character.isSurrogate(c)
-                      ~~~~~~~~~~~
-src/androidx/RequiresApiKotlinOuter19Passes.kt:98: Error: This call references a method added in API level 19; however, the containing class androidx.RequiresApiKotlinInner16Outer16Fails.MyStaticClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            Character.isSurrogate(c)
-                      ~~~~~~~~~~~
-4 errors, 0 warnings
-        """
-                .trimIndent()
-
-        check(*input).expect(expected)
-    }
-
-    @Test
-    fun `Auto-fix unsafe void-type method reference in Java source`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.AutofixUnsafeVoidMethodReferenceJava"),
-            )
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeVoidMethodReferenceJava.java line 34: Extract to static inner class:
-@@ -34 +34
--             view.setBackgroundTintList(new ColorStateList(null, null));
-+             Api21Impl.setBackgroundTintList(view, new ColorStateList(null, null));
-@@ -37 +37
-+ @androidx.annotation.RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static void setBackgroundTintList(View view, ColorStateList tint) {
-+         view.setBackgroundTintList(tint);
-+     }
-+
-@@ -38 +49
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix unsafe constructor reference in Java source`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.AutofixUnsafeConstructorReferenceJava"),
-            )
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeConstructorReferenceJava.java line 35: Extract to static inner class:
-@@ -35 +35
--             AccessibilityNodeInfo node = new AccessibilityNodeInfo(new View(context), 1);
-+             AccessibilityNodeInfo node = Api30Impl.createAccessibilityNodeInfo(new View(context), 1);
-@@ -38 +38
-+ @androidx.annotation.RequiresApi(30)
-+ static class Api30Impl {
-+     private Api30Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static AccessibilityNodeInfo createAccessibilityNodeInfo(View root, int virtualDescendantId) {
-+         return new AccessibilityNodeInfo(root, virtualDescendantId);
-+     }
-+
-@@ -39 +50
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix unsafe static method reference in Java source`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.AutofixUnsafeStaticMethodReferenceJava"),
-            )
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeStaticMethodReferenceJava.java line 33: Extract to static inner class:
-@@ -33 +33
--             return View.generateViewId();
-+             return Api17Impl.generateViewId();
-@@ -37 +37
-+ @androidx.annotation.RequiresApi(17)
-+ static class Api17Impl {
-+     private Api17Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static int generateViewId() {
-+         return View.generateViewId();
-+     }
-+
-@@ -38 +49
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix unsafe generic-type method reference in Java source`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.AutofixUnsafeGenericMethodReferenceJava"),
-            )
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeGenericMethodReferenceJava.java line 34: Extract to static inner class:
-@@ -34 +34
--             return context.getSystemService(serviceClass);
-+             return Api23Impl.getSystemService(context, serviceClass);
-@@ -38 +38
-+ @androidx.annotation.RequiresApi(23)
-+ static class Api23Impl {
-+     private Api23Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static <T> T getSystemService(Context context, java.lang.Class<T> serviceClass) {
-+         return context.getSystemService(serviceClass);
-+     }
-+
-@@ -39 +50
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix unsafe reference in Java source with existing inner class`() {
-        val input =
-            arrayOf(javaSample("androidx.AutofixUnsafeReferenceWithExistingClassJava"), RequiresApi)
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeReferenceWithExistingClassJava.java line 36: Extract to static inner class:
-@@ -36 +36
--             view.setBackgroundTintList(new ColorStateList(null, null));
-+             Api21Impl.setBackgroundTintList(view, new ColorStateList(null, null));
-@@ -46 +46
-+ @RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void setBackgroundTintList(View view, ColorStateList tint) {
-+         view.setBackgroundTintList(tint);
-+     }
-+
-@@ -47 +58
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix unsafe reference in Java source when the fix code already exists`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.AutofixUnsafeReferenceWithExistingFix"),
-                RequiresApi,
-                DoNotInline
-            )
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeReferenceWithExistingFix.java:37: Error: This call references a method added in API level 21; however, the containing class androidx.AutofixUnsafeReferenceWithExistingFix is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        view.setBackgroundTintList(new ColorStateList(null, null));
-             ~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeReferenceWithExistingFix.java:45: Error: This call references a method added in API level 21; however, the containing class androidx.AutofixUnsafeReferenceWithExistingFix is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        drawable.getOutline(null);
-                 ~~~~~~~~~~
-2 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeReferenceWithExistingFix.java line 37: Extract to static inner class:
-@@ -37 +37
--         view.setBackgroundTintList(new ColorStateList(null, null));
-+         Api21Impl.setBackgroundTintList(view, new ColorStateList(null, null));
-Fix for src/androidx/AutofixUnsafeReferenceWithExistingFix.java line 45: Extract to static inner class:
-@@ -45 +45
--         drawable.getOutline(null);
-+         Api21Impl.getOutline(drawable, null);
-@@ -58 +58
--     }
-+     @DoNotInline
-+ static void getOutline(Drawable drawable, android.graphics.Outline outline) {
-+     drawable.getOutline(outline);
-@@ -60 +62
-+ }
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Detection and auto-fix for qualified expressions (issue 205026874)`() {
-        val input =
-            arrayOf(
-                javaSample("androidx.sample.appcompat.widget.ActionBarBackgroundDrawable"),
-                RequiresApi
-            )
-
-        val expected =
-            """
-src/androidx/sample/appcompat/widget/ActionBarBackgroundDrawable.java:71: Error: This call references a method added in API level 21; however, the containing class androidx.sample.appcompat.widget.ActionBarBackgroundDrawable is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-                mContainer.mSplitBackground.getOutline(outline);
-                                            ~~~~~~~~~~
-src/androidx/sample/appcompat/widget/ActionBarBackgroundDrawable.java:76: Error: This call references a method added in API level 21; however, the containing class androidx.sample.appcompat.widget.ActionBarBackgroundDrawable is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-                mContainer.mBackground.getOutline(outline);
-                                       ~~~~~~~~~~
-2 errors, 0 warnings
-        """
-                .trimIndent()
-
-        val expectedFix =
-            """
-Fix for src/androidx/sample/appcompat/widget/ActionBarBackgroundDrawable.java line 71: Extract to static inner class:
-@@ -71 +71
--                 mContainer.mSplitBackground.getOutline(outline);
-+                 Api21Impl.getOutline(mContainer.mSplitBackground, outline);
-@@ -90 +90
-+ @RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void getOutline(Drawable drawable, Outline outline) {
-+         drawable.getOutline(outline);
-+     }
-+
-@@ -91 +102
-+ }
-Fix for src/androidx/sample/appcompat/widget/ActionBarBackgroundDrawable.java line 76: Extract to static inner class:
-@@ -76 +76
--                 mContainer.mBackground.getOutline(outline);
-+                 Api21Impl.getOutline(mContainer.mBackground, outline);
-@@ -90 +90
-+ @RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void getOutline(Drawable drawable, Outline outline) {
-+         drawable.getOutline(outline);
-+     }
-+
-@@ -91 +102
-+ }
-        """
-                .trimIndent()
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix includes fully qualified class name (issue 205035683, 236721202)`() {
-        val input =
-            arrayOf(javaSample("androidx.AutofixUnsafeMethodWithQualifiedClass"), RequiresApi)
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeMethodWithQualifiedClass.java:40: Error: This call references a method added in API level 19; however, the containing class androidx.AutofixUnsafeMethodWithQualifiedClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return builder.setMediaSize(mediaSize);
-                       ~~~~~~~~~~~~
-1 errors, 0 warnings
-        """
-
-        val expectedFixDiffs =
-            """
-Fix for src/androidx/AutofixUnsafeMethodWithQualifiedClass.java line 40: Extract to static inner class:
-@@ -40 +40
-+         return Api19Impl.setMediaSize(builder, mediaSize);
-+     }
-+ @RequiresApi(19)
-+ static class Api19Impl {
-+     private Api19Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static PrintAttributes.Builder setMediaSize(PrintAttributes.Builder builder, PrintAttributes.MediaSize mediaSize) {
-@@ -42 +52
-+
-@@ -43 +54
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-
-    @Test
-    fun `Auto-fix for unsafe method call on this`() {
-        val input = arrayOf(javaSample("androidx.AutofixUnsafeCallToThis"))
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeCallToThis.java:39: Error: This call references a method added in API level 21; however, the containing class androidx.AutofixUnsafeCallToThis is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            getClipToPadding();
-            ~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallToThis.java:48: Error: This call references a method added in API level 21; however, the containing class androidx.AutofixUnsafeCallToThis is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            this.getClipToPadding();
-                 ~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallToThis.java:57: Error: This call references a method added in API level 21; however, the containing class androidx.AutofixUnsafeCallToThis is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            super.getClipToPadding();
-                  ~~~~~~~~~~~~~~~~
-3 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeCallToThis.java line 39: Extract to static inner class:
-@@ -39 +39
--             getClipToPadding();
-+             Api21Impl.getClipToPadding(this);
-@@ -60 +60
-+ @androidx.annotation.RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static boolean getClipToPadding(ViewGroup viewGroup) {
-+         return viewGroup.getClipToPadding();
-+     }
-+
-@@ -61 +72
-+ }
-Fix for src/androidx/AutofixUnsafeCallToThis.java line 48: Extract to static inner class:
-@@ -48 +48
--             this.getClipToPadding();
-+             Api21Impl.getClipToPadding(this);
-@@ -60 +60
-+ @androidx.annotation.RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static boolean getClipToPadding(ViewGroup viewGroup) {
-+         return viewGroup.getClipToPadding();
-+     }
-+
-@@ -61 +72
-+ }
-Fix for src/androidx/AutofixUnsafeCallToThis.java line 57: Extract to static inner class:
-@@ -57 +57
--             super.getClipToPadding();
-+             Api21Impl.getClipToPadding(super);
-@@ -60 +60
-+ @androidx.annotation.RequiresApi(21)
-+ static class Api21Impl {
-+     private Api21Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static boolean getClipToPadding(ViewGroup viewGroup) {
-+         return viewGroup.getClipToPadding();
-+     }
-+
-@@ -61 +72
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix for unsafe method call on cast object (issue 206111383)`() {
-        val input = arrayOf(javaSample("androidx.AutofixUnsafeCallOnCast"))
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeCallOnCast.java:32: Error: This call references a method added in API level 28; however, the containing class androidx.AutofixUnsafeCallOnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-            ((DisplayCutout) secretDisplayCutout).getSafeInsetTop();
-                                                  ~~~~~~~~~~~~~~~
-1 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeCallOnCast.java line 32: Extract to static inner class:
-@@ -32 +32
--             ((DisplayCutout) secretDisplayCutout).getSafeInsetTop();
-+             Api28Impl.getSafeInsetTop((DisplayCutout) secretDisplayCutout);
-@@ -35 +35
-+ @androidx.annotation.RequiresApi(28)
-+ static class Api28Impl {
-+     private Api28Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @androidx.annotation.DoNotInline
-+     static int getSafeInsetTop(DisplayCutout displayCutout) {
-+         return displayCutout.getSafeInsetTop();
-+     }
-+
-@@ -36 +47
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix with implicit class cast from new return type (issue 214389795)`() {
-        val input =
-            arrayOf(javaSample("androidx.AutofixUnsafeCallWithImplicitReturnCast"), RequiresApi)
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:36: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return new AdaptiveIconDrawable(null, null);
-               ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:44: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return new AdaptiveIconDrawable(null, null);
-               ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:52: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return Icon.createWithAdaptiveBitmap(null);
-                    ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:60: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return Icon.createWithAdaptiveBitmap(null);
-                    ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:68: Error: This call references a method added in API level 24; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        useStyle(new Notification.DecoratedCustomViewStyle());
-                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-5 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 36: Extract to static inner class:
-@@ -36 +36
--         return new AdaptiveIconDrawable(null, null);
-+         return Api26Impl.createAdaptiveIconDrawableReturnsDrawable(null, null);
-@@ -77 +77
-+ @RequiresApi(26)
-+ static class Api26Impl {
-+     private Api26Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Drawable createAdaptiveIconDrawableReturnsDrawable(Drawable backgroundDrawable, Drawable foregroundDrawable) {
-+         return new AdaptiveIconDrawable(backgroundDrawable, foregroundDrawable);
-+     }
-+
-@@ -78 +89
-+ }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 44: Extract to static inner class:
-@@ -44 +44
--         return new AdaptiveIconDrawable(null, null);
-+         return Api26Impl.createAdaptiveIconDrawable(null, null);
-@@ -77 +77
-+ @RequiresApi(26)
-+ static class Api26Impl {
-+     private Api26Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static AdaptiveIconDrawable createAdaptiveIconDrawable(Drawable backgroundDrawable, Drawable foregroundDrawable) {
-+         return new AdaptiveIconDrawable(backgroundDrawable, foregroundDrawable);
-+     }
-+
-@@ -78 +89
-+ }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 52: Extract to static inner class:
-@@ -52 +52
--         return Icon.createWithAdaptiveBitmap(null);
-+         return Api26Impl.createWithAdaptiveBitmapReturnsObject(null);
-@@ -77 +77
-+ @RequiresApi(26)
-+ static class Api26Impl {
-+     private Api26Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static java.lang.Object createWithAdaptiveBitmapReturnsObject(android.graphics.Bitmap bits) {
-+         return Icon.createWithAdaptiveBitmap(bits);
-+     }
-+
-@@ -78 +89
-+ }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 60: Extract to static inner class:
-@@ -60 +60
--         return Icon.createWithAdaptiveBitmap(null);
-+         return Api26Impl.createWithAdaptiveBitmap(null);
-@@ -77 +77
-+ @RequiresApi(26)
-+ static class Api26Impl {
-+     private Api26Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Icon createWithAdaptiveBitmap(android.graphics.Bitmap bits) {
-+         return Icon.createWithAdaptiveBitmap(bits);
-+     }
-+
-@@ -78 +89
-+ }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 68: Extract to static inner class:
-@@ -68 +68
--         useStyle(new Notification.DecoratedCustomViewStyle());
-+         useStyle(Api24Impl.createDecoratedCustomViewStyleReturnsStyle());
-@@ -77 +77
-+ @RequiresApi(24)
-+ static class Api24Impl {
-+     private Api24Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Notification.Style createDecoratedCustomViewStyleReturnsStyle() {
-+         return new Notification.DecoratedCustomViewStyle();
-+     }
-+
-@@ -78 +89
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix for constructor needs qualified class name (issue 244714253)`() {
-        val input =
-            arrayOf(javaSample("androidx.AutofixUnsafeConstructorQualifiedClass"), RequiresApi)
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeConstructorQualifiedClass.java:32: Error: This call references a method added in API level 24; however, the containing class androidx.AutofixUnsafeConstructorQualifiedClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        return new Notification.DecoratedCustomViewStyle();
-               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-1 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeConstructorQualifiedClass.java line 32: Extract to static inner class:
-@@ -32 +32
-+         return Api24Impl.createDecoratedCustomViewStyle();
-+     }
-+ @RequiresApi(24)
-+ static class Api24Impl {
-+     private Api24Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Notification.DecoratedCustomViewStyle createDecoratedCustomViewStyle() {
-@@ -34 +44
-+
-@@ -35 +46
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix with implicit class cast from new parameter type (issue 266845827)`() {
-        val input =
-            arrayOf(javaSample("androidx.AutofixUnsafeCallWithImplicitParamCast"), RequiresApi)
-
-        val expected =
-            """
-src/androidx/AutofixUnsafeCallWithImplicitParamCast.java:34: Error: This call references a method added in API level 16; however, the containing class androidx.AutofixUnsafeCallWithImplicitParamCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        style.setBuilder(builder);
-              ~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitParamCast.java:43: Error: This call references a method added in API level 20; however, the containing class androidx.AutofixUnsafeCallWithImplicitParamCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        builder.extend(extender);
-                ~~~~~~
-2 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixUnsafeCallWithImplicitParamCast.java line 34: Extract to static inner class:
-@@ -34 +34
--         style.setBuilder(builder);
-+         Api16Impl.setBuilder(style, builder);
-@@ -45 +45
-+ @RequiresApi(16)
-+ static class Api16Impl {
-+     private Api16Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void setBuilder(Notification.Style style, Notification.Builder builder) {
-+         style.setBuilder(builder);
-+     }
-+
-@@ -46 +57
-+ }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitParamCast.java line 43: Extract to static inner class:
-@@ -43 +43
--         builder.extend(extender);
-+         Api20Impl.extend(builder, extender);
-@@ -45 +45
-+ @RequiresApi(20)
-+ static class Api20Impl {
-+     private Api20Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Notification.Builder extend(Notification.Builder builder, Notification.CarExtender extender) {
-+         return builder.extend(extender);
-+     }
-+
-@@ -46 +57
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-
-    @Test
-    fun `Auto-fix for method with varargs that are implicitly cast (issue 266845827)`() {
-        val input =
-            arrayOf(javaSample("androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast"), RequiresApi)
-
-        val expected =
-            """
-src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java:35: Error: This call references a method added in API level 27; however, the containing class androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        adapter.setAutofillOptions();
-                ~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java:43: Error: This call references a method added in API level 27; however, the containing class androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        adapter.setAutofillOptions(vararg);
-                ~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java:52: Error: This call references a method added in API level 27; however, the containing class androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
-        adapter.setAutofillOptions(vararg1, vararg2, vararg3);
-                ~~~~~~~~~~~~~~~~~~
-3 errors, 0 warnings
-        """
-
-        val expectedFix =
-            """
-Fix for src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java line 35: Extract to static inner class:
-@@ -35 +35
--         adapter.setAutofillOptions();
-+         Api27Impl.setAutofillOptions(adapter);
-@@ -54 +54
-+ @RequiresApi(27)
-+ static class Api27Impl {
-+     private Api27Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void setAutofillOptions(BaseAdapter baseAdapter, java.lang.CharSequence... options) {
-+         baseAdapter.setAutofillOptions(options);
-+     }
-+
-@@ -55 +66
-+ }
-Fix for src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java line 43: Extract to static inner class:
-@@ -43 +43
--         adapter.setAutofillOptions(vararg);
-+         Api27Impl.setAutofillOptions(adapter, vararg);
-@@ -54 +54
-+ @RequiresApi(27)
-+ static class Api27Impl {
-+     private Api27Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void setAutofillOptions(BaseAdapter baseAdapter, java.lang.CharSequence... options) {
-+         baseAdapter.setAutofillOptions(options);
-+     }
-+
-@@ -55 +66
-+ }
-Fix for src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java line 52: Extract to static inner class:
-@@ -52 +52
--         adapter.setAutofillOptions(vararg1, vararg2, vararg3);
-+         Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-@@ -54 +54
-+ @RequiresApi(27)
-+ static class Api27Impl {
-+     private Api27Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static void setAutofillOptions(BaseAdapter baseAdapter, java.lang.CharSequence... options) {
-+         baseAdapter.setAutofillOptions(options);
-+     }
-+
-@@ -55 +66
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFix)
-    }
-}
diff --git a/lint-checks/src/test/java/androidx/build/lint/ImplicitCastVerificationFailureDetectorTest.kt b/lint-checks/src/test/java/androidx/build/lint/ImplicitCastVerificationFailureDetectorTest.kt
deleted file mode 100644
index da62c1e..0000000
--- a/lint-checks/src/test/java/androidx/build/lint/ImplicitCastVerificationFailureDetectorTest.kt
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * Copyright 2023 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 androidx.build.lint
-
-import androidx.build.lint.Stubs.Companion.DoNotInline
-import androidx.build.lint.Stubs.Companion.RequiresApi
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class ImplicitCastVerificationFailureDetectorTest :
-    AbstractLintDetectorTest(
-        useDetector = ClassVerificationFailureDetector(),
-        useIssues = listOf(ClassVerificationFailureDetector.IMPLICIT_CAST_ISSUE),
-        stubs =
-            arrayOf(
-                // AndroidManifest with minSdkVersion=14
-                manifest().minSdk(14),
-                RequiresApi,
-                DoNotInline,
-            ),
-    ) {
-    @Test
-    fun `Unsafe implicit cast for method argument`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-                import androidx.annotation.DoNotInline;
-                import androidx.annotation.RequiresApi;
-
-                public class UnsafeImplicitCastAsMethodArgumentJava {
-                    @RequiresApi(24)
-                    public void setBuilder(Notification.MessagingStyle style,
-                            Notification.Builder builder) {
-                        Api16Impl.setBuilder(style, builder);
-                    }
-
-                    @RequiresApi(16)
-                    static class Api16Impl {
-                        private Api16Impl() {}
-                        @DoNotInline
-                        static void setBuilder(Notification.Style style,
-                                Notification.Builder builder) {
-                            style.setBuilder(builder);
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.DoNotInline
-                import androidx.annotation.RequiresApi
-
-                class UnsafeImplicitCastAsMethodArgumentKotlin {
-                    @RequiresApi(24)
-                    fun setBuilder(style: Notification.MessagingStyle,
-                            builder: Notification.Builder) {
-                        Api16Impl.setBuilder(style, builder);
-                    }
-
-                    @RequiresApi(16)
-                    private object Api16Impl {
-                        @JvmStatic
-                        @DoNotInline
-                        fun setBuilder(style: Notification.Style, builder: Notification.Builder) {
-                            style.setBuilder(builder)
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        val expected =
-            """
-src/java/androidx/UnsafeImplicitCastAsMethodArgumentJava.java:11: Error: This expression has type android.app.Notification.MessagingStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        Api16Impl.setBuilder(style, builder);
-                             ~~~~~
-src/java/androidx/UnsafeImplicitCastAsMethodArgumentKotlin.kt:11: Error: This expression has type android.app.Notification.MessagingStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        Api16Impl.setBuilder(style, builder);
-                             ~~~~~
-2 errors, 0 warnings
-        """
-
-        val expectedFixDiffs =
-            """
-Fix for src/java/androidx/UnsafeImplicitCastAsMethodArgumentJava.java line 11: Extract to static inner class:
-@@ -11 +11
--         Api16Impl.setBuilder(style, builder);
-+         Api16Impl.setBuilder(Api24Impl.castToStyle(style), builder);
-@@ -23 +23
-+ @RequiresApi(24)
-+ static class Api24Impl {
-+     private Api24Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Notification.Style castToStyle(Notification.MessagingStyle messagingStyle) {
-+         return messagingStyle;
-+     }
-+
-@@ -24 +35
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-
-    @Test
-    fun `Unsafe implicit cast within catch block`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Presentation;
-                import android.util.Log;
-                import android.view.WindowManager;
-                import androidx.annotation.DoNotInline;
-                import androidx.annotation.RequiresApi;
-
-                public class UnsafeImplicitCastInCatchBlockJava {
-                    @RequiresApi(17)
-                    public void tryShowPresentation(Presentation presentation) {
-                        try {
-                            Api17Impl.show(presentation);
-                        } catch (WindowManager.InvalidDisplayException e) {
-                            Log.w("Error", "Couldn't show presentation!", e);
-                        }
-                    }
-
-                    @RequiresApi(17)
-                    static class Api17Impl {
-                        private Api16Impl() {}
-                        @DoNotInline
-                        static void show(Presentation presentation) {
-                            presentation.show();
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Presentation
-                import android.util.Log
-                import android.view.WindowManager
-                import androidx.annotation.DoNotInline
-                import androidx.annotation.RequiresApi
-
-                class UnsafeImplicitCastInCatchBlockKotlin {
-                    @RequiresApi(17)
-                    fun tryShowPresentation(presentation: Presentation) {
-                        try {
-                            Api17Impl.show(presentation)
-                        } catch (e: WindowManager.InvalidDisplayException) {
-                            Log.w("Error", "Couldn't show presentation!", e)
-                        }
-                    }
-
-                    @RequiresApi(17)
-                    private object Api17Impl {
-                        @JvmStatic
-                        @DoNotInline
-                        fun show(presentation: Presentation) {
-                            presentation.show()
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        val expected =
-            """
-src/java/androidx/UnsafeImplicitCastInCatchBlockJava.java:15: Error: This expression has type android.view.WindowManager.InvalidDisplayException (introduced in API level 17) but it used as type java.lang.Throwable (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-            Log.w("Error", "Couldn't show presentation!", e);
-                                                          ~
-src/java/androidx/UnsafeImplicitCastInCatchBlockKotlin.kt:15: Error: This expression has type android.view.WindowManager.InvalidDisplayException (introduced in API level 17) but it used as type java.lang.Throwable (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-            Log.w("Error", "Couldn't show presentation!", e)
-                                                          ~
-2 errors, 0 warnings
-        """
-
-        val expectedFixDiffs =
-            """
-Fix for src/java/androidx/UnsafeImplicitCastInCatchBlockJava.java line 15: Extract to static inner class:
-@@ -15 +15
--             Log.w("Error", "Couldn't show presentation!", e);
-+             Log.w("Error", "Couldn't show presentation!", Api17Impl.castToThrowable(e));
-@@ -26 +26
--     }
-+     @DoNotInline
-+ static java.lang.Throwable castToThrowable(WindowManager.InvalidDisplayException invalidDisplayException) {
-+     return invalidDisplayException;
-@@ -28 +30
-+ }
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-
-    @Test
-    fun `Unsafe implicit cast in assignment statement`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-                import androidx.annotation.RequiresApi;
-
-                public class UnsafeImplicitCastInAssignmentJava {
-                    Notification.Style style;
-
-                    @RequiresApi(24)
-                    public void setNotificationStyle(Notification.MessagingStyle messagingStyle) {
-                        style = messagingStyle;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.RequiresApi
-
-                class UnsafeImplicitCastInAssignmentKotlin {
-                    lateinit var style: Notification.Style
-
-                    @RequiresApi(24)
-                    fun setNotificationStyle(messagingStyle: Notification.MessagingStyle) {
-                        style = messagingStyle
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        val expected =
-            """
-src/java/androidx/UnsafeImplicitCastInAssignmentJava.java:11: Error: This expression has type android.app.Notification.MessagingStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        style = messagingStyle;
-                ~~~~~~~~~~~~~~
-src/java/androidx/UnsafeImplicitCastInAssignmentKotlin.kt:11: Error: This expression has type android.app.Notification.MessagingStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        style = messagingStyle
-                ~~~~~~~~~~~~~~
-2 errors, 0 warnings
-        """
-
-        val expectedFixDiffs =
-            """
-Fix for src/java/androidx/UnsafeImplicitCastInAssignmentJava.java line 11: Extract to static inner class:
-@@ -11 +11
--         style = messagingStyle;
-+         style = Api24Impl.castToStyle(messagingStyle);
-@@ -13 +13
-+ @RequiresApi(24)
-+ static class Api24Impl {
-+     private Api24Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Notification.Style castToStyle(Notification.MessagingStyle messagingStyle) {
-+         return messagingStyle;
-+     }
-+
-@@ -14 +25
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-
-    @Test
-    fun `Unsafe implicit cast on return`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-                import androidx.annotation.RequiresApi;
-
-                public class ImplicitCastOnReturnJava {
-                    @RequiresApi(24)
-                    public Notification.Style convertStyle(Notification.MessagingStyle style) {
-                        return style;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.RequiresApi
-
-                class ImplicitCastOnReturnKotlin {
-                    @RequiresApi(24)
-                    fun convertStyle(style: Notification.MessagingStyle): Notification.Style {
-                        return style
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        val expected =
-            """
-src/java/androidx/ImplicitCastOnReturnJava.java:9: Error: This expression has type android.app.Notification.MessagingStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        return style;
-               ~~~~~
-src/java/androidx/ImplicitCastOnReturnKotlin.kt:9: Error: This expression has type android.app.Notification.MessagingStyle (introduced in API level 24) but it used as type android.app.Notification.Style (introduced in API level 16). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        return style
-               ~~~~~
-2 errors, 0 warnings
-        """
-
-        val expectedFixDiffs =
-            """
-Fix for src/java/androidx/ImplicitCastOnReturnJava.java line 9: Extract to static inner class:
-@@ -9 +9
--         return style;
-+         return Api24Impl.castToStyle(style);
-@@ -11 +11
-+ @RequiresApi(24)
-+ static class Api24Impl {
-+     private Api24Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static Notification.Style castToStyle(Notification.MessagingStyle messagingStyle) {
-+         return messagingStyle;
-+     }
-+
-@@ -12 +23
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-
-    @Test
-    fun `Unsafe implicit cast of method call result`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.graphics.drawable.AdaptiveIconDrawable;
-                import android.graphics.drawable.Drawable;
-                import androidx.annotation.DoNotInline;
-                import androidx.annotation.RequiresApi;
-
-                public class ImplicitCastOfMethodCallResultJava {
-                    @RequiresApi(26)
-                    public Drawable createAdaptiveIconDrawable() {
-                        return Api26Impl.createAdaptiveIconDrawable(null, null);
-                    }
-
-                    @RequiresApi(26)
-                    static class Api26Impl {
-                        private Api26Impl() {}
-                        @DoNotInline
-                        static AdaptiveIconDrawable createAdaptiveIconDrawable(
-                                Drawable backgroundDrawable, Drawable foregroundDrawable) {
-                            return new AdaptiveIconDrawable(backgroundDrawable, foregroundDrawable);
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.graphics.drawable.AdaptiveIconDrawable
-                import android.graphics.drawable.Drawable
-                import androidx.annotation.DoNotInline
-                import androidx.annotation.RequiresApi
-
-                class ImplicitCastOfMethodCallResultKotlin {
-                    @RequiresApi(26)
-                    fun createAdaptiveIconDrawable(): Drawable =
-                        Api26Impl.createAdaptiveIconDrawable(null, null)
-
-                    @RequiresApi(26)
-                    object Api26Impl {
-                        @JvmStatic
-                        @DoNotInline
-                        fun createAdaptiveIconDrawable(backgroundDrawable: Drawable,
-                                foregroundDrawable: Drawable): AdaptiveIconDrawable {
-                            return AdaptiveIconDrawable(backgroundDrawable, foregroundDrawable)
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        val expected =
-            """
-src/java/androidx/ImplicitCastOfMethodCallResultJava.java:11: Error: This expression has type android.graphics.drawable.AdaptiveIconDrawable (introduced in API level 26) but it used as type android.graphics.drawable.Drawable (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        return Api26Impl.createAdaptiveIconDrawable(null, null);
-               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src/java/androidx/ImplicitCastOfMethodCallResultKotlin.kt:11: Error: This expression has type android.graphics.drawable.AdaptiveIconDrawable (introduced in API level 26) but it used as type android.graphics.drawable.Drawable (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        Api26Impl.createAdaptiveIconDrawable(null, null)
-        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-2 errors, 0 warnings
-        """
-
-        val expectedFixDiffs =
-            """
-Fix for src/java/androidx/ImplicitCastOfMethodCallResultJava.java line 11: Extract to static inner class:
-@@ -11 +11
--         return Api26Impl.createAdaptiveIconDrawable(null, null);
-+         return Api26Impl.castToDrawable(Api26Impl.createAdaptiveIconDrawable(null, null));
-@@ -22 +22
--     }
-+     @DoNotInline
-+ static Drawable castToDrawable(AdaptiveIconDrawable adaptiveIconDrawable) {
-+     return adaptiveIconDrawable;
-@@ -24 +26
-+ }
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-
-    @Test
-    fun `Safe implicit cast to object`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-                import androidx.annotation.RequiresApi;
-
-                public class SafeImplicitCastToObjectJava {
-                    Object style;
-
-                    @RequiresApi(24)
-                    public void setNotificationStyle(Notification.MessagingStyle messagingStyle) {
-                        style = messagingStyle;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.RequiresApi
-
-                class SafeImplicitCastToObjectKotlin {
-                    lateinit var style: Any
-
-                    @RequiresApi(24)
-                    fun setNotificationStyle(messagingStyle: Notification.MessagingStyle) {
-                        style = messagingStyle
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        check(*input).expectClean()
-    }
-
-    @Test
-    fun `Safe explicit cast`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-                import androidx.annotation.RequiresApi;
-
-                public class SafeExplicitCastJava {
-                    Notification.Style style;
-
-                    @RequiresApi(24)
-                    public void setNotificationStyle(Notification.MessagingStyle messagingStyle) {
-                        style = (Notification.Style) messagingStyle;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.RequiresApi
-
-                class SafeExplicitCastKotlin {
-                    lateinit var style: Notification.Style
-
-                    @RequiresApi(24)
-                    fun setNotificationStyle(messagingStyle: Notification.MessagingStyle) {
-                        style = messagingStyle as Notification.Style
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        check(*input).expectClean()
-    }
-
-    @Test
-    fun `Safe implicit cast between classes from the same API level`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.media.tv.BroadcastInfoResponse;
-                import android.media.tv.PesResponse;
-                import androidx.annotation.RequiresApi;
-
-                public class SafeImplicitCastSameApiLevelJava {
-                    BroadcastInfoResponse response;
-
-                    @RequiresApi(33)
-                    public void setResponse(PesResponse pesResponse) {
-                        response = pesResponse;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.media.tv.BroadcastInfoResponse
-                import android.media.tv.PesResponse
-                import androidx.annotation.RequiresApi
-
-                class SafeImplicitCastSameApiLevelKotlin {
-                    lateinit var response: BroadcastInfoResponse
-
-                    @RequiresApi(33)
-                    fun setResponse(pesResponse: PesResponse) {
-                        response = pesResponse
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        check(*input).expectClean()
-    }
-
-    @Test
-    fun `Safe implicit cast within @RequiresApi class`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-
-                import androidx.annotation.DoNotInline;
-                import androidx.annotation.RequiresApi;
-
-                @RequiresApi(24)
-                static class SafeImplicitCastWithRequiresApiJava {
-                    private SafeImplicitCastWithRequiresApi() {}
-                    @DoNotInline
-                    static void extend(Notification.Builder builder,
-                            Notification.CarExtender extender) {
-                        builder.extend(extender);
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.DoNotInline;
-                import androidx.annotation.RequiresApi;
-
-                @RequiresApi(24)
-                object SafeImplicitCastWithRequiresApiKotlin {
-                    @JvmStatic
-                    @DoNotInline
-                    fun extend(builder: Notification.Builder, extender: Notification.CarExtender) {
-                        builder.extend(extender)
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        check(*input).expectClean()
-    }
-
-    @Test
-    fun `Safe implicit cast from null value`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.Notification;
-                import androidx.annotation.RequiresApi;
-
-                public class SafeCastFromNullJava {
-                    @RequiresApi(24)
-                    public Notification.MessagingStyle getStyle() {
-                        return null;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.Notification
-                import androidx.annotation.RequiresApi
-
-                class SafeCastFromNullKotlin {
-                    @RequiresApi(24)
-                    fun getStyle(): Notification.MessagingStyle? {
-                        return null
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        check(*input).expectClean()
-    }
-
-    @Test
-    fun `Safe implicit cast from type introduced earlier than the minSdk`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.app.FragmentBreadCrumbs;
-                import android.view.ViewGroup;
-
-                public class SafeCastFromPreMinSdkClassJava {
-                    ViewGroup viewGroup;
-
-                    public void setViewGroup(FragmentBreadCrumbs breadCrumbs) {
-                        // FragmentBreadCrumbs was introduced in API level 11
-                        viewGroup = breadCrumbs;
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-                kotlin(
-                    """
-                package java.androidx
-
-                import android.app.FragmentBreadCrumbs
-                import android.view.ViewGroup
-
-                class SafeCastFromPreMinSdkClassKotlin {
-                    lateinit var viewGroup: ViewGroup
-
-                    fun setViewGroup(breadCrumbs: FragmentBreadCrumbs) {
-                        // FragmentBreadCrumbs was introduced in API level 11
-                        viewGroup = breadCrumbs
-                    }
-                }
-            """
-                        .trimIndent()
-                ),
-            )
-
-        check(*input).expectClean()
-    }
-
-    @Test
-    fun `Unsafe implicit cast to varargs method`() {
-        val input =
-            arrayOf(
-                java(
-                    """
-                package java.androidx;
-
-                import android.icu.number.FormattedNumber;
-                import android.widget.BaseAdapter;
-                import androidx.annotation.DoNotInline;
-                import androidx.annotation.RequiresApi;
-
-                public class UnsafeCastToVarargs() {
-                    @RequiresApi(30)
-                    public void callVarArgsMethod(BaseAdapter adapter, FormattedNumber vararg1, FormattedNumber vararg2, FormattedNumber vararg3) {
-                        Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-                    }
-
-                    @RequiresApi(27)
-                    static class Api27Impl {
-                        private Api27Impl() {}
-                        @DoNotInline
-                        static void setAutofillOptions(BaseAdapter baseAdapter, CharSequence... options) {
-                            baseAdapter.setAutofillOptions(baseAdapter, options);
-                        }
-                    }
-                }
-            """
-                        .trimIndent()
-                )
-            )
-
-        val expected =
-            """
-src/java/androidx/UnsafeCastToVarargs.java:11: Error: This expression has type android.icu.number.FormattedNumber (introduced in API level 30) but it used as type java.lang.CharSequence (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-                                              ~~~~~~~
-src/java/androidx/UnsafeCastToVarargs.java:11: Error: This expression has type android.icu.number.FormattedNumber (introduced in API level 30) but it used as type java.lang.CharSequence (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-                                                       ~~~~~~~
-src/java/androidx/UnsafeCastToVarargs.java:11: Error: This expression has type android.icu.number.FormattedNumber (introduced in API level 30) but it used as type java.lang.CharSequence (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels. [ImplicitCastClassVerificationFailure]
-        Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-                                                                ~~~~~~~
-3 errors, 0 warnings
-        """
-        val expectedFixDiffs =
-            """
-Fix for src/java/androidx/UnsafeCastToVarargs.java line 11: Extract to static inner class:
-@@ -11 +11
--         Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-+         Api27Impl.setAutofillOptions(adapter, Api30Impl.castToCharSequence(vararg1), vararg2, vararg3);
-@@ -22 +22
-+ @RequiresApi(30)
-+ static class Api30Impl {
-+     private Api30Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static java.lang.CharSequence castToCharSequence(FormattedNumber formattedNumber) {
-+         return formattedNumber;
-+     }
-+
-@@ -23 +34
-+ }
-Fix for src/java/androidx/UnsafeCastToVarargs.java line 11: Extract to static inner class:
-@@ -11 +11
--         Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-+         Api27Impl.setAutofillOptions(adapter, vararg1, Api30Impl.castToCharSequence(vararg2), vararg3);
-@@ -22 +22
-+ @RequiresApi(30)
-+ static class Api30Impl {
-+     private Api30Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static java.lang.CharSequence castToCharSequence(FormattedNumber formattedNumber) {
-+         return formattedNumber;
-+     }
-+
-@@ -23 +34
-+ }
-Fix for src/java/androidx/UnsafeCastToVarargs.java line 11: Extract to static inner class:
-@@ -11 +11
--         Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, vararg3);
-+         Api27Impl.setAutofillOptions(adapter, vararg1, vararg2, Api30Impl.castToCharSequence(vararg3));
-@@ -22 +22
-+ @RequiresApi(30)
-+ static class Api30Impl {
-+     private Api30Impl() {
-+         // This class is not instantiable.
-+     }
-+
-+     @DoNotInline
-+     static java.lang.CharSequence castToCharSequence(FormattedNumber formattedNumber) {
-+         return formattedNumber;
-+     }
-+
-@@ -23 +34
-+ }
-        """
-
-        check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
-    }
-}