Merge "Update HealthEvent proto parsing" into androidx-main
diff --git a/.mailmap b/.mailmap
deleted file mode 100644
index 40c295e..0000000
--- a/.mailmap
+++ /dev/null
@@ -1 +0,0 @@
-Ember Rose <[email protected]> <[email protected]>
diff --git a/OWNERS b/OWNERS
index 697058a..b88cc13 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,7 +5,6 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
 [email protected]
 [email protected]
 [email protected]
@@ -29,6 +28,8 @@
 per-file *settings.gradle = [email protected], [email protected]
 per-file *libraryversions.toml = [email protected]
 per-file *libraryversions.toml = [email protected], [email protected], [email protected]
+# WebKit
+per-file *libraryversions.toml = [email protected], [email protected]
 per-file *docs-public/build.gradle = [email protected], [email protected]
 
 # Copybara can self-approve CLs within synced docs.
diff --git a/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/ActivityResultLaunchDetectorTest.kt b/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/ActivityResultLaunchDetectorTest.kt
index 7d5fc8b..df01c3d 100644
--- a/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/ActivityResultLaunchDetectorTest.kt
+++ b/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/ActivityResultLaunchDetectorTest.kt
@@ -43,7 +43,7 @@
     private val MANAGED_ACTIVITY_RESULT_LAUNCHER = bytecodeStub(
         filename = "ActivityResultRegistry.kt",
         filepath = "androidx/activity/compose",
-        checksum = 0x42f3e9f,
+        checksum = 0xef067b97,
         source = """
     package androidx.activity.compose
 
@@ -53,23 +53,23 @@
     """,
         """
     META-INF/main.kotlin_module:
-    H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AJcrFnZyfq5dakZhbkJMqxBaSWlzi
-    XaLEoMUAAIXWemUvAAAA
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgEuXiTs7P1UutSMwtyEkVYgtJLS7x
+    LlFi0GIAAJY6UNwvAAAA
     """,
-        """
+    """
     androidx/activity/compose/ManagedActivityResultLauncher.class:
-    H4sIAAAAAAAAAJ1Ry24aMRQ9NjAQQsqQNBTo+7EgWXQIatVXFCmNVJWKpBKJ
-    2LAyYBEH8ERjD0p2fEv/oKtKXVSoy35U1esJmyZd1Ytzzz0+1/fa/vX7+w8A
-    L/CM4ZXQwyhUw4tADKyaKXsZDMLpeWhkcCi0GMnh/lLvSBNPbFvEenAqoywY
-    Q3239bZ9JmYimAg9Cj73z+TAvtu7KTH417Us0gzertLK7jGk6lvdAjxk88gg
-    x5C2p8owvGn/53jU0ZsknGGzfnOgrS4Z6iethGSUPo8tw/q/Bi+1x6GdKB0c
-    SiuGwgrS+HSWogdkDjIMbEzShXJZg9hwh+HjYl7O8wrPL+Z57jvIcSLcxcpi
-    vp3OLeY+a/IGf5/5+cXjfurThp+u8Uam6flejb9ezBM5685rUosWo36o/n3b
-    jhwpY6PL52OaPn0QDiVDsa20PIqnfRmdiP5EumuFAzHpiki5fCmuHKuRFjaO
-    iOePwzgayA/KbVQ7sbZqKrvKKHLuax1aYVWoDXbA6Xfc4jQLfRbhA8oCisw9
-    xfY3rHxNth8SeomYxiPCwpUBeaxSLFG+Ri5X/DLx0+WuF2aSwvLV5rLQsSJ8
-    wseJ+xZSS5bCkyTex1OKB+Qo0QnrPaRa2GjhNiE2HZRbuINKD8ygiloPOYNV
-    g7sG9wyyBoWEFA3W/gCvD9WQJgMAAA==
+    H4sIAAAAAAAA/51Ry24TMRQ9dpLJoy2ZtDSk5f2S0i6YNALxqiqVSohBKUhp
+    lU1WTmKlbhJPNfZE7S7fwh+wQmKBIpZ8FOJ6mg0tK7w499zjc+177V+/v/8A
+    8BxPGV4KPYgjNTgPRN+qqbIXQT+anEVGBodCi6Ec7C/0tjTJ2LZEovsnMs6D
+    MdR3wzetUzEVwVjoYfC5dyr79u3edYnBv6rlkWXwdpVWdo8hU9/qLMNDvoQc
+    CgxZe6IMw+vWf7ZHN3rjlDOs1683tNUhQ/04TElO6bPEMqz+q/FKaxTZsdLB
+    obRiIKwgjU+mGXpA5qDoAAxsRPq5clmD2GCH4cN8Vi3xGi/NZyXuOyhwItzF
+    2ny2nS3MZz5r8gZ/l/v5xeN+5uOan93kjVzT871N/mo+S+W8O69JV4TM3bTx
+    98htOVTGxhfPRjRC9iAaSIZyS2n5KZn0ZHwsemPpZov6YtwRsXL5QiweqaEW
+    NomJl46iJO7L98ptbLQTbdVEdpRR5NzXOrLCqkgb7IDTF7nFqRf6McL7lAXu
+    DSjmtr+h+DXdfkDopWIWDwmXLw0oYYlihfIVcrniF6mfhrtamEsLq5ebi0LH
+    yvAJH6XuG8gsWAaP03gPTygekKNCJ6x2kQmxFuJmiHVUieJWiBo2umAGm7jd
+    RcFgyeCOwV2DvMFySsoGK38AjaXx2SsDAAA=
     """
     )
 
diff --git a/activity/activity-ktx/src/main/java/androidx/activity/PipHintTracker.kt b/activity/activity-ktx/src/main/java/androidx/activity/PipHintTracker.kt
index 710602a..d130d7f 100644
--- a/activity/activity-ktx/src/main/java/androidx/activity/PipHintTracker.kt
+++ b/activity/activity-ktx/src/main/java/androidx/activity/PipHintTracker.kt
@@ -75,7 +75,7 @@
         }
         // Check if the view is already attached to the window, if it is then emit the current
         // position and start listening for layout changes to track movement.
-        if (Api19Impl.isAttachedToWindow(view)) {
+        if (view.isAttachedToWindow) {
             trySend(view.positionInWindow())
             view.viewTreeObserver.addOnScrollChangedListener(scrollChangeListener)
             view.addOnLayoutChangeListener(layoutChangeListener)
@@ -93,11 +93,6 @@
     }
 }
 
-@RequiresApi(Build.VERSION_CODES.KITKAT)
-internal object Api19Impl {
-    fun isAttachedToWindow(view: View): Boolean = view.isAttachedToWindow
-}
-
 @RequiresApi(Build.VERSION_CODES.O)
 internal object Api26Impl {
     fun setPipParamsSourceRectHint(activity: Activity, hint: Rect) {
diff --git a/activity/activity/src/androidTest/java/androidx/activity/FullyDrawnReporterTest.kt b/activity/activity/src/androidTest/java/androidx/activity/FullyDrawnReporterTest.kt
index 955b8df..0edb154 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/FullyDrawnReporterTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/FullyDrawnReporterTest.kt
@@ -15,14 +15,12 @@
  */
 package androidx.activity
 
-import android.os.Build
 import android.view.View
 import android.view.ViewTreeObserver.OnDrawListener
 import androidx.core.view.OneShotPreDrawListener
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.withActivity
 import androidx.testutils.withUse
 import com.google.common.truth.Truth.assertThat
@@ -39,7 +37,6 @@
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
 class FullyDrawnReporterTest {
 
     @get:Rule
diff --git a/activity/activity/src/androidTest/java/androidx/activity/result/PickVisualMediaRequestTest.kt b/activity/activity/src/androidTest/java/androidx/activity/result/PickVisualMediaRequestTest.kt
index b3b3f9a..4d388bc 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/result/PickVisualMediaRequestTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/result/PickVisualMediaRequestTest.kt
@@ -19,14 +19,12 @@
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import leakcanary.DetectLeaksAfterTestSuccess
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@SdkSuppress(minSdkVersion = 19) // API 19 in the minimum for PickVisualMediaRequest
 @MediumTest
 @RunWith(AndroidJUnit4::class)
 class PickVisualMediaRequestTest {
diff --git a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
index 6c46125..819a7dd 100644
--- a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
+++ b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
@@ -98,28 +98,26 @@
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        if (android.os.Build.VERSION.SDK_INT >= 19) {
-            pickVisualMedia = registerForActivityResult(PickVisualMedia()) { uri ->
-                toast("Got image: $uri")
-            }
-            pickMultipleVisualMedia =
-                registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
-                    var media = ""
-                    uris.forEach {
-                        media += "uri: $it \n"
-                    }
-                    toast("Got media files: $media")
-                }
-            createDocument = registerForActivityResult(CreateDocument("image/png")) { uri ->
-                toast("Created document: $uri")
-            }
-            openDocuments = registerForActivityResult(OpenMultipleDocuments()) { uris ->
-                var docs = ""
+        pickVisualMedia = registerForActivityResult(PickVisualMedia()) { uri ->
+            toast("Got image: $uri")
+        }
+        pickMultipleVisualMedia =
+            registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
+                var media = ""
                 uris.forEach {
-                    docs += "uri: $it \n"
+                    media += "uri: $it \n"
                 }
-                toast("Got documents: $docs")
+                toast("Got media files: $media")
             }
+        createDocument = registerForActivityResult(CreateDocument("image/png")) { uri ->
+            toast("Created document: $uri")
+        }
+        openDocuments = registerForActivityResult(OpenMultipleDocuments()) { uris ->
+            var docs = ""
+            uris.forEach {
+                docs += "uri: $it \n"
+            }
+            toast("Got documents: $docs")
         }
 
         setContentView {
@@ -145,28 +143,26 @@
                 button("Pick an image (w/ GET_CONTENT)") {
                     getContent.launch("image/*")
                 }
-                if (android.os.Build.VERSION.SDK_INT >= 19) {
-                    button("Pick an image (w/ photo picker)") {
-                        pickVisualMedia.launch(
-                            PickVisualMediaRequest(PickVisualMedia.ImageOnly)
-                        )
-                    }
-                    button("Pick a GIF (w/ photo picker)") {
-                        pickVisualMedia.launch(
-                            PickVisualMediaRequest(PickVisualMedia.SingleMimeType("image/gif"))
-                        )
-                    }
-                    button("Pick 5 visual media max (w/ photo picker)") {
-                        pickMultipleVisualMedia.launch(
-                            PickVisualMediaRequest(PickVisualMedia.ImageAndVideo)
-                        )
-                    }
-                    button("Create document") {
-                        createDocument.launch("Temp")
-                    }
-                    button("Open documents") {
-                        openDocuments.launch(arrayOf("*/*"))
-                    }
+                button("Pick an image (w/ photo picker)") {
+                    pickVisualMedia.launch(
+                        PickVisualMediaRequest(PickVisualMedia.ImageOnly)
+                    )
+                }
+                button("Pick a GIF (w/ photo picker)") {
+                    pickVisualMedia.launch(
+                        PickVisualMediaRequest(PickVisualMedia.SingleMimeType("image/gif"))
+                    )
+                }
+                button("Pick 5 visual media max (w/ photo picker)") {
+                    pickMultipleVisualMedia.launch(
+                        PickVisualMediaRequest(PickVisualMedia.ImageAndVideo)
+                    )
+                }
+                button("Create document") {
+                    createDocument.launch("Temp")
+                }
+                button("Open documents") {
+                    openDocuments.launch(arrayOf("*/*"))
                 }
                 button("Start IntentSender") {
                     val request = IntentSenderRequest.Builder(
diff --git a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
index 77b733f..a5cc9aa 100644
--- a/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
+++ b/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/ExperimentalDetector.kt
@@ -75,6 +75,7 @@
 import org.jetbrains.uast.getContainingUMethod
 import org.jetbrains.uast.java.JavaUAnnotation
 import org.jetbrains.uast.toUElement
+import org.jetbrains.uast.toUElementOfType
 import org.jetbrains.uast.tryResolve
 
 class ExperimentalDetector : Detector(), SourceCodeScanner {
@@ -98,13 +99,11 @@
         // Infer the overridden method by taking the first (and only) abstract method from the
         // functional interface being implemented.
         val superClass = (lambda.functionalInterfaceType as? PsiClassReferenceType)?.resolve()
-        val superMethod = superClass?.allMethods
+        superClass?.toUElementOfType<UClass>()?.methods
             ?.first { method -> method.isAbstract() }
-            ?.toUElement()
-
-        if (superMethod is UMethod) {
-            checkMethodOverride(context, lambda, superMethod)
-        }
+            ?.let { superMethod ->
+                checkMethodOverride(context, lambda, superMethod)
+            }
     }
 
     override fun visitClass(
@@ -920,4 +919,5 @@
 } == true
 
 private fun PsiModifierListOwner.isAbstract(): Boolean =
-    modifierList?.hasModifierProperty(PsiModifier.ABSTRACT) == true
+    modifierList?.hasModifierProperty(PsiModifier.ABSTRACT) == true ||
+        hasModifierProperty(PsiModifier.ABSTRACT)
diff --git a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
index d1f5856..3c4ede5 100644
--- a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
+++ b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
@@ -344,6 +344,33 @@
         check(*input).expect(expected)
     }
 
+    @Test
+    fun resolveSamWithValueClass() {
+        val input = arrayOf(
+            kotlin(
+                """
+                @JvmInline
+                value class MyValue(val p: Int)
+
+                fun interface FunInterface {
+                  fun sam(): MyValue
+                }
+
+                fun itfConsumer(itf: FunInterface) {
+                  itf.sam().p
+                }
+
+                fun test() {
+                  itfConsumer {
+                    MyValue(42)
+                  }
+                }
+                """.trimIndent()
+            )
+        )
+        check(*input).expectClean()
+    }
+
     /* ktlint-disable max-line-length */
     companion object {
         /**
diff --git a/annotation/annotation-experimental/api/1.4.0-beta01.txt b/annotation/annotation-experimental/api/1.4.0-beta01.txt
new file mode 100644
index 0000000..03452a5
--- /dev/null
+++ b/annotation/annotation-experimental/api/1.4.0-beta01.txt
@@ -0,0 +1,43 @@
+// Signature format: 4.0
+package androidx.annotation {
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE, java.lang.annotation.ElementType.TYPE}) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.LOCAL_VARIABLE, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface OptIn {
+    method public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass();
+    property public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS) public @interface RequiresOptIn {
+    method public abstract androidx.annotation.RequiresOptIn.Level level() default androidx.annotation.RequiresOptIn.Level.ERROR;
+    property public abstract androidx.annotation.RequiresOptIn.Level level;
+  }
+
+  public enum RequiresOptIn.Level {
+    method public static androidx.annotation.RequiresOptIn.Level valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.annotation.RequiresOptIn.Level[] values();
+    enum_constant public static final androidx.annotation.RequiresOptIn.Level ERROR;
+    enum_constant public static final androidx.annotation.RequiresOptIn.Level WARNING;
+  }
+
+}
+
+package androidx.annotation.experimental {
+
+  @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS) public @interface Experimental {
+    method @Deprecated public abstract androidx.annotation.experimental.Experimental.Level level() default androidx.annotation.experimental.Experimental.Level.ERROR;
+    property @Deprecated public abstract androidx.annotation.experimental.Experimental.Level level;
+  }
+
+  @Deprecated public enum Experimental.Level {
+    method @Deprecated public static androidx.annotation.experimental.Experimental.Level valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.annotation.experimental.Experimental.Level[] values();
+    enum_constant @Deprecated public static final androidx.annotation.experimental.Experimental.Level ERROR;
+    enum_constant @Deprecated public static final androidx.annotation.experimental.Experimental.Level WARNING;
+  }
+
+  @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.LOCAL_VARIABLE, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface UseExperimental {
+    method @Deprecated public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass();
+    property @Deprecated public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass;
+  }
+
+}
+
diff --git a/annotation/annotation-experimental/api/res-1.4.0-beta01.txt b/annotation/annotation-experimental/api/res-1.4.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/annotation/annotation-experimental/api/res-1.4.0-beta01.txt
diff --git a/annotation/annotation-experimental/api/restricted_1.4.0-beta01.txt b/annotation/annotation-experimental/api/restricted_1.4.0-beta01.txt
new file mode 100644
index 0000000..03452a5
--- /dev/null
+++ b/annotation/annotation-experimental/api/restricted_1.4.0-beta01.txt
@@ -0,0 +1,43 @@
+// Signature format: 4.0
+package androidx.annotation {
+
+  @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE, java.lang.annotation.ElementType.TYPE}) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.LOCAL_VARIABLE, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface OptIn {
+    method public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass();
+    property public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS) public @interface RequiresOptIn {
+    method public abstract androidx.annotation.RequiresOptIn.Level level() default androidx.annotation.RequiresOptIn.Level.ERROR;
+    property public abstract androidx.annotation.RequiresOptIn.Level level;
+  }
+
+  public enum RequiresOptIn.Level {
+    method public static androidx.annotation.RequiresOptIn.Level valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.annotation.RequiresOptIn.Level[] values();
+    enum_constant public static final androidx.annotation.RequiresOptIn.Level ERROR;
+    enum_constant public static final androidx.annotation.RequiresOptIn.Level WARNING;
+  }
+
+}
+
+package androidx.annotation.experimental {
+
+  @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS) public @interface Experimental {
+    method @Deprecated public abstract androidx.annotation.experimental.Experimental.Level level() default androidx.annotation.experimental.Experimental.Level.ERROR;
+    property @Deprecated public abstract androidx.annotation.experimental.Experimental.Level level;
+  }
+
+  @Deprecated public enum Experimental.Level {
+    method @Deprecated public static androidx.annotation.experimental.Experimental.Level valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.annotation.experimental.Experimental.Level[] values();
+    enum_constant @Deprecated public static final androidx.annotation.experimental.Experimental.Level ERROR;
+    enum_constant @Deprecated public static final androidx.annotation.experimental.Experimental.Level WARNING;
+  }
+
+  @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.LOCAL_VARIABLE, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface UseExperimental {
+    method @Deprecated public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass();
+    property @Deprecated public abstract Class<? extends java.lang.annotation.Annotation>[] markerClass;
+  }
+
+}
+
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimatorRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimatorRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimatorRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnimatorRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnyRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnyRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnyRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AnyRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ArrayRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ArrayRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ArrayRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ArrayRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AttrRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AttrRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AttrRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/AttrRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BinderThread.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BinderThread.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BinderThread.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BinderThread.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BoolRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BoolRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BoolRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/BoolRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ChecksSdkIntAtLeast.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ChecksSdkIntAtLeast.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ChecksSdkIntAtLeast.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ChecksSdkIntAtLeast.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ColorRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ColorRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ColorRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ColorRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ContentView.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ContentView.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ContentView.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/ContentView.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DeprecatedSinceApi.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DeprecatedSinceApi.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DeprecatedSinceApi.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DeprecatedSinceApi.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimenRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimenRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimenRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimenRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Dimension.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Dimension.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Dimension.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Dimension.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimensionUnit.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimensionUnit.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimensionUnit.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DimensionUnit.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DisplayContext.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DisplayContext.jvm.kt
old mode 100755
new mode 100644
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DisplayContext.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DisplayContext.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DoNotInline.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DoNotInline.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DoNotInline.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DoNotInline.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DrawableRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DrawableRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DrawableRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/DrawableRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FontRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FontRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FontRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FontRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FractionRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FractionRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FractionRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/FractionRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/GravityInt.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/GravityInt.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/GravityInt.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/GravityInt.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/HalfFloat.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/HalfFloat.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/HalfFloat.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/HalfFloat.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IdRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IdRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IdRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IdRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InspectableProperty.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InspectableProperty.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InspectableProperty.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InspectableProperty.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IntegerRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IntegerRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IntegerRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/IntegerRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InterpolatorRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InterpolatorRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InterpolatorRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/InterpolatorRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Keep.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Keep.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Keep.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Keep.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/LayoutRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/LayoutRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/LayoutRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/LayoutRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MainThread.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MainThread.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MainThread.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MainThread.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MenuRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MenuRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MenuRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/MenuRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NavigationRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NavigationRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NavigationRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NavigationRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonNull.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonNull.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonNull.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonNull.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonUiContext.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonUiContext.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonUiContext.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/NonUiContext.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Nullable.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Nullable.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Nullable.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Nullable.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/PluralsRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/PluralsRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/PluralsRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/PluralsRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Px.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Px.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Px.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/Px.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RawRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RawRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RawRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RawRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresExtension.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresExtension.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresExtension.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresExtension.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresPermission.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresPermission.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresPermission.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/RequiresPermission.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StringRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StringRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StringRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StringRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleableRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleableRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleableRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/StyleableRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/TransitionRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/TransitionRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/TransitionRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/TransitionRes.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/UiContext.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/UiContext.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/UiContext.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/UiContext.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/WorkerThread.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/WorkerThread.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/WorkerThread.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/WorkerThread.jvm.kt
diff --git a/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/XmlRes.kt b/annotation/annotation/src/jvmMain/kotlin/androidx/annotation/XmlRes.jvm.kt
similarity index 100%
rename from annotation/annotation/src/jvmMain/kotlin/androidx/annotation/XmlRes.kt
rename to annotation/annotation/src/jvmMain/kotlin/androidx/annotation/XmlRes.jvm.kt
diff --git a/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/properties/ExceptDateSamples.kt b/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/properties/ExceptDateSamples.kt
index a265e12..56c43e7 100644
--- a/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/properties/ExceptDateSamples.kt
+++ b/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/properties/ExceptDateSamples.kt
@@ -26,14 +26,13 @@
 public fun exceptDateMapWhenUsage(exceptDate: ExceptDate) =
   exceptDate.mapWhen(
     object : ExceptDate.Mapper<String> {
-      public override fun date(instance: LocalDate): String = """Got LocalDate: $instance"""
+      override fun date(instance: LocalDate): String = """Got LocalDate: $instance"""
 
-      public override fun localDateTime(instance: LocalDateTime): String =
+      override fun localDateTime(instance: LocalDateTime): String =
         """Got a local DateTime: $instance"""
 
-      public override fun instant(instance: Instant): String =
-        """Got an absolute DateTime: $instance"""
+      override fun instant(instance: Instant): String = """Got an absolute DateTime: $instance"""
 
-      public override fun orElse(): String = """Got some unrecognized variant: $exceptDate"""
+      override fun orElse(): String = """Got some unrecognized variant: $exceptDate"""
     }
   )
diff --git a/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/types/DayOfWeekSamples.kt b/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/types/DayOfWeekSamples.kt
index 395abf4..1bdc8b2 100644
--- a/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/types/DayOfWeekSamples.kt
+++ b/appactions/builtintypes/builtintypes/samples/src/main/java/androidx/appactions/builtintypes/samples/types/DayOfWeekSamples.kt
@@ -23,22 +23,22 @@
 public fun dayOfWeekMapWhenUsage(dayOfWeek: DayOfWeek) =
   dayOfWeek.mapWhen(
     object : DayOfWeek.Mapper<String> {
-      public override fun friday(): String = "Got Friday"
+      override fun friday(): String = "Got Friday"
 
-      public override fun monday(): String = "Got Monday"
+      override fun monday(): String = "Got Monday"
 
-      public override fun publicHolidays(): String = "Got PublicHolidays"
+      override fun publicHolidays(): String = "Got PublicHolidays"
 
-      public override fun saturday(): String = "Got Saturday"
+      override fun saturday(): String = "Got Saturday"
 
-      public override fun sunday(): String = "Got Sunday"
+      override fun sunday(): String = "Got Sunday"
 
-      public override fun thursday(): String = "Got Thursday"
+      override fun thursday(): String = "Got Thursday"
 
-      public override fun tuesday(): String = "Got Tuesday"
+      override fun tuesday(): String = "Got Tuesday"
 
-      public override fun wednesday(): String = "Got Wednesday"
+      override fun wednesday(): String = "Got Wednesday"
 
-      public override fun orElse(): String = """Got some unrecognized DayOfWeek: $dayOfWeek"""
+      override fun orElse(): String = """Got some unrecognized DayOfWeek: $dayOfWeek"""
     }
   )
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ByDay.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ByDay.kt
index 1f536336..1f085e1 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ByDay.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ByDay.kt
@@ -51,7 +51,7 @@
   /** Constructor for the [DayOfWeek] variant. */
   public constructor(dayOfWeek: DayOfWeek) : this(asDayOfWeek = dayOfWeek)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -64,12 +64,12 @@
       else -> error("No variant present in ByDay")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is ByDay) return false
     if (asDayOfWeek != other.asDayOfWeek) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asDayOfWeek)
+  override fun hashCode(): Int = Objects.hash(asDayOfWeek)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndDate.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndDate.kt
index 2c5db36..18964fb 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndDate.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndDate.kt
@@ -51,7 +51,7 @@
   /** Constructor for the [LocalDate] variant. */
   public constructor(date: LocalDate) : this(asDate = date)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -64,12 +64,12 @@
       else -> error("No variant present in EndDate")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is EndDate) return false
     if (asDate != other.asDate) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asDate)
+  override fun hashCode(): Int = Objects.hash(asDate)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndTime.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndTime.kt
index 7b66224..58d1b00 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndTime.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/EndTime.kt
@@ -56,7 +56,7 @@
   /** Constructor for the [LocalTime] variant. */
   public constructor(time: LocalTime) : this(asTime = time)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -69,12 +69,12 @@
       else -> error("No variant present in EndTime")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is EndTime) return false
     if (asTime != other.asTime) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asTime)
+  override fun hashCode(): Int = Objects.hash(asTime)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ExceptDate.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ExceptDate.kt
index a2e81d0..4e15b62 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ExceptDate.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/ExceptDate.kt
@@ -92,7 +92,7 @@
       else -> error("No variant present in ExceptDate")
     }
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -117,7 +117,7 @@
       else -> error("No variant present in ExceptDate")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is ExceptDate) return false
     if (asDate != other.asDate) return false
@@ -126,7 +126,7 @@
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asDate, asLocalDateTime, asInstant)
+  override fun hashCode(): Int = Objects.hash(asDate, asLocalDateTime, asInstant)
 
   /** Maps each of the possible variants of [ExceptDate] to some [R]. */
   public interface Mapper<R> {
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/Name.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/Name.kt
index 5348a83..a2d3f08 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/Name.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/Name.kt
@@ -47,7 +47,7 @@
   /** Constructor for the [String] variant. */
   public constructor(text: String) : this(asText = text)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -60,12 +60,12 @@
       else -> error("No variant present in Name")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is Name) return false
     if (asText != other.asText) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asText)
+  override fun hashCode(): Int = Objects.hash(asText)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/RepeatFrequency.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/RepeatFrequency.kt
index c66b581..861e71d 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/RepeatFrequency.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/RepeatFrequency.kt
@@ -52,7 +52,7 @@
   /** Constructor for the [Duration] variant. */
   public constructor(duration: Duration) : this(asDuration = duration)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -65,12 +65,12 @@
       else -> error("No variant present in RepeatFrequency")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is RepeatFrequency) return false
     if (asDuration != other.asDuration) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asDuration)
+  override fun hashCode(): Int = Objects.hash(asDuration)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartDate.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartDate.kt
index f6c2b67..431b420 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartDate.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartDate.kt
@@ -51,7 +51,7 @@
   /** Constructor for the [LocalDate] variant. */
   public constructor(date: LocalDate) : this(asDate = date)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -64,12 +64,12 @@
       else -> error("No variant present in StartDate")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is StartDate) return false
     if (asDate != other.asDate) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asDate)
+  override fun hashCode(): Int = Objects.hash(asDate)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartTime.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartTime.kt
index f6d9144..ea72193 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartTime.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/properties/StartTime.kt
@@ -56,7 +56,7 @@
   /** Constructor for the [LocalTime] variant. */
   public constructor(time: LocalTime) : this(asTime = time)
 
-  public override fun toString(): String = toString(includeWrapperName = true)
+  override fun toString(): String = toString(includeWrapperName = true)
 
   internal fun toString(includeWrapperName: Boolean): String =
     when {
@@ -69,12 +69,12 @@
       else -> error("No variant present in StartTime")
     }
 
-  public override fun equals(other: Any?): Boolean {
+  override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other !is StartTime) return false
     if (asTime != other.asTime) return false
     return true
   }
 
-  public override fun hashCode(): Int = Objects.hash(asTime)
+  override fun hashCode(): Int = Objects.hash(asTime)
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/serializers/DayOfWeekAsCanonicalUrlSerializer.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/serializers/DayOfWeekAsCanonicalUrlSerializer.kt
index 5dfdb1e..0579bf4 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/serializers/DayOfWeekAsCanonicalUrlSerializer.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/serializers/DayOfWeekAsCanonicalUrlSerializer.kt
@@ -27,8 +27,8 @@
  * @see DayOfWeek.canonicalUrl
  */
 public class DayOfWeekAsCanonicalUrlSerializer : StringSerializer<DayOfWeek> {
-  public override fun serialize(instance: DayOfWeek): String = instance.canonicalUrl
+  override fun serialize(instance: DayOfWeek): String = instance.canonicalUrl
 
-  public override fun deserialize(`value`: String): DayOfWeek? =
+  override fun deserialize(`value`: String): DayOfWeek? =
     DayOfWeek.values().firstOrNull { it.canonicalUrl == value }
 }
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Alarm.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Alarm.kt
index a1ff043..4ed329e 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Alarm.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Alarm.kt
@@ -67,7 +67,7 @@
     get() = null
 
   /** Converts this [Alarm] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -82,7 +82,7 @@
    */
   public interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
     /** Returns a built [Alarm]. */
-    public override fun build(): Alarm
+    override fun build(): Alarm
 
     /** Sets the `alarmSchedule`. */
     @Suppress("DocumentExceptions")
@@ -106,8 +106,8 @@
  * )
  * class MyAlarm internal constructor(
  *   alarm: Alarm,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractAlarm<
  *   MyAlarm,
  *   MyAlarm.Builder
@@ -127,6 +127,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractAlarm.Builder<
  *       Builder,
@@ -142,11 +143,11 @@
   Builder : AbstractAlarm.Builder<Builder, Self>
 >
 internal constructor(
-  public final override val namespace: String,
-  public final override val alarmSchedule: Schedule?,
-  @get:Suppress("AutoBoxing") public final override val isAlarmEnabled: Boolean?,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val alarmSchedule: Schedule?,
+  @get:Suppress("AutoBoxing") final override val isAlarmEnabled: Boolean?,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : Alarm {
   /**
    * Human readable name for the concrete [Self] class.
@@ -170,7 +171,7 @@
   /** Returns a concrete [Builder] with the additional, non-[Alarm] properties copied over. */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setAlarmSchedule(alarmSchedule)
@@ -178,7 +179,7 @@
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -191,10 +192,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, alarmSchedule, isAlarmEnabled, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -221,11 +222,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyAlarm :
    *   : AbstractAlarm<
    *     MyAlarm,
    *     MyAlarm.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractAlarm.Builder<
    *       Builder,
@@ -307,36 +310,36 @@
      */
     @Suppress("BuilderSetStyle") protected abstract fun buildFromAlarm(alarm: Alarm): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromAlarm(AlarmImpl(namespace, alarmSchedule, isAlarmEnabled, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setAlarmSchedule(schedule: Schedule?): Self {
+    final override fun setAlarmSchedule(schedule: Schedule?): Self {
       this.alarmSchedule = schedule
       return this as Self
     }
 
-    public final override fun setAlarmEnabled(@Suppress("AutoBoxing") boolean: Boolean?): Self {
+    final override fun setAlarmEnabled(@Suppress("AutoBoxing") boolean: Boolean?): Self {
       this.isAlarmEnabled = boolean
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -350,11 +353,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, alarmSchedule, isAlarmEnabled, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/CommonExecutionStatus.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/CommonExecutionStatus.kt
index 067ccb1..9bf51a9 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/CommonExecutionStatus.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/CommonExecutionStatus.kt
@@ -49,7 +49,7 @@
 )
 public interface CommonExecutionStatus : ExecutionStatus {
   /** Converts this [CommonExecutionStatus] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -66,7 +66,7 @@
    */
   public interface Builder<Self : Builder<Self>> : ExecutionStatus.Builder<Self> {
     /** Returns a built [CommonExecutionStatus]. */
-    public override fun build(): CommonExecutionStatus
+    override fun build(): CommonExecutionStatus
   }
 }
 
@@ -81,8 +81,8 @@
  * )
  * class MyCommonExecutionStatus internal constructor(
  *   commonExecutionStatus: CommonExecutionStatus,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractCommonExecutionStatus<
  *   MyCommonExecutionStatus,
  *   MyCommonExecutionStatus.Builder
@@ -102,6 +102,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractCommonExecutionStatus.Builder<
  *       Builder,
@@ -113,13 +114,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractCommonExecutionStatus<
-    Self : AbstractCommonExecutionStatus<Self, Builder>,
-    Builder : AbstractCommonExecutionStatus.Builder<Builder, Self>
-    >
+  Self : AbstractCommonExecutionStatus<Self, Builder>,
+  Builder : AbstractCommonExecutionStatus.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : CommonExecutionStatus {
   /**
    * Human readable name for the concrete [Self] class.
@@ -152,13 +153,13 @@
    */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -169,10 +170,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -193,11 +194,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyCommonExecutionStatus :
    *   : AbstractCommonExecutionStatus<
    *     MyCommonExecutionStatus,
    *     MyCommonExecutionStatus.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractCommonExecutionStatus.Builder<
    *       Builder,
@@ -244,9 +247,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractCommonExecutionStatus<Built, Self>
-      > : CommonExecutionStatus.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractCommonExecutionStatus<Built, Self>
+  > : CommonExecutionStatus.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -281,26 +284,26 @@
       commonExecutionStatus: CommonExecutionStatus
     ): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromCommonExecutionStatus(CommonExecutionStatusImpl(namespace, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -312,11 +315,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/DayOfWeek.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/DayOfWeek.kt
index 5eb1d15..450fdc3 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/DayOfWeek.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/DayOfWeek.kt
@@ -54,7 +54,7 @@
       else -> mapper.orElse()
     }
 
-  public override fun toString(): String = """DayOfWeek($canonicalUrl)"""
+  override fun toString(): String = """DayOfWeek($canonicalUrl)"""
 
   public companion object {
     /** The day of the week between Thursday and Saturday. */
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ExecutionStatus.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ExecutionStatus.kt
index 83fec04..52faa64 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ExecutionStatus.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ExecutionStatus.kt
@@ -49,7 +49,7 @@
 )
 public interface ExecutionStatus : Intangible {
   /** Converts this [ExecutionStatus] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -66,7 +66,7 @@
    */
   public interface Builder<Self : Builder<Self>> : Intangible.Builder<Self> {
     /** Returns a built [ExecutionStatus]. */
-    public override fun build(): ExecutionStatus
+    override fun build(): ExecutionStatus
   }
 }
 
@@ -81,8 +81,8 @@
  * )
  * class MyExecutionStatus internal constructor(
  *   executionStatus: ExecutionStatus,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractExecutionStatus<
  *   MyExecutionStatus,
  *   MyExecutionStatus.Builder
@@ -102,6 +102,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractExecutionStatus.Builder<
  *       Builder,
@@ -113,13 +114,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractExecutionStatus<
-    Self : AbstractExecutionStatus<Self, Builder>,
-    Builder : AbstractExecutionStatus.Builder<Builder, Self>
-    >
+  Self : AbstractExecutionStatus<Self, Builder>,
+  Builder : AbstractExecutionStatus.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : ExecutionStatus {
   /**
    * Human readable name for the concrete [Self] class.
@@ -145,13 +146,13 @@
    */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -162,10 +163,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -186,11 +187,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyExecutionStatus :
    *   : AbstractExecutionStatus<
    *     MyExecutionStatus,
    *     MyExecutionStatus.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractExecutionStatus.Builder<
    *       Builder,
@@ -237,9 +240,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractExecutionStatus<Built, Self>
-      > : ExecutionStatus.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractExecutionStatus<Built, Self>
+  > : ExecutionStatus.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -271,26 +274,26 @@
     @Suppress("BuilderSetStyle")
     protected abstract fun buildFromExecutionStatus(executionStatus: ExecutionStatus): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromExecutionStatus(ExecutionStatusImpl(namespace, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -302,11 +305,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/GenericErrorStatus.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/GenericErrorStatus.kt
index 6fd1add..9b05a4a 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/GenericErrorStatus.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/GenericErrorStatus.kt
@@ -45,7 +45,7 @@
 )
 public interface GenericErrorStatus : CommonExecutionStatus {
   /** Converts this [GenericErrorStatus] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -62,7 +62,7 @@
    */
   public interface Builder<Self : Builder<Self>> : CommonExecutionStatus.Builder<Self> {
     /** Returns a built [GenericErrorStatus]. */
-    public override fun build(): GenericErrorStatus
+    override fun build(): GenericErrorStatus
   }
 }
 
@@ -77,8 +77,8 @@
  * )
  * class MyGenericErrorStatus internal constructor(
  *   genericErrorStatus: GenericErrorStatus,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractGenericErrorStatus<
  *   MyGenericErrorStatus,
  *   MyGenericErrorStatus.Builder
@@ -98,6 +98,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractGenericErrorStatus.Builder<
  *       Builder,
@@ -109,13 +110,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractGenericErrorStatus<
-    Self : AbstractGenericErrorStatus<Self, Builder>,
-    Builder : AbstractGenericErrorStatus.Builder<Builder, Self>
-    >
+  Self : AbstractGenericErrorStatus<Self, Builder>,
+  Builder : AbstractGenericErrorStatus.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : GenericErrorStatus {
   /**
    * Human readable name for the concrete [Self] class.
@@ -142,13 +143,13 @@
    */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -159,10 +160,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -183,11 +184,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyGenericErrorStatus :
    *   : AbstractGenericErrorStatus<
    *     MyGenericErrorStatus,
    *     MyGenericErrorStatus.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractGenericErrorStatus.Builder<
    *       Builder,
@@ -234,9 +237,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractGenericErrorStatus<Built, Self>
-      > : GenericErrorStatus.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractGenericErrorStatus<Built, Self>
+  > : GenericErrorStatus.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -271,26 +274,26 @@
       genericErrorStatus: GenericErrorStatus
     ): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromGenericErrorStatus(GenericErrorStatusImpl(namespace, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -302,11 +305,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Intangible.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Intangible.kt
index 7f3e192..09aaac6 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Intangible.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Intangible.kt
@@ -46,7 +46,7 @@
 )
 public interface Intangible : Thing {
   /** Converts this [Intangible] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -61,7 +61,7 @@
    */
   public interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
     /** Returns a built [Intangible]. */
-    public override fun build(): Intangible
+    override fun build(): Intangible
   }
 }
 
@@ -76,8 +76,8 @@
  * )
  * class MyIntangible internal constructor(
  *   intangible: Intangible,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractIntangible<
  *   MyIntangible,
  *   MyIntangible.Builder
@@ -97,6 +97,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractIntangible.Builder<
  *       Builder,
@@ -108,13 +109,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractIntangible<
-    Self : AbstractIntangible<Self, Builder>,
-    Builder : AbstractIntangible.Builder<Builder, Self>
-    >
+  Self : AbstractIntangible<Self, Builder>,
+  Builder : AbstractIntangible.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : Intangible {
   /**
    * Human readable name for the concrete [Self] class.
@@ -138,13 +139,13 @@
   /** Returns a concrete [Builder] with the additional, non-[Intangible] properties copied over. */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -155,10 +156,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -179,11 +180,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyIntangible :
    *   : AbstractIntangible<
    *     MyIntangible,
    *     MyIntangible.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractIntangible.Builder<
    *       Builder,
@@ -230,9 +233,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractIntangible<Built, Self>
-      > : Intangible.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractIntangible<Built, Self>
+  > : Intangible.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -264,26 +267,26 @@
     @Suppress("BuilderSetStyle")
     protected abstract fun buildFromIntangible(intangible: Intangible): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromIntangible(IntangibleImpl(namespace, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -295,11 +298,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ObjectCreationLimitReachedStatus.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ObjectCreationLimitReachedStatus.kt
index e5cc7ed..bb7888c 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ObjectCreationLimitReachedStatus.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/ObjectCreationLimitReachedStatus.kt
@@ -50,7 +50,7 @@
    * Converts this [ObjectCreationLimitReachedStatus] to its builder with all the properties copied
    * over.
    */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -67,7 +67,7 @@
    */
   public interface Builder<Self : Builder<Self>> : ExecutionStatus.Builder<Self> {
     /** Returns a built [ObjectCreationLimitReachedStatus]. */
-    public override fun build(): ObjectCreationLimitReachedStatus
+    override fun build(): ObjectCreationLimitReachedStatus
   }
 }
 
@@ -82,8 +82,8 @@
  * )
  * class MyObjectCreationLimitReachedStatus internal constructor(
  *   objectCreationLimitReachedStatus: ObjectCreationLimitReachedStatus,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractObjectCreationLimitReachedStatus<
  *   MyObjectCreationLimitReachedStatus,
  *   MyObjectCreationLimitReachedStatus.Builder
@@ -103,6 +103,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractObjectCreationLimitReachedStatus.Builder<
  *       Builder,
@@ -114,13 +115,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractObjectCreationLimitReachedStatus<
-    Self : AbstractObjectCreationLimitReachedStatus<Self, Builder>,
-    Builder : AbstractObjectCreationLimitReachedStatus.Builder<Builder, Self>
-    >
+  Self : AbstractObjectCreationLimitReachedStatus<Self, Builder>,
+  Builder : AbstractObjectCreationLimitReachedStatus.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : ObjectCreationLimitReachedStatus {
   /**
    * Human readable name for the concrete [Self] class.
@@ -154,13 +155,13 @@
    */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -171,10 +172,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -195,11 +196,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyObjectCreationLimitReachedStatus :
    *   : AbstractObjectCreationLimitReachedStatus<
    *     MyObjectCreationLimitReachedStatus,
    *     MyObjectCreationLimitReachedStatus.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractObjectCreationLimitReachedStatus.Builder<
    *       Builder,
@@ -246,9 +249,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractObjectCreationLimitReachedStatus<Built, Self>
-      > : ObjectCreationLimitReachedStatus.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractObjectCreationLimitReachedStatus<Built, Self>
+  > : ObjectCreationLimitReachedStatus.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -283,28 +286,28 @@
       objectCreationLimitReachedStatus: ObjectCreationLimitReachedStatus
     ): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromObjectCreationLimitReachedStatus(
         ObjectCreationLimitReachedStatusImpl(namespace, identifier, name)
       )
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -316,11 +319,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
@@ -341,8 +344,8 @@
 
 private class ObjectCreationLimitReachedStatusImpl :
   AbstractObjectCreationLimitReachedStatus<
-      ObjectCreationLimitReachedStatusImpl, ObjectCreationLimitReachedStatusImpl.Builder
-      > {
+    ObjectCreationLimitReachedStatusImpl, ObjectCreationLimitReachedStatusImpl.Builder
+  > {
   protected override val selfTypeName: String
     get() = "ObjectCreationLimitReachedStatus"
 
@@ -363,8 +366,8 @@
 
   public class Builder :
     AbstractObjectCreationLimitReachedStatus.Builder<
-        Builder, ObjectCreationLimitReachedStatusImpl
-        >() {
+      Builder, ObjectCreationLimitReachedStatusImpl
+    >() {
     protected override val selfTypeName: String
       get() = "ObjectCreationLimitReachedStatus.Builder"
 
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Person.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Person.kt
index 35da28c..51aca82 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Person.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Person.kt
@@ -64,7 +64,7 @@
     get() = null
 
   /** Converts this [Person] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -79,7 +79,7 @@
    */
   public interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
     /** Returns a built [Person]. */
-    public override fun build(): Person
+    override fun build(): Person
 
     /** Sets the `email`. */
     @Suppress("DocumentExceptions")
@@ -102,8 +102,8 @@
  * )
  * class MyPerson internal constructor(
  *   person: Person,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractPerson<
  *   MyPerson,
  *   MyPerson.Builder
@@ -123,6 +123,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractPerson.Builder<
  *       Builder,
@@ -138,11 +139,11 @@
   Builder : AbstractPerson.Builder<Builder, Self>
 >
 internal constructor(
-  public final override val namespace: String,
-  public final override val email: String?,
-  public final override val telephoneNumber: String?,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val email: String?,
+  final override val telephoneNumber: String?,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : Person {
   /**
    * Human readable name for the concrete [Self] class.
@@ -166,7 +167,7 @@
   /** Returns a concrete [Builder] with the additional, non-[Person] properties copied over. */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setEmail(email)
@@ -174,7 +175,7 @@
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -187,10 +188,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, email, telephoneNumber, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -217,11 +218,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyPerson :
    *   : AbstractPerson<
    *     MyPerson,
    *     MyPerson.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractPerson.Builder<
    *       Builder,
@@ -303,36 +306,36 @@
      */
     @Suppress("BuilderSetStyle") protected abstract fun buildFromPerson(person: Person): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromPerson(PersonImpl(namespace, email, telephoneNumber, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setEmail(text: String?): Self {
+    final override fun setEmail(text: String?): Self {
       this.email = text
       return this as Self
     }
 
-    public final override fun setTelephoneNumber(text: String?): Self {
+    final override fun setTelephoneNumber(text: String?): Self {
       this.telephoneNumber = text
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -346,11 +349,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, email, telephoneNumber, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Schedule.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Schedule.kt
index 0f2ec37..8a83a84 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Schedule.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Schedule.kt
@@ -201,7 +201,7 @@
     get() = null
 
   /** Converts this [Schedule] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -216,7 +216,7 @@
    */
   public interface Builder<Self : Builder<Self>> : Intangible.Builder<Self> {
     /** Returns a built [Schedule]. */
-    public override fun build(): Schedule
+    override fun build(): Schedule
 
     /** Appends [DayOfWeek] as a value to `byDays`. */
     public fun addByDay(dayOfWeek: DayOfWeek): Self = addByDay(ByDay(dayOfWeek))
@@ -340,8 +340,8 @@
  * )
  * class MySchedule internal constructor(
  *   schedule: Schedule,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractSchedule<
  *   MySchedule,
  *   MySchedule.Builder
@@ -361,6 +361,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractSchedule.Builder<
  *       Builder,
@@ -376,21 +377,21 @@
   Builder : AbstractSchedule.Builder<Builder, Self>
 >
 internal constructor(
-  public final override val namespace: String,
-  public final override val byDays: List<ByDay>,
-  public final override val byMonths: List<Long>,
-  public final override val byMonthDays: List<Long>,
-  public final override val byMonthWeeks: List<Long>,
-  public final override val endDate: EndDate?,
-  public final override val endTime: EndTime?,
-  public final override val exceptDate: ExceptDate?,
-  @get:Suppress("AutoBoxing") public final override val repeatCount: Long?,
-  public final override val repeatFrequency: RepeatFrequency?,
-  public final override val scheduleTimezone: String?,
-  public final override val startDate: StartDate?,
-  public final override val startTime: StartTime?,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val byDays: List<ByDay>,
+  final override val byMonths: List<Long>,
+  final override val byMonthDays: List<Long>,
+  final override val byMonthWeeks: List<Long>,
+  final override val endDate: EndDate?,
+  final override val endTime: EndTime?,
+  final override val exceptDate: ExceptDate?,
+  @get:Suppress("AutoBoxing") final override val repeatCount: Long?,
+  final override val repeatFrequency: RepeatFrequency?,
+  final override val scheduleTimezone: String?,
+  final override val startDate: StartDate?,
+  final override val startTime: StartTime?,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : Schedule {
   /**
    * Human readable name for the concrete [Self] class.
@@ -430,7 +431,7 @@
   /** Returns a concrete [Builder] with the additional, non-[Schedule] properties copied over. */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .addByDays(byDays)
@@ -448,7 +449,7 @@
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -471,7 +472,7 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(
       namespace,
       byDays,
@@ -491,7 +492,7 @@
       additionalProperties
     )
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -548,11 +549,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MySchedule :
    *   : AbstractSchedule<
    *     MySchedule,
    *     MySchedule.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractSchedule.Builder<
    *       Builder,
@@ -656,7 +659,7 @@
      */
     @Suppress("BuilderSetStyle") protected abstract fun buildFromSchedule(schedule: Schedule): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromSchedule(
         ScheduleImpl(
           namespace,
@@ -677,123 +680,123 @@
         )
       )
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun addByDay(byDay: ByDay): Self {
+    final override fun addByDay(byDay: ByDay): Self {
       byDays += byDay
       return this as Self
     }
 
-    public final override fun addByDays(values: Iterable<ByDay>): Self {
+    final override fun addByDays(values: Iterable<ByDay>): Self {
       byDays += values
       return this as Self
     }
 
-    public final override fun clearByDays(): Self {
+    final override fun clearByDays(): Self {
       byDays.clear()
       return this as Self
     }
 
-    public final override fun addByMonth(integer: Long): Self {
+    final override fun addByMonth(integer: Long): Self {
       byMonths += integer
       return this as Self
     }
 
-    public final override fun addByMonths(values: Iterable<Long>): Self {
+    final override fun addByMonths(values: Iterable<Long>): Self {
       byMonths += values
       return this as Self
     }
 
-    public final override fun clearByMonths(): Self {
+    final override fun clearByMonths(): Self {
       byMonths.clear()
       return this as Self
     }
 
-    public final override fun addByMonthDay(integer: Long): Self {
+    final override fun addByMonthDay(integer: Long): Self {
       byMonthDays += integer
       return this as Self
     }
 
-    public final override fun addByMonthDays(values: Iterable<Long>): Self {
+    final override fun addByMonthDays(values: Iterable<Long>): Self {
       byMonthDays += values
       return this as Self
     }
 
-    public final override fun clearByMonthDays(): Self {
+    final override fun clearByMonthDays(): Self {
       byMonthDays.clear()
       return this as Self
     }
 
-    public final override fun addByMonthWeek(integer: Long): Self {
+    final override fun addByMonthWeek(integer: Long): Self {
       byMonthWeeks += integer
       return this as Self
     }
 
-    public final override fun addByMonthWeeks(values: Iterable<Long>): Self {
+    final override fun addByMonthWeeks(values: Iterable<Long>): Self {
       byMonthWeeks += values
       return this as Self
     }
 
-    public final override fun clearByMonthWeeks(): Self {
+    final override fun clearByMonthWeeks(): Self {
       byMonthWeeks.clear()
       return this as Self
     }
 
-    public final override fun setEndDate(endDate: EndDate?): Self {
+    final override fun setEndDate(endDate: EndDate?): Self {
       this.endDate = endDate
       return this as Self
     }
 
-    public final override fun setEndTime(endTime: EndTime?): Self {
+    final override fun setEndTime(endTime: EndTime?): Self {
       this.endTime = endTime
       return this as Self
     }
 
-    public final override fun setExceptDate(exceptDate: ExceptDate?): Self {
+    final override fun setExceptDate(exceptDate: ExceptDate?): Self {
       this.exceptDate = exceptDate
       return this as Self
     }
 
-    public final override fun setRepeatCount(@Suppress("AutoBoxing") integer: Long?): Self {
+    final override fun setRepeatCount(@Suppress("AutoBoxing") integer: Long?): Self {
       this.repeatCount = integer
       return this as Self
     }
 
-    public final override fun setRepeatFrequency(repeatFrequency: RepeatFrequency?): Self {
+    final override fun setRepeatFrequency(repeatFrequency: RepeatFrequency?): Self {
       this.repeatFrequency = repeatFrequency
       return this as Self
     }
 
-    public final override fun setScheduleTimezone(text: String?): Self {
+    final override fun setScheduleTimezone(text: String?): Self {
       this.scheduleTimezone = text
       return this as Self
     }
 
-    public final override fun setStartDate(startDate: StartDate?): Self {
+    final override fun setStartDate(startDate: StartDate?): Self {
       this.startDate = startDate
       return this as Self
     }
 
-    public final override fun setStartTime(startTime: StartTime?): Self {
+    final override fun setStartTime(startTime: StartTime?): Self {
       this.startTime = startTime
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -817,7 +820,7 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(
         namespace,
         byDays,
@@ -838,7 +841,7 @@
       )
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/SuccessStatus.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/SuccessStatus.kt
index 48d1590..65ac499 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/SuccessStatus.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/SuccessStatus.kt
@@ -45,7 +45,7 @@
 )
 public interface SuccessStatus : CommonExecutionStatus {
   /** Converts this [SuccessStatus] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -62,7 +62,7 @@
    */
   public interface Builder<Self : Builder<Self>> : CommonExecutionStatus.Builder<Self> {
     /** Returns a built [SuccessStatus]. */
-    public override fun build(): SuccessStatus
+    override fun build(): SuccessStatus
   }
 }
 
@@ -77,8 +77,8 @@
  * )
  * class MySuccessStatus internal constructor(
  *   successStatus: SuccessStatus,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractSuccessStatus<
  *   MySuccessStatus,
  *   MySuccessStatus.Builder
@@ -98,6 +98,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractSuccessStatus.Builder<
  *       Builder,
@@ -109,13 +110,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractSuccessStatus<
-    Self : AbstractSuccessStatus<Self, Builder>,
-    Builder : AbstractSuccessStatus.Builder<Builder, Self>
-    >
+  Self : AbstractSuccessStatus<Self, Builder>,
+  Builder : AbstractSuccessStatus.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : SuccessStatus {
   /**
    * Human readable name for the concrete [Self] class.
@@ -141,13 +142,13 @@
    */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -158,10 +159,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -182,11 +183,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MySuccessStatus :
    *   : AbstractSuccessStatus<
    *     MySuccessStatus,
    *     MySuccessStatus.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractSuccessStatus.Builder<
    *       Builder,
@@ -233,9 +236,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractSuccessStatus<Built, Self>
-      > : SuccessStatus.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractSuccessStatus<Built, Self>
+  > : SuccessStatus.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -267,26 +270,26 @@
     @Suppress("BuilderSetStyle")
     protected abstract fun buildFromSuccessStatus(successStatus: SuccessStatus): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromSuccessStatus(SuccessStatusImpl(namespace, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -298,11 +301,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Thing.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Thing.kt
index 585d0c9..f86de3b 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Thing.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Thing.kt
@@ -113,8 +113,8 @@
  * )
  * class MyThing internal constructor(
  *   thing: Thing,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractThing<
  *   MyThing,
  *   MyThing.Builder
@@ -134,6 +134,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractThing.Builder<
  *       Builder,
@@ -149,9 +150,9 @@
   Builder : AbstractThing.Builder<Builder, Self>
 >
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : Thing {
   /**
    * Human readable name for the concrete [Self] class.
@@ -173,13 +174,13 @@
   /** Returns a concrete [Builder] with the additional, non-[Thing] properties copied over. */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -190,10 +191,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -214,11 +215,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyThing :
    *   : AbstractThing<
    *     MyThing,
    *     MyThing.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractThing.Builder<
    *       Builder,
@@ -296,26 +299,25 @@
      */
     @Suppress("BuilderSetStyle") protected abstract fun buildFromThing(thing: Thing): Built
 
-    public final override fun build(): Built =
-      buildFromThing(ThingImpl(namespace, identifier, name))
+    final override fun build(): Built = buildFromThing(ThingImpl(namespace, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -327,11 +329,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Timer.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Timer.kt
index a40ebf1..c34b587 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Timer.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/Timer.kt
@@ -57,7 +57,7 @@
     get() = null
 
   /** Converts this [Timer] to its builder with all the properties copied over. */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -72,7 +72,7 @@
    */
   public interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
     /** Returns a built [Timer]. */
-    public override fun build(): Timer
+    override fun build(): Timer
 
     /** Sets the `duration`. */
     @Suppress("DocumentExceptions")
@@ -91,8 +91,8 @@
  * )
  * class MyTimer internal constructor(
  *   timer: Timer,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractTimer<
  *   MyTimer,
  *   MyTimer.Builder
@@ -112,6 +112,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractTimer.Builder<
  *       Builder,
@@ -127,10 +128,10 @@
   Builder : AbstractTimer.Builder<Builder, Self>
 >
 internal constructor(
-  public final override val namespace: String,
-  public final override val duration: Duration?,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val duration: Duration?,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : Timer {
   /**
    * Human readable name for the concrete [Self] class.
@@ -154,14 +155,14 @@
   /** Returns a concrete [Builder] with the additional, non-[Timer] properties copied over. */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setDuration(duration)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -173,10 +174,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, duration, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -200,11 +201,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyTimer :
    *   : AbstractTimer<
    *     MyTimer,
    *     MyTimer.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractTimer.Builder<
    *       Builder,
@@ -284,31 +287,31 @@
      */
     @Suppress("BuilderSetStyle") protected abstract fun buildFromTimer(timer: Timer): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromTimer(TimerImpl(namespace, duration, identifier, name))
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setDuration(duration: Duration?): Self {
+    final override fun setDuration(duration: Duration?): Self {
       this.duration = duration
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -321,11 +324,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, duration, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
diff --git a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/UnsupportedOperationStatus.kt b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/UnsupportedOperationStatus.kt
index f4c63a4..7743764 100644
--- a/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/UnsupportedOperationStatus.kt
+++ b/appactions/builtintypes/builtintypes/src/main/java/androidx/appactions/builtintypes/types/UnsupportedOperationStatus.kt
@@ -48,7 +48,7 @@
   /**
    * Converts this [UnsupportedOperationStatus] to its builder with all the properties copied over.
    */
-  public override fun toBuilder(): Builder<*>
+  override fun toBuilder(): Builder<*>
 
   public companion object {
     /** Returns a default implementation of [Builder]. */
@@ -65,7 +65,7 @@
    */
   public interface Builder<Self : Builder<Self>> : ExecutionStatus.Builder<Self> {
     /** Returns a built [UnsupportedOperationStatus]. */
-    public override fun build(): UnsupportedOperationStatus
+    override fun build(): UnsupportedOperationStatus
   }
 }
 
@@ -80,8 +80,8 @@
  * )
  * class MyUnsupportedOperationStatus internal constructor(
  *   unsupportedOperationStatus: UnsupportedOperationStatus,
- *   val foo: String,
- *   val bars: List<Int>,
+ *   @Document.StringProperty val foo: String,
+ *   @Document.LongProperty val bars: List<Int>,
  * ) : AbstractUnsupportedOperationStatus<
  *   MyUnsupportedOperationStatus,
  *   MyUnsupportedOperationStatus.Builder
@@ -101,6 +101,7 @@
  *       .addBars(bars)
  *   }
  *
+ *   @Document.BuilderProducer
  *   class Builder :
  *     AbstractUnsupportedOperationStatus.Builder<
  *       Builder,
@@ -112,13 +113,13 @@
  */
 @Suppress("UNCHECKED_CAST")
 public abstract class AbstractUnsupportedOperationStatus<
-    Self : AbstractUnsupportedOperationStatus<Self, Builder>,
-    Builder : AbstractUnsupportedOperationStatus.Builder<Builder, Self>
-    >
+  Self : AbstractUnsupportedOperationStatus<Self, Builder>,
+  Builder : AbstractUnsupportedOperationStatus.Builder<Builder, Self>
+>
 internal constructor(
-  public final override val namespace: String,
-  public final override val identifier: String,
-  public final override val name: Name?,
+  final override val namespace: String,
+  final override val identifier: String,
+  final override val name: Name?,
 ) : UnsupportedOperationStatus {
   /**
    * Human readable name for the concrete [Self] class.
@@ -152,13 +153,13 @@
    */
   protected abstract fun toBuilderWithAdditionalPropertiesOnly(): Builder
 
-  public final override fun toBuilder(): Builder =
+  final override fun toBuilder(): Builder =
     toBuilderWithAdditionalPropertiesOnly()
       .setNamespace(namespace)
       .setIdentifier(identifier)
       .setName(name)
 
-  public final override fun equals(other: Any?): Boolean {
+  final override fun equals(other: Any?): Boolean {
     if (this === other) return true
     if (other == null || this::class.java != other::class.java) return false
     other as Self
@@ -169,10 +170,10 @@
     return true
   }
 
-  public final override fun hashCode(): Int =
+  final override fun hashCode(): Int =
     Objects.hash(namespace, identifier, name, additionalProperties)
 
-  public final override fun toString(): String {
+  final override fun toString(): String {
     val attributes = mutableMapOf<String, String>()
     if (namespace.isNotEmpty()) {
       attributes["namespace"] = namespace
@@ -193,11 +194,13 @@
    *
    * Allows for extension like:
    * ```kt
+   * @Document(...)
    * class MyUnsupportedOperationStatus :
    *   : AbstractUnsupportedOperationStatus<
    *     MyUnsupportedOperationStatus,
    *     MyUnsupportedOperationStatus.Builder>(...) {
    *
+   *   @Document.BuilderProducer
    *   class Builder
    *   : AbstractUnsupportedOperationStatus.Builder<
    *       Builder,
@@ -244,9 +247,9 @@
    */
   @Suppress("StaticFinalBuilder")
   public abstract class Builder<
-      Self : Builder<Self, Built>,
-      Built : AbstractUnsupportedOperationStatus<Built, Self>
-      > : UnsupportedOperationStatus.Builder<Self> {
+    Self : Builder<Self, Built>,
+    Built : AbstractUnsupportedOperationStatus<Built, Self>
+  > : UnsupportedOperationStatus.Builder<Self> {
     /**
      * Human readable name for the concrete [Self] class.
      *
@@ -281,28 +284,28 @@
       unsupportedOperationStatus: UnsupportedOperationStatus
     ): Built
 
-    public final override fun build(): Built =
+    final override fun build(): Built =
       buildFromUnsupportedOperationStatus(
         UnsupportedOperationStatusImpl(namespace, identifier, name)
       )
 
-    public final override fun setNamespace(namespace: String): Self {
+    final override fun setNamespace(namespace: String): Self {
       this.namespace = namespace
       return this as Self
     }
 
-    public final override fun setIdentifier(text: String): Self {
+    final override fun setIdentifier(text: String): Self {
       this.identifier = text
       return this as Self
     }
 
-    public final override fun setName(name: Name?): Self {
+    final override fun setName(name: Name?): Self {
       this.name = name
       return this as Self
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun equals(other: Any?): Boolean {
+    final override fun equals(other: Any?): Boolean {
       if (this === other) return true
       if (other == null || this::class.java != other::class.java) return false
       other as Self
@@ -314,11 +317,11 @@
     }
 
     @Suppress("BuilderSetStyle")
-    public final override fun hashCode(): Int =
+    final override fun hashCode(): Int =
       Objects.hash(namespace, identifier, name, additionalProperties)
 
     @Suppress("BuilderSetStyle")
-    public final override fun toString(): String {
+    final override fun toString(): String {
       val attributes = mutableMapOf<String, String>()
       if (namespace.isNotEmpty()) {
         attributes["namespace"] = namespace
@@ -339,8 +342,8 @@
 
 private class UnsupportedOperationStatusImpl :
   AbstractUnsupportedOperationStatus<
-      UnsupportedOperationStatusImpl, UnsupportedOperationStatusImpl.Builder
-      > {
+    UnsupportedOperationStatusImpl, UnsupportedOperationStatusImpl.Builder
+  > {
   protected override val selfTypeName: String
     get() = "UnsupportedOperationStatus"
 
diff --git a/appcompat/appcompat-resources/api/restricted_current.txt b/appcompat/appcompat-resources/api/restricted_current.txt
index 6a66d3a..1278c5d 100644
--- a/appcompat/appcompat-resources/api/restricted_current.txt
+++ b/appcompat/appcompat-resources/api/restricted_current.txt
@@ -58,7 +58,7 @@
 package androidx.appcompat.widget {
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DrawableUtils {
-    method public static boolean canSafelyMutateDrawable(android.graphics.drawable.Drawable);
+    method @Deprecated public static boolean canSafelyMutateDrawable(android.graphics.drawable.Drawable);
     method public static android.graphics.Rect getOpticalBounds(android.graphics.drawable.Drawable);
     method public static android.graphics.PorterDuff.Mode! parseTintMode(int, android.graphics.PorterDuff.Mode!);
     field public static final android.graphics.Rect! INSETS_NONE;
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/DrawableContainerCompat.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/DrawableContainerCompat.java
index d9730ce..9fd6026 100644
--- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/DrawableContainerCompat.java
+++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/DrawableContainerCompat.java
@@ -517,9 +517,7 @@
             if (Build.VERSION.SDK_INT >= 23) {
                 DrawableCompat.setLayoutDirection(d, DrawableCompat.getLayoutDirection(this));
             }
-            if (Build.VERSION.SDK_INT >= 19) {
-                DrawableCompat.setAutoMirrored(d, mDrawableContainerState.mAutoMirrored);
-            }
+            DrawableCompat.setAutoMirrored(d, mDrawableContainerState.mAutoMirrored);
             final Rect hotspotBounds = mHotspotBounds;
             if (Build.VERSION.SDK_INT >= 21 && hotspotBounds != null) {
                 DrawableCompat.setHotspotBounds(d, hotspotBounds.left, hotspotBounds.top,
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
index 9349881..04e9541 100644
--- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
+++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
@@ -24,20 +24,13 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.DrawableContainer;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.InsetDrawable;
-import android.graphics.drawable.LayerDrawable;
-import android.graphics.drawable.ScaleDrawable;
 import android.os.Build;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
-import androidx.appcompat.graphics.drawable.DrawableWrapperCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
-import androidx.core.graphics.drawable.WrappedDrawable;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -69,13 +62,9 @@
                     insets.right,
                     insets.bottom
             );
-        } else if (Build.VERSION.SDK_INT >= 18) {
+        } else {
             return Api18Impl.getOpticalInsets(DrawableCompat.unwrap(drawable));
         }
-
-        // If we reach here, either we're running on a device pre-v18, the Drawable didn't have
-        // any optical insets, or a reflection issue, so we'll just return an empty rect.
-        return INSETS_NONE;
     }
 
     /**
@@ -101,43 +90,11 @@
     /**
      * Some drawable implementations have problems with mutation. This method returns false if
      * there is a known issue in the given drawable's implementation.
+     *
+     * @deprecated it is always true.
      */
+    @Deprecated
     public static boolean canSafelyMutateDrawable(@NonNull Drawable drawable) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            // We'll never return false on API level >= 17, stop early.
-            return true;
-        }
-
-        if (Build.VERSION.SDK_INT < 15 && drawable instanceof InsetDrawable) {
-            return false;
-        } else if (Build.VERSION.SDK_INT < 15 && drawable instanceof GradientDrawable) {
-            // GradientDrawable has a bug pre-ICS which results in mutate() resulting
-            // in loss of color
-            return false;
-        } else if (Build.VERSION.SDK_INT < 17 && drawable instanceof LayerDrawable) {
-            return false;
-        }
-
-        if (drawable instanceof DrawableContainer) {
-            // If we have a DrawableContainer, let's traverse its child array
-            final Drawable.ConstantState state = drawable.getConstantState();
-            if (state instanceof DrawableContainer.DrawableContainerState) {
-                final DrawableContainer.DrawableContainerState containerState =
-                        (DrawableContainer.DrawableContainerState) state;
-                for (final Drawable child : containerState.getChildren()) {
-                    if (!canSafelyMutateDrawable(child)) {
-                        return false;
-                    }
-                }
-            }
-        } else if (drawable instanceof WrappedDrawable) {
-            return canSafelyMutateDrawable(((WrappedDrawable) drawable).getWrappedDrawable());
-        } else if (drawable instanceof DrawableWrapperCompat) {
-            return canSafelyMutateDrawable(((DrawableWrapperCompat) drawable).getDrawable());
-        } else if (drawable instanceof ScaleDrawable) {
-            return canSafelyMutateDrawable(((ScaleDrawable) drawable).getDrawable());
-        }
-
         return true;
     }
 
@@ -179,8 +136,7 @@
         }
     }
 
-    // Only accessible on SDK_INT >= 18 and < 29.
-    @RequiresApi(18)
+    // Only accessible on SDK_INT < 29.
     static class Api18Impl {
         private static final boolean sReflectionSuccessful;
         private static final Method sGetOpticalInsets;
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java
index 916e4ac..d64a144e 100644
--- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java
+++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java
@@ -203,9 +203,7 @@
         final ColorStateList tintList = getTintList(context, resId);
         if (tintList != null) {
             // First mutate the Drawable, then wrap it and set the tint list
-            if (DrawableUtils.canSafelyMutateDrawable(drawable)) {
-                drawable = drawable.mutate();
-            }
+            drawable = drawable.mutate();
             drawable = DrawableCompat.wrap(drawable);
             DrawableCompat.setTintList(drawable, tintList);
 
@@ -438,13 +436,10 @@
     static void tintDrawable(Drawable drawable, TintInfo tint, int[] state) {
         int[] drawableState = drawable.getState();
 
-        boolean mutated = false;
-        if (DrawableUtils.canSafelyMutateDrawable(drawable)) {
-            mutated = drawable.mutate() == drawable;
-            if (!mutated) {
-                Log.d(TAG, "Mutated drawable is not the same instance as the input.");
-                return;
-            }
+        boolean mutated = drawable.mutate() == drawable;
+        if (!mutated) {
+            Log.d(TAG, "Mutated drawable is not the same instance as the input.");
+            return;
         }
 
         // Workaround for b/232275112 where LayerDrawable loses its state on mutate().
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatVectorDrawableIntegrationTest.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatVectorDrawableIntegrationTest.java
index 8ed530e..d05ef8a 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatVectorDrawableIntegrationTest.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatVectorDrawableIntegrationTest.java
@@ -89,17 +89,13 @@
         assertEquals("Left side should be white", Color.red(leftColor), 255);
         assertEquals("Right side should be black", Color.red(rightColor), 0);
 
-        if (Build.VERSION.SDK_INT >= 19) {
-            // setLayoutDirection is only available after API 17. However, it correctly set its
-            // drawable's layout direction until API 19.
-            view1.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
-            vectorDrawable.draw(mCanvas);
+        view1.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        vectorDrawable.draw(mCanvas);
 
-            leftColor = mBitmap.getPixel(LEFT_CENTER_X, CENTER_Y);
-            rightColor = mBitmap.getPixel(RIGHT_CENTER_X, CENTER_Y);
+        leftColor = mBitmap.getPixel(LEFT_CENTER_X, CENTER_Y);
+        rightColor = mBitmap.getPixel(RIGHT_CENTER_X, CENTER_Y);
 
-            assertEquals("Left side should be black", Color.red(leftColor), 0);
-            assertEquals("Right side should be white", Color.red(rightColor), 255);
-        }
+        assertEquals("Left side should be black", Color.red(leftColor), 0);
+        assertEquals("Right side should be white", Color.red(rightColor), 255);
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java
index 35ee8d3..a25e6a5 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java
@@ -68,10 +68,8 @@
         Configuration conf = context.getResources().getConfiguration();
         if (Build.VERSION.SDK_INT >= 24) {
             conf.setLocales(LocaleList.forLanguageTags(locales.toLanguageTags()));
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            conf.setLocale(locales.get(0));
         } else {
-            conf.locale = locales.get(0);
+            conf.setLocale(locales.get(0));
         }
         // updateConfiguration is required to make the configuration change stick.
         // updateConfiguration must be called before any use of the actual Resources.
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplicationConfigurationTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplicationConfigurationTestCase.kt
index bab064a..80561e1 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplicationConfigurationTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplicationConfigurationTestCase.kt
@@ -18,7 +18,6 @@
 
 import android.content.res.Configuration
 import android.content.res.Resources
-import android.os.Build
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.app.NightModeCustomAttachBaseContextActivity.CUSTOM_FONT_SCALE
 import androidx.appcompat.app.NightModeCustomAttachBaseContextActivity.CUSTOM_LOCALE
@@ -115,10 +114,6 @@
     companion object {
         @JvmStatic
         @Parameterized.Parameters
-        fun data() = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        fun data() = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationActivity.java
index 5c9e24e..9e0e311 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationActivity.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationActivity.java
@@ -59,11 +59,7 @@
         if (locale != null) {
             // Configuration.setLocale is added after 17 and Configuration.locale is deprecated
             // after 24
-            if (Build.VERSION.SDK_INT >= 17) {
-                config.setLocale(locale);
-            } else {
-                config.locale = locale;
-            }
+            config.setLocale(locale);
         }
         return config;
     }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationTestCase.kt
index fea48d4..e502df0 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomApplyOverrideConfigurationTestCase.kt
@@ -16,7 +16,6 @@
 
 package androidx.appcompat.app
 
-import android.os.Build
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.app.NightModeCustomApplyOverrideConfigurationActivity.CUSTOM_FONT_SCALE
 import androidx.appcompat.app.NightModeCustomApplyOverrideConfigurationActivity.CUSTOM_LOCALE
@@ -83,10 +82,6 @@
     companion object {
         @JvmStatic
         @Parameterized.Parameters
-        fun data() = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        fun data() = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomAttachBaseContextTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomAttachBaseContextTestCase.kt
index da4f6d1..62d0906 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomAttachBaseContextTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeCustomAttachBaseContextTestCase.kt
@@ -16,7 +16,6 @@
 
 package androidx.appcompat.app
 
-import android.os.Build
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.app.NightModeCustomAttachBaseContextActivity.CUSTOM_FONT_SCALE
 import androidx.appcompat.app.NightModeCustomAttachBaseContextActivity.CUSTOM_LOCALE
@@ -78,10 +77,6 @@
     companion object {
         @JvmStatic
         @Parameterized.Parameters
-        fun data() = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        fun data() = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModePreventOverrideConfigTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModePreventOverrideConfigTestCase.kt
index 29d06b1..075ff08 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModePreventOverrideConfigTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModePreventOverrideConfigTestCase.kt
@@ -17,7 +17,6 @@
 package androidx.appcompat.app
 
 import android.content.res.Configuration
-import android.os.Build
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.testutils.NightModeActivityTestRule
 import androidx.appcompat.testutils.NightModeUtils.NightSetMode
@@ -67,10 +66,6 @@
     companion object {
         @JvmStatic
         @Parameterized.Parameters
-        fun data() = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        fun data() = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
index 523d88d..c698bba 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
@@ -17,7 +17,6 @@
 package androidx.appcompat.app
 
 import android.content.res.Configuration
-import android.os.Build
 import androidx.appcompat.Orientation
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
@@ -109,10 +108,6 @@
     public companion object {
         @JvmStatic
         @Parameterized.Parameters
-        public fun data(): List<NightSetMode> = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        public fun data(): List<NightSetMode> = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt
index f5f1e53..962dfd5 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt
@@ -19,7 +19,6 @@
 import android.app.Activity
 import android.app.Instrumentation
 import android.content.res.Configuration
-import android.os.Build
 import androidx.appcompat.Orientation
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
@@ -132,10 +131,6 @@
     public companion object {
         @JvmStatic
         @Parameterized.Parameters
-        public fun data(): List<NightSetMode> = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        public fun data(): List<NightSetMode> = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt
index 1e3451f..51fc6d3a 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt
@@ -19,7 +19,6 @@
 import android.content.Context
 import android.content.res.Configuration
 import android.location.LocationManager
-import android.os.Build
 import android.webkit.WebView
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
@@ -282,10 +281,6 @@
 
         @Parameterized.Parameters
         @JvmStatic
-        fun data() = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        fun data() = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesTestCase.kt
index fe35b47..f0ebe47 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesTestCase.kt
@@ -17,7 +17,6 @@
 package androidx.appcompat.app
 
 import android.content.res.Configuration
-import android.os.Build
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.testutils.NightModeUtils.NightSetMode
@@ -161,10 +160,6 @@
     companion object {
         @JvmStatic
         @Parameterized.Parameters
-        fun data() = if (Build.VERSION.SDK_INT >= 17) {
-            listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
-        } else {
-            listOf(NightSetMode.DEFAULT)
-        }
+        fun data() = listOf(NightSetMode.DEFAULT, NightSetMode.LOCAL)
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/NightModeUtils.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/NightModeUtils.kt
index 1fb9286..a666cda 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/NightModeUtils.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/NightModeUtils.kt
@@ -20,7 +20,6 @@
 import android.content.Context
 import android.content.pm.ActivityInfo
 import android.content.res.Configuration
-import android.os.Build
 import android.util.Log
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.app.AppCompatDelegate
@@ -189,12 +188,7 @@
         setMode: NightSetMode
     ) = when (setMode) {
         NightSetMode.DEFAULT -> AppCompatDelegate.setDefaultNightMode(nightMode)
-        NightSetMode.LOCAL ->
-            if (Build.VERSION.SDK_INT >= 17) {
-                activity!!.delegate.localNightMode = nightMode
-            } else {
-                throw Exception("Local night mode is not supported on SDK_INT < 17")
-            }
+        NightSetMode.LOCAL -> activity!!.delegate.localNightMode = nightMode
     }
 
     @NightMode
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java
index 525e43a..8502458 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatBaseAutoSizeTest.java
@@ -431,10 +431,8 @@
             mActivityTestRule.runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    if (Build.VERSION.SDK_INT >= 17) {
-                        autoSizeView.setCompoundDrawablesRelative(
-                                drawable, drawable, drawable, drawable);
-                    }
+                    autoSizeView.setCompoundDrawablesRelative(
+                            drawable, drawable, drawable, drawable);
                 }
             });
             mInstrumentation.waitForIdleSync();
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java
index 9e83bac..2a3c537 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.os.Build;
 import android.text.StaticLayout;
 import android.text.method.SingleLineTransformationMethod;
 import android.util.AttributeSet;
@@ -85,10 +84,7 @@
         final AppCompatTextView textView = (AppCompatTextView) mActivity
                 .getLayoutInflater().inflate(R.layout.textview_autosize_maxlines, null);
         assertTrue(textView instanceof CustomTextViewWithTransformationMethod);
-        // Method added in API 16.
-        if (Build.VERSION.SDK_INT >= 16) {
-            assertEquals(1, textView.getMaxLines());
-        }
+        assertEquals(1, textView.getMaxLines());
         assertEquals(TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM, textView.getAutoSizeTextType());
         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
     }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index 4976f99..28d90ef 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -475,7 +475,7 @@
             // Workaround for incorrect default fontScale on earlier SDKs.
             overrideConfig.fontScale = 0f;
             Configuration referenceConfig =
-                    Api17Impl.createConfigurationContext(baseContext, overrideConfig)
+                    baseContext.createConfigurationContext(overrideConfig)
                             .getResources().getConfiguration();
             // Revert the uiMode change so that the diff doesn't include uiMode.
             Configuration baseConfig = baseContext.getResources().getConfiguration();
@@ -2687,11 +2687,9 @@
     void setConfigurationLocales(Configuration conf, @NonNull LocaleListCompat locales) {
         if (Build.VERSION.SDK_INT >= 24) {
             Api24Impl.setLocales(conf, locales);
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            Api17Impl.setLocale(conf, locales.get(0));
-            Api17Impl.setLayoutDirection(conf, locales.get(0));
         } else {
-            conf.locale = locales.get(0);
+            conf.setLocale(locales.get(0));
+            conf.setLayoutDirection(locales.get(0));
         }
     }
 
@@ -2795,9 +2793,7 @@
         }
         if (newLocales != null && !currentLocales.equals(newLocales)) {
             configChanges |= ActivityInfo.CONFIG_LOCALE;
-            if (Build.VERSION.SDK_INT >= 17) {
-                configChanges |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
-            }
+            configChanges |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
         }
 
         if (DEBUG) {
@@ -2836,9 +2832,8 @@
             // layout direction after recreating in Android S.
             if (Build.VERSION.SDK_INT >= 31
                     && (configChanges & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0) {
-                Api17Impl.setLayoutDirection(
-                        ((Activity) mHost).getWindow().getDecorView(),
-                        Api17Impl.getLayoutDirection(overrideConfig));
+                View view = ((Activity) mHost).getWindow().getDecorView();
+                view.setLayoutDirection(overrideConfig.getLayoutDirection());
             }
             ActivityCompat.recreate((Activity) mHost);
             handled = true;
@@ -3908,8 +3903,8 @@
             delta.smallestScreenWidthDp = change.smallestScreenWidthDp;
         }
 
-        if (Build.VERSION.SDK_INT >= 17) {
-            Api17Impl.generateConfigDelta_densityDpi(base, change, delta);
+        if (base.densityDpi != change.densityDpi) {
+            delta.densityDpi = change.densityDpi;
         }
 
         // Assets sequence and window configuration are not supported.
@@ -3917,44 +3912,6 @@
         return delta;
     }
 
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() { }
-
-        static void generateConfigDelta_densityDpi(@NonNull Configuration base,
-                @NonNull Configuration change, @NonNull Configuration delta) {
-            if (base.densityDpi != change.densityDpi) {
-                delta.densityDpi = change.densityDpi;
-            }
-        }
-
-        @DoNotInline
-        static Context createConfigurationContext(@NonNull Context context,
-                @NonNull Configuration overrideConfiguration) {
-            return context.createConfigurationContext(overrideConfiguration);
-        }
-
-        @DoNotInline
-        static void setLayoutDirection(Configuration configuration, Locale loc) {
-            configuration.setLayoutDirection(loc);
-        }
-
-        @DoNotInline
-        static void setLayoutDirection(View view, int layoutDirection) {
-            view.setLayoutDirection(layoutDirection);
-        }
-
-        @DoNotInline
-        static void setLocale(Configuration configuration, Locale loc) {
-            configuration.setLocale(loc);
-        }
-
-        @DoNotInline
-        static int getLayoutDirection(Configuration configuration) {
-            return configuration.getLayoutDirection();
-        }
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() { }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatViewInflater.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatViewInflater.java
index a8936f8..317cd76 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatViewInflater.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatViewInflater.java
@@ -419,7 +419,7 @@
 
     private void backportAccessibilityAttributes(@NonNull Context context, @NonNull View view,
             @NonNull AttributeSet attrs) {
-        if (Build.VERSION.SDK_INT < 19 || Build.VERSION.SDK_INT > 28) {
+        if (Build.VERSION.SDK_INT > 28) {
             return;
         }
 
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/view/ActionBarPolicy.java b/appcompat/appcompat/src/main/java/androidx/appcompat/view/ActionBarPolicy.java
index 9566fa3..9d0943c 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/view/ActionBarPolicy.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/view/ActionBarPolicy.java
@@ -23,7 +23,6 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Build;
-import android.view.ViewConfiguration;
 
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.R;
@@ -74,11 +73,7 @@
     }
 
     public boolean showsOverflowMenuButton() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return true;
-        } else {
-            return !ViewConfiguration.get(mContext).hasPermanentMenuKey();
-        }
+        return true;
     }
 
     public int getEmbeddedMenuWidthLimit() {
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemImpl.java
index 6d20471..dbdc39a 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemImpl.java
@@ -25,7 +25,6 @@
 import android.content.res.Resources;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.util.Log;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.KeyEvent;
@@ -471,17 +470,7 @@
 
     @Override
     public CharSequence getTitleCondensed() {
-        final CharSequence ctitle = mTitleCondensed != null ? mTitleCondensed : mTitle;
-
-        if (Build.VERSION.SDK_INT < 18 && ctitle != null && !(ctitle instanceof String)) {
-            // For devices pre-JB-MR2, where we have a non-String CharSequence, we need to
-            // convert this to a String so that EventLog.writeEvent() does not throw an exception
-            // in Activity.onMenuItemSelected()
-            return ctitle.toString();
-        } else {
-            // Else, we just return the condensed title
-            return ctitle;
-        }
+        return mTitleCondensed != null ? mTitleCondensed : mTitle;
     }
 
     @Override
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemWrapperICS.java b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemWrapperICS.java
index 7943434..d35af13 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemWrapperICS.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuItemWrapperICS.java
@@ -23,7 +23,6 @@
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.MenuItem;
@@ -31,7 +30,7 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
-import androidx.annotation.RequiresApi;
+import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.view.CollapsibleActionView;
 import androidx.core.internal.view.SupportMenuItem;
@@ -296,12 +295,8 @@
 
     @Override
     public MenuItem setActionProvider(android.view.ActionProvider provider) {
-        ActionProviderWrapper actionProviderWrapper;
-        if (Build.VERSION.SDK_INT >= 16) {
-            actionProviderWrapper = new ActionProviderWrapperJB(mContext, provider);
-        } else {
-            actionProviderWrapper = new ActionProviderWrapper(mContext, provider);
-        }
+        ActionProviderWrapper actionProviderWrapper = new ActionProviderWrapper(mContext,
+                provider);
         mWrappedObject.setSupportActionProvider(provider != null ? actionProviderWrapper : null);
         return this;
     }
@@ -425,8 +420,10 @@
         }
     }
 
-    private class ActionProviderWrapper extends androidx.core.view.ActionProvider {
-        final android.view.ActionProvider mInner;
+    private class ActionProviderWrapper extends androidx.core.view.ActionProvider
+            implements android.view.ActionProvider.VisibilityListener {
+        private ActionProvider.VisibilityListener mListener;
+        private final android.view.ActionProvider mInner;
 
         ActionProviderWrapper(Context context, android.view.ActionProvider inner) {
             super(context);
@@ -434,36 +431,6 @@
         }
 
         @Override
-        public View onCreateActionView() {
-            return mInner.onCreateActionView();
-        }
-
-        @Override
-        public boolean onPerformDefaultAction() {
-            return mInner.onPerformDefaultAction();
-        }
-
-        @Override
-        public boolean hasSubMenu() {
-            return mInner.hasSubMenu();
-        }
-
-        @Override
-        public void onPrepareSubMenu(android.view.SubMenu subMenu) {
-            mInner.onPrepareSubMenu(getSubMenuWrapper(subMenu));
-        }
-    }
-
-    @RequiresApi(16)
-    private class ActionProviderWrapperJB extends ActionProviderWrapper
-            implements android.view.ActionProvider.VisibilityListener {
-        private ActionProvider.VisibilityListener mListener;
-
-        ActionProviderWrapperJB(Context context, android.view.ActionProvider inner) {
-            super(context, inner);
-        }
-
-        @Override
         public View onCreateActionView(MenuItem forItem) {
             return mInner.onCreateActionView(forItem);
         }
@@ -495,8 +462,28 @@
                 mListener.onActionProviderVisibilityChanged(isVisible);
             }
         }
-    }
 
+        @Override
+        public boolean onPerformDefaultAction() {
+            return mInner.onPerformDefaultAction();
+        }
+
+        @Override
+        @NonNull
+        public View onCreateActionView() {
+            return mInner.onCreateActionView();
+        }
+
+        @Override
+        public boolean hasSubMenu() {
+            return mInner.hasSubMenu();
+        }
+
+        @Override
+        public void onPrepareSubMenu(android.view.SubMenu subMenu) {
+            mInner.onPrepareSubMenu(getSubMenuWrapper(subMenu));
+        }
+    }
 
     /**
      * Wrap a support {@link androidx.appcompat.view.CollapsibleActionView} into a framework
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuPopupHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuPopupHelper.java
index 69c498c..aa98768 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuPopupHelper.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/view/menu/MenuPopupHelper.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.Build;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.View;
@@ -32,10 +31,8 @@
 import android.widget.PopupWindow.OnDismissListener;
 
 import androidx.annotation.AttrRes;
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.StyleRes;
 import androidx.appcompat.R;
@@ -233,11 +230,7 @@
         final Display display = windowManager.getDefaultDisplay();
         final Point displaySize = new Point();
 
-        if (Build.VERSION.SDK_INT >= 17) {
-            Api17Impl.getRealSize(display, displaySize);
-        } else {
-            display.getSize(displaySize);
-        }
+        display.getRealSize(displaySize);
 
         final int smallestWidth = Math.min(displaySize.x, displaySize.y);
         final int minSmallestWidthCascading = mContext.getResources().getDimensionPixelSize(
@@ -351,16 +344,4 @@
     public ListView getListView() {
         return getPopup().getListView();
     }
-
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void getRealSize(Display display, Point outSize) {
-            display.getRealSize(outSize);
-        }
-    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActionBarOverlayLayout.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActionBarOverlayLayout.java
index bdfbbdb..8fc7067 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActionBarOverlayLayout.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActionBarOverlayLayout.java
@@ -78,7 +78,6 @@
 
     // Content overlay drawable - generally the action bar's shadow
     private Drawable mWindowContentOverlay;
-    private boolean mIgnoreWindowContentOverlay;
 
     private boolean mOverlayMode;
     private boolean mHasNonEmbeddedTabs;
@@ -168,9 +167,6 @@
         setWillNotDraw(mWindowContentOverlay == null);
         ta.recycle();
 
-        mIgnoreWindowContentOverlay = context.getApplicationInfo().targetSdkVersion <
-                Build.VERSION_CODES.KITKAT;
-
         mFlingEstimator = new OverScroller(context);
     }
 
@@ -196,14 +192,6 @@
 
     public void setOverlayMode(boolean overlayMode) {
         mOverlayMode = overlayMode;
-
-        /*
-         * Drawing the window content overlay was broken before K so starting to draw it
-         * again unexpectedly will cause artifacts in some apps. They should fix it.
-         */
-        mIgnoreWindowContentOverlay = overlayMode &&
-                getContext().getApplicationInfo().targetSdkVersion <
-                        Build.VERSION_CODES.KITKAT;
     }
 
     public boolean isInOverlayMode() {
@@ -249,9 +237,7 @@
     @Override
     @SuppressWarnings("deprecation") /* SYSTEM_UI_FLAG_LAYOUT_* */
     public void onWindowSystemUiVisibilityChanged(int visible) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            super.onWindowSystemUiVisibilityChanged(visible);
-        }
+        super.onWindowSystemUiVisibilityChanged(visible);
         pullChildren();
         final int diff = mLastSystemUiVisibility ^ visible;
         mLastSystemUiVisibility = visible;
@@ -540,7 +526,7 @@
     @Override
     public void draw(@NonNull Canvas c) {
         super.draw(c);
-        if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) {
+        if (mWindowContentOverlay != null) {
             final int top = mActionBarTop.getVisibility() == VISIBLE ?
                     (int) (mActionBarTop.getBottom() + mActionBarTop.getTranslationY() + 0.5f)
                     : 0;
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java
index 82d92e2..c7d4f79 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCheckBox.java
@@ -117,14 +117,6 @@
         setButtonDrawable(AppCompatResources.getDrawable(getContext(), resId));
     }
 
-    @Override
-    public int getCompoundPaddingLeft() {
-        final int value = super.getCompoundPaddingLeft();
-        return mCompoundButtonHelper != null
-                ? mCompoundButtonHelper.getCompoundPaddingLeft(value)
-                : value;
-    }
-
     /**
      * This should be accessed from {@link androidx.core.widget.CompoundButtonCompat}
      */
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCompoundButtonHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCompoundButtonHelper.java
index 3513f72..bf9b410 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCompoundButtonHelper.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatCompoundButtonHelper.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.util.AttributeSet;
 import android.widget.CompoundButton;
 
@@ -144,15 +143,4 @@
         }
     }
 
-    int getCompoundPaddingLeft(int superValue) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            // Before JB-MR1 the button drawable wasn't taken into account for padding. We'll
-            // workaround that here
-            Drawable buttonDrawable = CompoundButtonCompat.getButtonDrawable(mView);
-            if (buttonDrawable != null) {
-                superValue += buttonDrawable.getIntrinsicWidth();
-            }
-        }
-        return superValue;
-    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatDrawableManager.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatDrawableManager.java
index 6bd8f11..479200e 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatDrawableManager.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatDrawableManager.java
@@ -309,9 +309,7 @@
                 }
 
                 private void setPorterDuffColorFilter(Drawable d, int color, PorterDuff.Mode mode) {
-                    if (DrawableUtils.canSafelyMutateDrawable(d)) {
-                        d = d.mutate();
-                    }
+                    d = d.mutate();
                     d.setColorFilter(getPorterDuffColorFilter(color, mode == null ? DEFAULT_MODE
                             : mode));
                 }
@@ -423,9 +421,7 @@
                     }
 
                     if (colorAttrSet) {
-                        if (DrawableUtils.canSafelyMutateDrawable(drawable)) {
-                            drawable = drawable.mutate();
-                        }
+                        drawable = drawable.mutate();
 
                         final int color = getThemeAttrColor(context, colorAttr);
                         drawable.setColorFilter(getPorterDuffColorFilter(color, tintMode));
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java
index 693f95f..dee338b 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatRadioButton.java
@@ -115,14 +115,6 @@
         setButtonDrawable(AppCompatResources.getDrawable(getContext(), resId));
     }
 
-    @Override
-    public int getCompoundPaddingLeft() {
-        final int value = super.getCompoundPaddingLeft();
-        return mCompoundButtonHelper != null
-                ? mCompoundButtonHelper.getCompoundPaddingLeft(value)
-                : value;
-    }
-
     /**
      * This should be accessed from {@link androidx.core.widget.CompoundButtonCompat}
      */
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java
index 4eb3371..8408ef6 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextHelper.java
@@ -548,12 +548,10 @@
             applyCompoundDrawableTint(compoundDrawables[2], mDrawableRightTint);
             applyCompoundDrawableTint(compoundDrawables[3], mDrawableBottomTint);
         }
-        if (Build.VERSION.SDK_INT >= 17) {
-            if (mDrawableStartTint != null || mDrawableEndTint != null) {
-                final Drawable[] compoundDrawables = Api17Impl.getCompoundDrawablesRelative(mView);
-                applyCompoundDrawableTint(compoundDrawables[0], mDrawableStartTint);
-                applyCompoundDrawableTint(compoundDrawables[2], mDrawableEndTint);
-            }
+        if (mDrawableStartTint != null || mDrawableEndTint != null) {
+            final Drawable[] compoundDrawables = Api17Impl.getCompoundDrawablesRelative(mView);
+            applyCompoundDrawableTint(compoundDrawables[0], mDrawableStartTint);
+            applyCompoundDrawableTint(compoundDrawables[2], mDrawableEndTint);
         }
     }
 
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeHelper.java
index 446b6d8..684696a 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeHelper.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatTextViewAutoSizeHelper.java
@@ -34,7 +34,6 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
-import android.view.View;
 import android.widget.TextView;
 
 import androidx.annotation.DoNotInline;
@@ -47,7 +46,6 @@
 import androidx.core.view.ViewCompat;
 import androidx.core.widget.TextViewCompat;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -75,11 +73,6 @@
     @SuppressLint("BanConcurrentHashMap")
     private static java.util.concurrent.ConcurrentHashMap<String, Method>
             sTextViewMethodByNameCache = new java.util.concurrent.ConcurrentHashMap<>();
-    // Cache of TextView fields used via reflection; the key is the field name and the value is
-    // the field itself or null if it can not be found.
-    @SuppressLint("BanConcurrentHashMap")
-    private static java.util.concurrent.ConcurrentHashMap<String, Field> sTextViewFieldByNameCache =
-            new java.util.concurrent.ConcurrentHashMap<>();
     // Use this to specify that any of the auto-size configuration int values have not been set.
     static final float UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE = -1f;
     // Ported from TextView#VERY_WIDE. Represents a maximum width in pixels the TextView takes when
@@ -647,14 +640,12 @@
         setRawTextSize(TypedValue.applyDimension(unit, size, res.getDisplayMetrics()));
     }
 
+    @SuppressLint("BanUncheckedReflection")
     private void setRawTextSize(float size) {
         if (size != mTextView.getPaint().getTextSize()) {
             mTextView.getPaint().setTextSize(size);
 
-            boolean isInLayout = false;
-            if (Build.VERSION.SDK_INT >= 18) {
-                isInLayout = Api18Impl.isInLayout(mTextView);
-            }
+            boolean isInLayout = mTextView.isInLayout();
 
             if (mTextView.getLayout() != null) {
                 // Do not auto-size right after setting the text size.
@@ -731,11 +722,18 @@
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             return Api23Impl.createStaticLayoutForMeasuring(
                     text, alignment, availableWidth, maxLines, mTextView, mTempTextPaint, mImpl);
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            return Api16Impl.createStaticLayoutForMeasuring(
-                    text, alignment, availableWidth, mTextView, mTempTextPaint);
         } else {
-            return createStaticLayoutForMeasuringPre16(text, alignment, availableWidth);
+            final float lineSpacingMultiplier = mTextView.getLineSpacingMultiplier();
+            final float lineSpacingAdd = mTextView.getLineSpacingExtra();
+            final boolean includePad = mTextView.getIncludeFontPadding();
+
+            // The layout could not be constructed using the builder so fall back to the
+            // most broad constructor.
+            return new StaticLayout(text, mTempTextPaint, availableWidth,
+                    alignment,
+                    lineSpacingMultiplier,
+                    lineSpacingAdd,
+                    includePad);
         }
     }
 
@@ -749,7 +747,7 @@
             }
         }
 
-        final int maxLines = Build.VERSION.SDK_INT >= 16 ? Api16Impl.getMaxLines(mTextView) : -1;
+        final int maxLines = mTextView.getMaxLines();
         initTempTextPaint(suggestedSizeInPx);
 
         // Needs reflection call due to being private.
@@ -771,25 +769,7 @@
         return true;
     }
 
-
-    private StaticLayout createStaticLayoutForMeasuringPre16(CharSequence text,
-            Layout.Alignment alignment, int availableWidth) {
-        // The default values have been inlined with the StaticLayout defaults.
-
-        final float lineSpacingMultiplier = accessAndReturnWithDefault(mTextView,
-                "mSpacingMult", 1.0f);
-        final float lineSpacingAdd = accessAndReturnWithDefault(mTextView,
-                "mSpacingAdd", 0.0f);
-        final boolean includePad = accessAndReturnWithDefault(mTextView,
-                "mIncludePad", true);
-
-        return new StaticLayout(text, mTempTextPaint, availableWidth,
-                alignment,
-                lineSpacingMultiplier,
-                lineSpacingAdd,
-                includePad);
-    }
-
+    @SuppressLint("BanUncheckedReflection")
     @SuppressWarnings("unchecked")
     // This is marked package-protected so that it doesn't require a synthetic accessor
     // when being used from the Impl inner classes
@@ -814,22 +794,6 @@
         return result;
     }
 
-    @SuppressWarnings("unchecked")
-    private static <T> T accessAndReturnWithDefault(@NonNull Object object,
-            @NonNull final String fieldName, @NonNull final T defaultValue) {
-        try {
-            final Field field = getTextViewField(fieldName);
-            if (field == null) {
-                return defaultValue;
-            }
-
-            return (T) field.get(object);
-        }  catch (IllegalAccessException e) {
-            Log.w(TAG, "Failed to access TextView#" + fieldName + " member", e);
-            return defaultValue;
-        }
-    }
-
     @Nullable
     private static Method getTextViewMethod(@NonNull final String methodName) {
         try {
@@ -850,25 +814,6 @@
         }
     }
 
-    @Nullable
-    private static Field getTextViewField(@NonNull final String fieldName) {
-        try {
-            Field field = sTextViewFieldByNameCache.get(fieldName);
-            if (field == null) {
-                field = TextView.class.getDeclaredField(fieldName);
-                if (field != null) {
-                    field.setAccessible(true);
-                    sTextViewFieldByNameCache.put(fieldName, field);
-                }
-            }
-
-            return field;
-        } catch (NoSuchFieldException e) {
-            Log.w(TAG, "Failed to access TextView#" + fieldName + " member", e);
-            return null;
-        }
-    }
-
     /**
      * @return {@code true} if this widget supports auto-sizing text and has been configured to
      * auto-size.
@@ -928,50 +873,4 @@
             return layoutBuilder.build();
         }
     }
-
-    @RequiresApi(18)
-    private static final class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean isInLayout(@NonNull View view) {
-            return view.isInLayout();
-        }
-    }
-
-    @RequiresApi(16)
-    private static final class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getMaxLines(@NonNull TextView textView) {
-            return textView.getMaxLines();
-        }
-
-        @DoNotInline
-        @NonNull
-        static StaticLayout createStaticLayoutForMeasuring(
-                @NonNull CharSequence text,
-                @NonNull Layout.Alignment alignment,
-                int availableWidth,
-                @NonNull TextView textView,
-                @NonNull TextPaint tempTextPaint
-        ) {
-            final float lineSpacingMultiplier = textView.getLineSpacingMultiplier();
-            final float lineSpacingAdd = textView.getLineSpacingExtra();
-            final boolean includePad = textView.getIncludeFontPadding();
-
-            // The layout could not be constructed using the builder so fall back to the
-            // most broad constructor.
-            return new StaticLayout(text, tempTextPaint, availableWidth,
-                    alignment,
-                    lineSpacingMultiplier,
-                    lineSpacingAdd,
-                    includePad);
-        }
-    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java
index c764cb6..24ca26b 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SwitchCompat.java
@@ -48,11 +48,9 @@
 import android.widget.Switch;
 import android.widget.TextView;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.FloatRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.appcompat.R;
 import androidx.appcompat.content.res.AppCompatResources;
 import androidx.appcompat.text.AllCapsTransformationMethod;
@@ -1139,9 +1137,7 @@
         final float targetPosition = newCheckedState ? 1 : 0;
         mPositionAnimator = ObjectAnimator.ofFloat(this, THUMB_POS, targetPosition);
         mPositionAnimator.setDuration(THUMB_ANIMATION_DURATION);
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api18Impl.setAutoCancel(mPositionAnimator, true);
-        }
+        mPositionAnimator.setAutoCancel(true);
         mPositionAnimator.start();
     }
 
@@ -1692,16 +1688,4 @@
             }
         }
     }
-
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setAutoCancel(ObjectAnimator objectAnimator, boolean cancel) {
-            objectAnimator.setAutoCancel(cancel);
-        }
-    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/Toolbar.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/Toolbar.java
index b48c66c..9198f6a 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/Toolbar.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/Toolbar.java
@@ -559,9 +559,7 @@
 
     @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            super.onRtlPropertiesChanged(layoutDirection);
-        }
+        super.onRtlPropertiesChanged(layoutDirection);
 
         ensureContentInsets();
         mContentInsets.setDirection(layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL);
diff --git a/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/utils/BootCountUtilTest.java b/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/utils/BootCountUtilTest.java
deleted file mode 100644
index 421ce9b..0000000
--- a/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/utils/BootCountUtilTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2022 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.appsearch.utils;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SdkSuppress;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class BootCountUtilTest {
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = ApplicationProvider.getApplicationContext();
-    }
-
-    @Test
-    @SdkSuppress(maxSdkVersion = 16)
-    public void testGetCurrentBootCount_belowAPI17_returnsNeg1() {
-        assertThat(BootCountUtil.getCurrentBootCount(mContext)).isEqualTo(-1);
-    }
-}
diff --git a/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesActivity.java b/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesActivity.java
index ab3e69c..5d84149 100644
--- a/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesActivity.java
+++ b/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesActivity.java
@@ -121,14 +121,13 @@
 
     @Override
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.app_search_debug:
-                Intent intent = new Intent(this, AppSearchDebugActivity.class);
-                intent.putExtra(AppSearchDebugActivity.DB_INTENT_KEY, DB_NAME);
-                intent.putExtra(AppSearchDebugActivity.STORAGE_TYPE_INTENT_KEY,
-                        AppSearchDebugActivity.STORAGE_TYPE_LOCAL);
-                startActivity(intent);
-                return true;
+        if (item.getItemId() == R.id.app_search_debug) {
+            Intent intent = new Intent(this, AppSearchDebugActivity.class);
+            intent.putExtra(AppSearchDebugActivity.DB_INTENT_KEY, DB_NAME);
+            intent.putExtra(AppSearchDebugActivity.STORAGE_TYPE_INTENT_KEY,
+                    AppSearchDebugActivity.STORAGE_TYPE_LOCAL);
+            startActivity(intent);
+            return true;
         }
 
         return false;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchConfigImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchConfigImpl.java
index 13b63f5..d2cb2cf 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchConfigImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchConfigImpl.java
@@ -114,6 +114,16 @@
     }
 
     @Override
+    public boolean getUseNewQualifiedIdJoinIndex() {
+        return mIcingOptionsConfig.getUseNewQualifiedIdJoinIndex();
+    }
+
+    @Override
+    public boolean getBuildPropertyExistenceMetadataHits() {
+        return mIcingOptionsConfig.getBuildPropertyExistenceMetadataHits();
+    }
+
+    @Override
     public int getMaxDocumentSizeBytes() {
         return mLimitConfig.getMaxDocumentSizeBytes();
     }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
index ecb9768..4c9fbfe 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
@@ -312,6 +312,9 @@
                             mConfig.getIntegerIndexBucketSplitThreshold())
                     .setLiteIndexSortAtIndexing(mConfig.getLiteIndexSortAtIndexing())
                     .setLiteIndexSortSize(mConfig.getLiteIndexSortSize())
+                    .setUseNewQualifiedIdJoinIndex(mConfig.getUseNewQualifiedIdJoinIndex())
+                    .setBuildPropertyExistenceMetadataHits(
+                            mConfig.getBuildPropertyExistenceMetadataHits())
                     .build();
             LogUtil.piiTrace(TAG, "Constructing IcingSearchEngine, request", options);
             mIcingSearchEngineLocked = new IcingSearchEngine(options);
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java
index 4201c4e..11a0c04 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java
@@ -88,4 +88,14 @@
     public int getLiteIndexSortSize() {
         return DEFAULT_LITE_INDEX_SORT_SIZE;
     }
+
+    @Override
+    public boolean getUseNewQualifiedIdJoinIndex() {
+        return DEFAULT_USE_NEW_QUALIFIED_ID_JOIN_INDEX;
+    }
+
+    @Override
+    public boolean getBuildPropertyExistenceMetadataHits() {
+        return DEFAULT_BUILD_PROPERTY_EXISTENCE_METADATA_HITS;
+    }
 }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
index 418569a..870df5a 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
@@ -70,6 +70,10 @@
      */
     int DEFAULT_LITE_INDEX_SORT_SIZE = 8192;   // 8Kib
 
+    boolean DEFAULT_USE_NEW_QUALIFIED_ID_JOIN_INDEX = false;
+
+    boolean DEFAULT_BUILD_PROPERTY_EXISTENCE_METADATA_HITS = false;
+
     /**
      * The maximum allowable token length. All tokens in excess of this size will be truncated to
      * max_token_length before being indexed.
@@ -206,4 +210,19 @@
      * <p>Setting a lower sort size reduces querying latency at the expense of indexing latency.
      */
     int getLiteIndexSortSize();
+
+    /**
+     * Flag for {@link com.google.android.icing.proto.IcingSearchEngineOptions}.
+     *
+     * <p>Whether to use the new qualified Id join index.
+     */
+    boolean getUseNewQualifiedIdJoinIndex();
+
+    /**
+     * Flag for {@link com.google.android.icing.proto.IcingSearchEngineOptions}.
+     *
+     * <p>Whether to build the metadata hits used for property existence check, which is required
+     * to support the hasProperty function in advanced query.
+     */
+    boolean getBuildPropertyExistenceMetadataHits();
 }
diff --git a/appsearch/appsearch/api/current.txt b/appsearch/appsearch/api/current.txt
index 67c188e..37c352c 100644
--- a/appsearch/appsearch/api/current.txt
+++ b/appsearch/appsearch/api/current.txt
@@ -24,6 +24,8 @@
 
   @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public static @interface Document.DocumentProperty {
     method public abstract boolean indexNestedProperties() default false;
+    method public abstract String[] indexableNestedPropertiesList() default {};
+    method public abstract boolean inheritIndexableNestedPropertiesFromSuperclass() default false;
     method public abstract String name() default "";
     method public abstract boolean required() default false;
   }
diff --git a/appsearch/appsearch/api/restricted_current.txt b/appsearch/appsearch/api/restricted_current.txt
index 67c188e..37c352c 100644
--- a/appsearch/appsearch/api/restricted_current.txt
+++ b/appsearch/appsearch/api/restricted_current.txt
@@ -24,6 +24,8 @@
 
   @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public static @interface Document.DocumentProperty {
     method public abstract boolean indexNestedProperties() default false;
+    method public abstract String[] indexableNestedPropertiesList() default {};
+    method public abstract boolean inheritIndexableNestedPropertiesFromSuperclass() default false;
     method public abstract String name() default "";
     method public abstract boolean required() default false;
   }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
index 77db243..5d52268 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
@@ -16,6 +16,8 @@
 // @exportToFramework:skipFile()
 package androidx.appsearch.app;
 
+import static androidx.appsearch.app.AppSearchSchema.LongPropertyConfig.INDEXING_TYPE_RANGE;
+import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS;
 import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES;
 import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID;
 import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN;
@@ -875,6 +877,184 @@
         assertThat(documents).hasSize(1);
     }
 
+    @Document(name = "Artist", parent = {Root.class})
+    static class Artist extends Root {
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS) String mName;
+        @Document.LongProperty(indexingType = INDEXING_TYPE_RANGE) long mAge;
+        @Document.StringProperty(indexingType = INDEXING_TYPE_PREFIXES) String mMostFamousWork;
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS) String mNationality;
+    }
+
+
+    // Indexed properties for Media type: {"name", "description", "leadActor.name", "leadActor.age"}
+    @Document(name = "Media", parent = {Root.class})
+    static class Media extends Root {
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS) String mName;
+        @Document.StringProperty(indexingType = INDEXING_TYPE_PREFIXES) String mDescription;
+        @Document.DocumentProperty(indexableNestedPropertiesList = {"name", "age"})
+        Artist mLeadActor;
+    }
+
+    // Indexed properties for Movie type: {"name", "description", "leadActor.name",
+    // "leadActor.nationality"}
+    // Movie does not index "leadActor.age" as the java class does not extend from Media
+    @Document(name = "Movie", parent = {Media.class})
+    static class Movie extends Root {
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS) String mName;
+        @Document.StringProperty(indexingType = INDEXING_TYPE_PREFIXES) String mDescription;
+        @Document.DocumentProperty(
+                indexableNestedPropertiesList = {"name", "nationality"},
+                inheritIndexableNestedPropertiesFromSuperclass = true)
+        Artist mLeadActor;
+    }
+
+    // Indexed properties for Documentary type: {"name", "description", "leadActor.name",
+    // "leadActor.age", "leadActor.mostFamousWork"}
+    // Documentary extends Media, so it should index all nested properties in Media.leadActor, as
+    // well as "leadActor.mostFamousWork"
+    @Document(name = "Documentary", parent = {Media.class})
+    static class Documentary extends Media {
+        @Document.DocumentProperty(
+                indexableNestedPropertiesList = {"mostFamousWork"},
+                inheritIndexableNestedPropertiesFromSuperclass = true)
+        Artist mLeadActor;
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS) String mEvent;
+    }
+
+    // Indexed properties for DocumentaryMovie type: {"name", "description", "leadActor.name",
+    // "leadActor.age", "leadActor.mostFamousWork"}
+    // Documentary extends Media, so it should index all nested properties in Media.leadActor, but
+    // should not index "leadActor.nationality" as it does not extend from Movie.
+    @Document(name = "DocumentaryMovie", parent = {Documentary.class, Movie.class})
+    static class DocumentaryMovie extends Documentary {
+        @Document.DocumentProperty(
+                indexableNestedPropertiesList = {},
+                inheritIndexableNestedPropertiesFromSuperclass = true)
+        Artist mLeadActor;
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS) String mDate;
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesList() throws Exception {
+        assumeTrue(mSession.getFeatures().isFeatureSupported(
+                Features.SCHEMA_ADD_INDEXABLE_NESTED_PROPERTIES));
+
+        mSession.setSchemaAsync(new SetSchemaRequest.Builder()
+                // Artist, Media, Movie and Documentary are added automatically as they are
+                // DocumentaryMovie's dependencies.
+                .addDocumentClasses(DocumentaryMovie.class)
+                // Add an unrelated schema type
+                .addDocumentClasses(Gift.class)
+                .build()).get();
+
+
+        // Create documents
+        Artist actor = new Artist();
+        actor.mNamespace = "namespace";
+        actor.mId = "id1";
+        actor.mName = "actor";
+        actor.mAge = 30;
+        actor.mMostFamousWork = "famousWork";
+        actor.mNationality = "nationality";
+
+        Media media = new Media();
+        media.mNamespace = "namespace";
+        media.mId = "id2";
+        media.mName = "media";
+        media.mDescription = "mediaDescription";
+        media.mLeadActor = actor;
+
+        Movie movie = new Movie();
+        movie.mNamespace = "namespace";
+        movie.mId = "id3";
+        movie.mName = "movie";
+        movie.mDescription = "movieDescription";
+        movie.mLeadActor = actor;
+
+        Documentary documentary = new Documentary();
+        documentary.mNamespace = "namespace";
+        documentary.mId = "id4";
+        documentary.mName = "documentary";
+        documentary.mDescription = "documentaryDescription";
+        documentary.mLeadActor = actor;
+        documentary.mEvent = "documentaryEvent";
+
+        DocumentaryMovie documentaryMovie = new DocumentaryMovie();
+        documentaryMovie.mNamespace = "namespace";
+        documentaryMovie.mId = "id5";
+        documentaryMovie.mName = "documentaryMovie";
+        documentaryMovie.mDescription = "documentaryMovieDescription";
+        documentaryMovie.mLeadActor = actor;
+        documentaryMovie.mEvent = "documentaryMovieEvent";
+        documentaryMovie.mDate = "2023-10-12";
+
+        checkIsBatchResultSuccess(mSession.putAsync(
+                new PutDocumentsRequest.Builder()
+                        .addDocuments(actor, media, movie, documentary, documentaryMovie)
+                        .build()));
+
+        // Query for all documents
+        SearchResults searchResults = mSession.search("",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build());
+        List<GenericDocument> documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(5);
+
+
+        // Query for "actor" should retrieve all documents.
+        searchResults = mSession.search("actor",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(5);
+
+        // Query for "leadActor.age == 30" should retrieve Media, Documentary and DocumentaryMovie
+        searchResults = mSession.search("leadActor.age == 30",
+                new SearchSpec.Builder()
+                        .setNumericSearchEnabled(true)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(3);
+        assertThat(documents.get(0).getId()).isEqualTo("id5");  // documentaryMovie
+        assertThat(documents.get(1).getId()).isEqualTo("id4");  // documentary
+        assertThat(documents.get(2).getId()).isEqualTo("id2");  // media
+
+        // Query for "famous" should retrieve Actor, Documentary and DocumentaryMovie
+        searchResults = mSession.search("famous",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(3);
+        assertThat(documents.get(0).getId()).isEqualTo("id5");  // documentaryMovie
+        assertThat(documents.get(1).getId()).isEqualTo("id4");  // documentary
+        assertThat(documents.get(2).getId()).isEqualTo("id1");  // actor
+
+        // Query for "nationality" should retrieve Actor and Movie.
+        searchResults = mSession.search("nationality",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(2);
+        assertThat(documents.get(0).getId()).isEqualTo("id3");  // movie
+        assertThat(documents.get(1).getId()).isEqualTo("id1");  // actor
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesList_notSupported() {
+        assumeFalse(mSession.getFeatures().isFeatureSupported(
+                Features.SCHEMA_ADD_INDEXABLE_NESTED_PROPERTIES));
+
+        assertThrows(UnsupportedOperationException.class,
+                () -> mSession.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addDocumentClasses(DocumentaryMovie.class)
+                                .build()));
+    }
+
     // A class that some properties are annotated via getters without backing fields.
     @Document
     static class FakeMessage {
@@ -1640,6 +1820,344 @@
         assertThat(documents).containsExactly(businessGeneric);
     }
 
+    @Document(name = "Event", parent = InterfaceRoot.class)
+    interface Event extends InterfaceRoot {
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS)
+        String getName();
+
+        @Document.DocumentProperty(indexableNestedPropertiesList = {"name", "age"})
+        Artist getPerformer();
+
+        @Document.BuilderProducer
+        class Builder {
+            String mId;
+            String mNamespace;
+            long mCreationTimestamp;
+            String mName;
+            Artist mPerformer;
+
+            Builder(String id, String namespace) {
+                mId = id;
+                mNamespace = namespace;
+            }
+
+            public Event build() {
+                return new EventImpl(mId, mNamespace, mCreationTimestamp, mName, mPerformer);
+            }
+
+            public Event.Builder setCreationTimestamp(long creationTimestamp) {
+                mCreationTimestamp = creationTimestamp;
+                return this;
+            }
+
+            public Event.Builder setName(String name) {
+                mName = name;
+                return this;
+            }
+
+            public Event.Builder setPerformer(Artist performer) {
+                mPerformer = performer;
+                return this;
+            }
+        }
+    }
+
+    @Document(name = "Charity", parent = InterfaceRoot.class)
+    interface Charity extends InterfaceRoot {
+        @Document.StringProperty(indexingType = INDEXING_TYPE_EXACT_TERMS)
+        String getName();
+
+        @Document.DocumentProperty(indexableNestedPropertiesList = {"name", "nationality"})
+        Artist getPerformer();
+
+        @Document.BuilderProducer
+        class Builder {
+            String mId;
+            String mNamespace;
+            long mCreationTimestamp;
+            String mName;
+            Artist mPerformer;
+
+            Builder(String id, String namespace) {
+                mId = id;
+                mNamespace = namespace;
+            }
+
+            public Charity build() {
+                return new CharityImpl(mId, mNamespace, mCreationTimestamp, mName, mPerformer);
+            }
+
+            public Charity.Builder setCreationTimestamp(long creationTimestamp) {
+                mCreationTimestamp = creationTimestamp;
+                return this;
+            }
+
+            public Charity.Builder setName(String name) {
+                mName = name;
+                return this;
+            }
+
+            public Charity.Builder setPerformer(Artist performer) {
+                mPerformer = performer;
+                return this;
+            }
+        }
+    }
+
+    @Document(name = "CharityEvent", parent = {Event.class, Charity.class})
+    interface CharityEvent extends Event, Charity {
+        @Document.StringProperty(indexingType = INDEXING_TYPE_PREFIXES)
+        String getDescription();
+
+        @Document.DocumentProperty(inheritIndexableNestedPropertiesFromSuperclass = true)
+        Artist getPerformer();
+
+        @Document.BuilderProducer
+        class Builder {
+            String mId;
+            String mNamespace;
+            long mCreationTimestamp;
+            String mName;
+            String mDescription;
+            Artist mPerformer;
+
+            Builder(String id, String namespace) {
+                mId = id;
+                mNamespace = namespace;
+            }
+
+            public CharityEvent build() {
+                return new CharityEventImpl(mId, mNamespace, mCreationTimestamp, mName,
+                        mDescription, mPerformer);
+            }
+
+            public CharityEvent.Builder setCreationTimestamp(long creationTimestamp) {
+                mCreationTimestamp = creationTimestamp;
+                return this;
+            }
+
+            public CharityEvent.Builder setName(String name) {
+                mName = name;
+                return this;
+            }
+
+            public CharityEvent.Builder setDescription(String description) {
+                mDescription = description;
+                return this;
+            }
+
+            public CharityEvent.Builder setPerformer(Artist performer) {
+                mPerformer = performer;
+                return this;
+            }
+        }
+    }
+
+
+    static class EventImpl implements Event {
+        String mId;
+        String mNamespace;
+        long mCreationTimestamp;
+        String mName;
+        Artist mPerformer;
+
+        EventImpl(String id, String namespace, long creationTimestamp, String name,
+                Artist performer) {
+            mId = id;
+            mNamespace = namespace;
+            mCreationTimestamp = creationTimestamp;
+            mName = name;
+            mPerformer = performer;
+        }
+
+        @Override
+        public String getId() {
+            return mId;
+        }
+
+        @Override
+        public String getNamespace() {
+            return mNamespace;
+        }
+
+        @Override
+        public long getCreationTimestamp() {
+            return mCreationTimestamp;
+        }
+
+        @Override
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public Artist getPerformer() {
+            return mPerformer;
+        }
+    }
+
+    static class CharityImpl implements Charity {
+        String mId;
+        String mNamespace;
+        long mCreationTimestamp;
+        String mName;
+        Artist mPerformer;
+
+        CharityImpl(String id, String namespace, long creationTimestamp, String name,
+                Artist performer) {
+            mId = id;
+            mNamespace = namespace;
+            mCreationTimestamp = creationTimestamp;
+            mName = name;
+            mPerformer = performer;
+        }
+
+        @Override
+        public String getId() {
+            return mId;
+        }
+
+        @Override
+        public String getNamespace() {
+            return mNamespace;
+        }
+
+        @Override
+        public long getCreationTimestamp() {
+            return mCreationTimestamp;
+        }
+
+        @Override
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public Artist getPerformer() {
+            return mPerformer;
+        }
+    }
+
+    // CharityEventImpl.performer's nested properties: {performer.name, performer.age,
+    // performer.nationality}
+    static class CharityEventImpl implements CharityEvent {
+        String mId;
+        String mNamespace;
+        long mCreationTimestamp;
+        String mName;
+        String mDescription;
+        Artist mPerformer;
+
+        CharityEventImpl(String id, String namespace, long creationTimestamp, String name,
+                String description, Artist performer) {
+            mId = id;
+            mNamespace = namespace;
+            mCreationTimestamp = creationTimestamp;
+            mName = name;
+            mDescription = description;
+            mPerformer = performer;
+        }
+
+        public String getId() {
+            return mId;
+        }
+
+        public String getNamespace() {
+            return mNamespace;
+        }
+
+        public long getCreationTimestamp() {
+            return mCreationTimestamp;
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public Artist getPerformer() {
+            return mPerformer;
+        }
+
+        public String getDescription() {
+            return null;
+        }
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListForInterface() throws Exception {
+        assumeTrue(mSession.getFeatures().isFeatureSupported(
+                Features.SCHEMA_ADD_INDEXABLE_NESTED_PROPERTIES));
+
+        mSession.setSchemaAsync(new SetSchemaRequest.Builder()
+                .addDocumentClasses(CharityEventImpl.class)
+                // Add an unrelated schema type
+                .addDocumentClasses(Gift.class)
+                .build()).get();
+
+
+        // Create documents
+        Artist performer = new Artist();
+        performer.mNamespace = "namespace";
+        performer.mId = "id1";
+        performer.mName = "performer";
+        performer.mAge = 30;
+        performer.mMostFamousWork = "famousWork";
+        performer.mNationality = "nationality";
+
+        CharityEventImpl charityEvent = new CharityEventImpl("id2", "namespace", 0, "charityEvent",
+                "charityEventDescription", performer);
+
+        checkIsBatchResultSuccess(mSession.putAsync(
+                new PutDocumentsRequest.Builder()
+                        .addDocuments(performer, charityEvent)
+                        .build()));
+
+        // Query for all documents
+        SearchResults searchResults = mSession.search("",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build());
+        List<GenericDocument> documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(2);
+
+
+        // Query for "performer" should retrieve all documents.
+        searchResults = mSession.search("performer",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(2);
+
+        // Query for "performer.age == 30" should retrieve CharityEvent
+        searchResults = mSession.search("performer.age == 30",
+                new SearchSpec.Builder()
+                        .setNumericSearchEnabled(true)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(1);
+        assertThat(documents.get(0).getId()).isEqualTo("id2");  // charityEvent
+
+        // Query for "famous" should retrieve Performer
+        searchResults = mSession.search("famous",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(1);
+        assertThat(documents.get(0).getId()).isEqualTo("id1");  // performer
+
+        // Query for "nationality" should retrieve Performer and CharityEvent.
+        searchResults = mSession.search("nationality",
+                new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).hasSize(2);
+        assertThat(documents.get(0).getId()).isEqualTo("id2");  // charityEvent
+        assertThat(documents.get(1).getId()).isEqualTo("id1");  // performer
+    }
+
     @Test
     public void testAppSearchDocumentClassMap() throws Exception {
         // Before this test, AppSearch's annotation processor has already generated the maps for
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
index 8e802e6..59415fb 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
@@ -332,14 +332,64 @@
         String name() default "";
 
         /**
-         * Configures whether fields in the nested document should be indexed.
+         * Configures whether all fields in the nested document should be indexed.
          *
          * <p>If false, the nested document's properties are not indexed regardless of its own
-         * schema.
+         * schema, unless {@link #indexableNestedPropertiesList()} is used to index a subset of
+         * properties from the nested document.
+         *
+         * <p>{@link IllegalArgumentException} will be thrown during setSchema if set to true and
+         * defining a non-empty list for {@link #indexableNestedPropertiesList()}
          */
         boolean indexNestedProperties() default false;
 
         /**
+         * The list of properties in the nested document to index. The property will be indexed
+         * according to its indexing configurations in the document's schema definition.
+         *
+         * <p>{@link #indexNestedProperties} is required to be false if this list is non-empty.
+         * {@link IllegalArgumentException} will be thrown during setSchema if this condition is
+         * not met.
+         *
+         * @see
+         * AppSearchSchema.DocumentPropertyConfig.Builder#addIndexableNestedProperties(Collection)
+         */
+        String[] indexableNestedPropertiesList() default {};
+
+        /**
+         * Configures whether to inherit the indexable nested properties list from the Document's
+         * superclass type definition. When set to true, the indexable property paths will be
+         * a union of the paths specified in {@link #indexableNestedPropertiesList()} and any
+         * path specified in the document class's superclass or inherited interfaces.
+         * Effectively, this is a no-op if none of the document superclasses specify a path for
+         * this document property.
+         *
+         * <p>Ex. Consider the following Document classes:
+         * <pre>
+         * {@code
+         * @Document
+         * class Person {
+         *   @Document.DocumentProperty(indexableNestedPropertiesList = {"streetName", "zipcode"})
+         *   Address livesAt;
+         * }
+         * @Document
+         * class Artist extends Person {
+         *   @Document.DocumentProperty(
+         *     indexableNestedPropertiesList = {"country"},
+         *     inheritIndexableNestedPropertiesFromSuperclass = true
+         *   )
+         *   Address livesAt;
+         * }
+         * }
+         * </pre>
+         *
+         * <p>By setting 'inheritIndexableNestedPropertiesFromSuperclass = true', Artist.livesAt
+         * inherits the indexable nested properties defined by its parent class's livesAt field
+         * (Person.livesAt) and indexes all three fields: {streetName, zipCode, country}
+         */
+        boolean inheritIndexableNestedPropertiesFromSuperclass() default false;
+
+        /**
          * Configures whether this property must be specified for the document to be valid.
          *
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentClassCreationInfo.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentClassCreationInfo.java
index a2a4fd6..f882f0f 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentClassCreationInfo.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentClassCreationInfo.java
@@ -420,9 +420,7 @@
         }
 
         private static boolean isAnnotatedWithBuilderProducer(@NonNull Element element) {
-            return element.getAnnotationMirrors().stream()
-                    .anyMatch(annotation -> annotation.getAnnotationType().toString()
-                            .equals(BUILDER_PRODUCER_CLASS.canonicalName()));
+            return !IntrospectionHelper.getAnnotations(element, BUILDER_PRODUCER_CLASS).isEmpty();
         }
 
         /**
@@ -452,8 +450,8 @@
         }
 
         /**
-         * Makes sure the type is a {@link DeclaredType} with a non-private & non-static method
-         * of the form {@code DocumentClass build()}.
+         * Makes sure the builder type is a {@link DeclaredType} with a non-private & non-static
+         * method of the form {@code DocumentClass build()}.
          *
          * @param annotatedElement The method/class annotated with
          *                         {@code @Document.BuilderProducer}.
@@ -471,12 +469,12 @@
             if (builderType.getKind() != TypeKind.DECLARED) {
                 throw exception;
             }
-            TypeElement builderClass = (TypeElement) ((DeclaredType) builderType).asElement();
-            boolean hasBuildMethod = helper.getAllMethods(builderClass).stream()
-                    .anyMatch(method -> !method.getModifiers().contains(Modifier.STATIC)
-                            && !method.getModifiers().contains(Modifier.PRIVATE)
-                            && helper.isReturnTypeMatching(method, documentClass.asType())
-                            && method.getParameters().isEmpty());
+            boolean hasBuildMethod = helper.getAllMethods((DeclaredType) builderType)
+                    .anyMatch(method -> method.getElement().getSimpleName().contentEquals("build")
+                            && !method.getElement().getModifiers().contains(Modifier.STATIC)
+                            && !method.getElement().getModifiers().contains(Modifier.PRIVATE)
+                            && helper.isReturnTypeMatching(method.getType(), documentClass.asType())
+                            && method.getType().getParameterTypes().isEmpty());
             if (!hasBuildMethod) {
                 throw exception;
             }
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
index a6c6a24..216d075 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
@@ -48,6 +48,9 @@
 /**
  * Processes @Document annotations.
  *
+ * @see AnnotatedGetterAndFieldAccumulator for the DocumentModel's invariants with regards to its
+ * getter and field definitions.
+ *
  * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java
index a458359..8ad865d 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java
@@ -22,6 +22,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.compiler.annotationwrapper.DataPropertyAnnotation;
+import androidx.appsearch.compiler.annotationwrapper.DocumentPropertyAnnotation;
+import androidx.appsearch.compiler.annotationwrapper.PropertyAnnotation;
 
 import com.google.auto.value.AutoValue;
 import com.squareup.javapoet.ClassName;
@@ -38,6 +41,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.WeakHashMap;
+import java.util.stream.Stream;
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.AnnotationMirror;
@@ -118,6 +122,7 @@
     final TypeMirror mBytePrimitiveType;
     private final ProcessingEnvironment mEnv;
     private final Types mTypeUtils;
+    private final Elements mElementUtils;
 
     private final WeakHashMap<TypeElement, LinkedHashSet<ExecutableElement>> mAllMethodsCache =
             new WeakHashMap<>();
@@ -125,27 +130,27 @@
     IntrospectionHelper(ProcessingEnvironment env) {
         mEnv = env;
 
-        Elements elementUtil = env.getElementUtils();
+        mElementUtils = env.getElementUtils();
         mTypeUtils = env.getTypeUtils();
-        mCollectionType = elementUtil.getTypeElement(Collection.class.getName()).asType();
-        mListType = elementUtil.getTypeElement(List.class.getName()).asType();
-        mStringType = elementUtil.getTypeElement(String.class.getName()).asType();
-        mIntegerBoxType = elementUtil.getTypeElement(Integer.class.getName()).asType();
+        mCollectionType = mElementUtils.getTypeElement(Collection.class.getName()).asType();
+        mListType = mElementUtils.getTypeElement(List.class.getName()).asType();
+        mStringType = mElementUtils.getTypeElement(String.class.getName()).asType();
+        mIntegerBoxType = mElementUtils.getTypeElement(Integer.class.getName()).asType();
         mIntPrimitiveType = mTypeUtils.unboxedType(mIntegerBoxType);
-        mLongBoxType = elementUtil.getTypeElement(Long.class.getName()).asType();
+        mLongBoxType = mElementUtils.getTypeElement(Long.class.getName()).asType();
         mLongPrimitiveType = mTypeUtils.unboxedType(mLongBoxType);
-        mFloatBoxType = elementUtil.getTypeElement(Float.class.getName()).asType();
+        mFloatBoxType = mElementUtils.getTypeElement(Float.class.getName()).asType();
         mFloatPrimitiveType = mTypeUtils.unboxedType(mFloatBoxType);
-        mDoubleBoxType = elementUtil.getTypeElement(Double.class.getName()).asType();
+        mDoubleBoxType = mElementUtils.getTypeElement(Double.class.getName()).asType();
         mDoublePrimitiveType = mTypeUtils.unboxedType(mDoubleBoxType);
-        mBooleanBoxType = elementUtil.getTypeElement(Boolean.class.getName()).asType();
+        mBooleanBoxType = mElementUtils.getTypeElement(Boolean.class.getName()).asType();
         mBooleanPrimitiveType = mTypeUtils.unboxedType(mBooleanBoxType);
-        mByteBoxType = elementUtil.getTypeElement(Byte.class.getName()).asType();
+        mByteBoxType = mElementUtils.getTypeElement(Byte.class.getName()).asType();
         mByteBoxArrayType = mTypeUtils.getArrayType(mByteBoxType);
         mBytePrimitiveType = mTypeUtils.unboxedType(mByteBoxType);
         mBytePrimitiveArrayType = mTypeUtils.getArrayType(mBytePrimitiveType);
         mGenericDocumentType =
-                elementUtil.getTypeElement(GENERIC_DOCUMENT_CLASS.canonicalName()).asType();
+                mElementUtils.getTypeElement(GENERIC_DOCUMENT_CLASS.canonicalName()).asType();
     }
 
     /**
@@ -155,11 +160,58 @@
     @Nullable
     public static AnnotationMirror getDocumentAnnotation(@NonNull Element element) {
         Objects.requireNonNull(element);
-        for (AnnotationMirror annotation : element.getAnnotationMirrors()) {
-            String annotationFq = annotation.getAnnotationType().toString();
-            if (IntrospectionHelper.DOCUMENT_ANNOTATION_CLASS.canonicalName().equals(
-                    annotationFq)) {
-                return annotation;
+        List<? extends AnnotationMirror> annotations = getAnnotations(element,
+                DOCUMENT_ANNOTATION_CLASS);
+        if (annotations.isEmpty()) {
+            return null;
+        } else {
+            return annotations.get(0);
+        }
+    }
+
+    /**
+     * Returns a list of annotations of a given kind from the input element's annotations,
+     * specified by the annotation's class name. Returns null if no annotation of such kind is
+     * found.
+     */
+    @NonNull
+    public static List<? extends AnnotationMirror> getAnnotations(@NonNull Element element,
+            @NonNull ClassName className) {
+        Objects.requireNonNull(element);
+        Objects.requireNonNull(className);
+        return element.getAnnotationMirrors()
+                .stream()
+                .filter(annotation -> annotation.getAnnotationType().toString()
+                        .equals(className.canonicalName()))
+                .toList();
+    }
+
+    /**
+     * Returns the document property annotation that matches the given property name from a given
+     * class or interface element.
+     *
+     * <p>Returns null if the property cannot be found in the class or interface, or if the
+     * property matching the property name is not a document property.
+     */
+    @Nullable
+    public DocumentPropertyAnnotation getDocumentPropertyAnnotation(
+            @NonNull TypeElement clazz, @NonNull String propertyName) throws ProcessingException {
+        Objects.requireNonNull(clazz);
+        Objects.requireNonNull(propertyName);
+        for (Element enclosedElement : clazz.getEnclosedElements()) {
+            AnnotatedGetterOrField getterOrField =
+                    AnnotatedGetterOrField.tryCreateFor(enclosedElement, mEnv);
+            if (getterOrField == null || !(getterOrField.getAnnotation().getPropertyKind()
+                    == PropertyAnnotation.Kind.DATA_PROPERTY)) {
+                continue;
+            }
+            if (((DataPropertyAnnotation) getterOrField.getAnnotation()).getDataPropertyKind()
+                    == DataPropertyAnnotation.Kind.DOCUMENT_PROPERTY) {
+                DocumentPropertyAnnotation documentPropertyAnnotation =
+                        (DocumentPropertyAnnotation) getterOrField.getAnnotation();
+                if (documentPropertyAnnotation.getName().equals(propertyName)) {
+                    return documentPropertyAnnotation;
+                }
             }
         }
         return null;
@@ -352,13 +404,62 @@
     }
 
     /**
-     * Whether the method returns the specified type.
+     * A method's type and element (i.e. declaration).
+     *
+     * <p>Note: The parameter and return types may differ between the type and the element.
+     * For example,
+     *
+     * <pre>
+     * {@code
+     * public class StringSet implements Set<String> {...}
+     * }
+     * </pre>
+     *
+     * <p>Here, the type of {@code StringSet.add()} is {@code (String) -> boolean} and the element
+     * points to the generic declaration within {@code Set<T>} with a return type of
+     * {@code boolean} and a single parameter of type {@code T}.
+     */
+    public static class MethodTypeAndElement {
+        private final ExecutableType mType;
+        private final ExecutableElement mElement;
+
+        public MethodTypeAndElement(
+                @NonNull ExecutableType type, @NonNull ExecutableElement element) {
+            mType = type;
+            mElement = element;
+        }
+
+        @NonNull
+        public ExecutableType getType() {
+            return mType;
+        }
+
+        @NonNull
+        public ExecutableElement getElement() {
+            return mElement;
+        }
+    }
+
+    /**
+     * Returns a stream of all the methods (including inherited) within a {@link DeclaredType}.
+     *
+     * <p>Does not include constructors.
+     */
+    @NonNull
+    public Stream<MethodTypeAndElement> getAllMethods(@NonNull DeclaredType type) {
+        return mElementUtils.getAllMembers((TypeElement) type.asElement()).stream()
+                .filter(el -> el.getKind() == ElementKind.METHOD)
+                .map(el -> new MethodTypeAndElement(
+                        (ExecutableType) mTypeUtils.asMemberOf(type, el),
+                        (ExecutableElement) el));
+    }
+
+    /**
+     * Whether the method returns the specified type (or subtype).
      */
     public boolean isReturnTypeMatching(
-            @NonNull ExecutableElement method, @NonNull TypeMirror type) {
-        TypeMirror target = method.getKind() == ElementKind.CONSTRUCTOR
-                ? method.getEnclosingElement().asType() : method.getReturnType();
-        return mTypeUtils.isSameType(type, target);
+            @NonNull ExecutableType method, @NonNull TypeMirror type) {
+        return mTypeUtils.isAssignable(method.getReturnType(), type);
     }
 
     /**
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java
index 288a61b..9199c47 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java
@@ -21,6 +21,10 @@
 import static androidx.appsearch.compiler.IntrospectionHelper.PROPERTY_CONFIG_CLASS;
 import static androidx.appsearch.compiler.IntrospectionHelper.getDocumentClassFactoryForClass;
 
+import static com.google.auto.common.MoreTypes.asTypeElement;
+
+import static javax.lang.model.type.TypeKind.DECLARED;
+
 import androidx.annotation.NonNull;
 import androidx.appsearch.compiler.annotationwrapper.DataPropertyAnnotation;
 import androidx.appsearch.compiler.annotationwrapper.DocumentPropertyAnnotation;
@@ -36,8 +40,14 @@
 import com.squareup.javapoet.TypeSpec;
 import com.squareup.javapoet.WildcardTypeName;
 
+import java.util.ArrayDeque;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.Modifier;
@@ -47,6 +57,7 @@
 /** Generates java code for an {@link androidx.appsearch.app.AppSearchSchema}. */
 class SchemaCodeGenerator {
     private final DocumentModel mModel;
+    private final IntrospectionHelper mHelper;
     private final LinkedHashSet<TypeElement> mDependencyDocumentClasses;
 
     public static void generate(
@@ -58,6 +69,7 @@
 
     private SchemaCodeGenerator(@NonNull DocumentModel model, @NonNull ProcessingEnvironment env) {
         mModel = model;
+        mHelper = new IntrospectionHelper(env);
         mDependencyDocumentClasses = computeDependencyClasses(model, env);
     }
 
@@ -206,6 +218,12 @@
                 DocumentPropertyAnnotation documentPropertyAnnotation =
                         (DocumentPropertyAnnotation) annotation;
                 codeBlock.add(createSetShouldIndexNestedPropertiesExpr(documentPropertyAnnotation));
+                Set<String> indexableNestedProperties = getAllIndexableNestedProperties(
+                        documentPropertyAnnotation);
+                for (String propertyPath : indexableNestedProperties) {
+                    codeBlock.add(
+                            CodeBlock.of("\n.addIndexableNestedProperties($L)", propertyPath));
+                }
                 break;
             case LONG_PROPERTY:
                 LongPropertyAnnotation longPropertyAnnotation = (LongPropertyAnnotation) annotation;
@@ -223,6 +241,59 @@
                 .build();
     }
 
+
+    /**
+     * Finds all indexable nested properties for the given type class and document property
+     * annotation. This includes indexable nested properties that should be inherited from the
+     * type's parent.
+     */
+    private Set<String> getAllIndexableNestedProperties(
+            @NonNull DocumentPropertyAnnotation documentPropertyAnnotation)
+            throws ProcessingException {
+        Set<String> indexableNestedProperties = new HashSet<>(
+                documentPropertyAnnotation.getIndexableNestedPropertiesList());
+
+        if (documentPropertyAnnotation.shouldInheritIndexableNestedPropertiesFromSuperClass()) {
+            // List of classes to expand into parent classes to search for the property annotation
+            Queue<TypeElement> classesToExpand = new ArrayDeque<>();
+            Set<TypeElement> visited = new HashSet<>();
+            classesToExpand.add(mModel.getClassElement());
+            while (!classesToExpand.isEmpty()) {
+                TypeElement currentClass = classesToExpand.poll();
+                if (visited.contains(currentClass)) {
+                    continue;
+                }
+                visited.add(currentClass);
+                // Look for the document property annotation in the class's parent classes
+                List<TypeMirror> parentTypes = new ArrayList<>();
+                parentTypes.add(currentClass.getSuperclass());
+                parentTypes.addAll(currentClass.getInterfaces());
+                for (TypeMirror parent : parentTypes) {
+                    if (!parent.getKind().equals(DECLARED)) {
+                        continue;
+                    }
+                    TypeElement parentElement = asTypeElement(parent);
+                    DocumentPropertyAnnotation annotation = mHelper.getDocumentPropertyAnnotation(
+                            parentElement, documentPropertyAnnotation.getName());
+                    if (annotation == null) {
+                        // The property is not found in this level. Continue searching in one level
+                        // above as the property could still be defined for this level by class
+                        // inheritance.
+                        classesToExpand.add(parentElement);
+                    } else {
+                        indexableNestedProperties.addAll(
+                                annotation.getIndexableNestedPropertiesList());
+                        if (annotation.shouldInheritIndexableNestedPropertiesFromSuperClass()) {
+                            // Continue searching in the parent class's parents
+                            classesToExpand.add(parentElement);
+                        }
+                    }
+                }
+            }
+        }
+        return indexableNestedProperties;
+    }
+
     /**
      * Creates an expr like {@code .setCardinality(PropertyConfig.CARDINALITY_REPEATED)}.
      */
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/annotationwrapper/DocumentPropertyAnnotation.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/annotationwrapper/DocumentPropertyAnnotation.java
index 4bf1789..3807b17 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/annotationwrapper/DocumentPropertyAnnotation.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/annotationwrapper/DocumentPropertyAnnotation.java
@@ -23,8 +23,11 @@
 import androidx.appsearch.compiler.IntrospectionHelper;
 
 import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
 import com.squareup.javapoet.ClassName;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import javax.lang.model.type.TypeMirror;
@@ -57,10 +60,19 @@
     static DocumentPropertyAnnotation parse(
             @NonNull Map<String, Object> annotationParams, @NonNull String defaultName) {
         String name = (String) annotationParams.get("name");
+        List<String> indexableNestedPropertiesList = new ArrayList<>();
+        Object indexableList = annotationParams.get("indexableNestedPropertiesList");
+        if (indexableList instanceof List) {
+            for (Object property : (List<?>) indexableList) {
+                indexableNestedPropertiesList.add(property.toString());
+            }
+        }
         return new AutoValue_DocumentPropertyAnnotation(
                 name.isEmpty() ? defaultName : name,
                 (boolean) annotationParams.get("required"),
-                (boolean) annotationParams.get("indexNestedProperties"));
+                (boolean) annotationParams.get("indexNestedProperties"),
+                ImmutableList.copyOf(indexableNestedPropertiesList),
+                (boolean) annotationParams.get("inheritIndexableNestedPropertiesFromSuperclass"));
     }
 
     /**
@@ -68,6 +80,19 @@
      */
     public abstract boolean shouldIndexNestedProperties();
 
+    /**
+     * Returns the list of nested properties to index for the nested document other than the
+     * properties inherited from the type's parent.
+     */
+    @NonNull
+    public abstract ImmutableList<String> getIndexableNestedPropertiesList();
+
+    /**
+     * Specifies whether to inherit the parent class's definition for the indexable nested
+     * properties list.
+     */
+    public abstract boolean shouldInheritIndexableNestedPropertiesFromSuperClass();
+
     @NonNull
     @Override
     public final Kind getDataPropertyKind() {
diff --git a/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java b/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
index 18148d7..2c9e09d 100644
--- a/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
+++ b/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
@@ -1828,6 +1828,341 @@
     }
 
     @Test
+    public void testIndexableNestedPropertiesListSimple() throws Exception {
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"}) Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("Person.java", "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultContains("Person.java", "addIndexableNestedProperties(\"streetName\")");
+
+        checkEqualsGolden("Person.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListEmpty() throws Exception {
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList = {})"
+                        + "  Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+        checkResultDoesNotContain("Person.java", "addIndexableNestedProperties");
+        checkEqualsGolden("Person.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListInheritSuperclassTrue() throws Exception {
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"}) Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Artist\", parent = {Person.class})\n"
+                        + "class Artist extends Person {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "  @Document.DocumentProperty("
+                        + "    indexableNestedPropertiesList = {\"state\"},"
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("Artist.java", "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultContains("Artist.java", "addIndexableNestedProperties(\"streetName\")");
+        checkResultContains("Artist.java", "addIndexableNestedProperties(\"state\")");
+
+        checkEqualsGolden("Artist.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListInheritSuperclassFalse() throws Exception {
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"}) Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Artist\", parent = {Person.class})\n"
+                        + "class Artist extends Person {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "  @Document.DocumentProperty("
+                        + "    indexableNestedPropertiesList = {\"state\"},"
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = false)"
+                        + "  Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("Artist.java", "addIndexableNestedProperties(\"state\")");
+        checkResultDoesNotContain("Artist.java", "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultDoesNotContain("Artist.java", "addIndexableNestedProperties(\"streetName\")");
+
+        checkEqualsGolden("Artist.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListInheritWithMultipleParentsClasses()
+            throws Exception {
+        // Tests that the child class inherits nested properties from the parent correctly. When
+        // set to true, the field overridden by the child class should only inherit indexable
+        // nested properties form its java parent class (i.e. the superclass/interface which the
+        // child class extends from/implements).
+        // In this test case, Artist's parent class is Person, and ArtistEmployee's parent class
+        // is Artist. This means that ArtistEmployee.livesAt's indexable list should contain the
+        // properties s specified in Artist.livesAt. and Person.livesAt (since both Artist and
+        // ArtistEmployee sets inheritFromParent=true for this field). ArtistEmployee.livesAt
+        // should not inherit the indexable list from Employee.livesAt since Employee is not
+        // ArtistEmployee's java class parent.
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"}) Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Artist\", parent = {Person.class})\n"
+                        + "class Artist extends Person {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "  @Document.DocumentProperty("
+                        + "    indexableNestedPropertiesList = {\"state\"},"
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Employee\", parent = {Person.class})\n"
+                        + "class Employee extends Person {\n"
+                        + "  @Document.DocumentProperty("
+                        + "    indexableNestedPropertiesList = {\"zipCode\"},"
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"zipCode\", \"streetName\"}) Address worksAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"ArtistEmployee\", parent = {Artist.class,"
+                        + "Employee.class})\n"
+                        + "class ArtistEmployee extends Artist {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "  @Document.DocumentProperty("
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("ArtistEmployee.java",
+                "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultContains("ArtistEmployee.java", "addIndexableNestedProperties(\"streetName\")");
+        checkResultContains("ArtistEmployee.java", "addIndexableNestedProperties(\"state\")");
+        // ArtistEmployee's indexable list should not contain 'zipCode' as  ArtistEmployee only
+        // extends Artist, which does not index zipCode
+        checkResultDoesNotContain("ArtistEmployee.java",
+                "addIndexableNestedProperties(\"zipCode\")");
+
+        checkEqualsGolden("ArtistEmployee.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListImplicitInheritance() throws Exception {
+        // Tests that properties that are not declared in the child class itself but exists in
+        // the class due to java class inheritance indexes the correct indexable list.
+        // Artist.livesAt should be defined for Artist and index the same indexable properties as
+        // Person.livesAt.
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"}) Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Artist\", parent = {Person.class})\n"
+                        + "class Artist extends Person {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("Artist.java",
+                "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultContains("Artist.java", "addIndexableNestedProperties(\"streetName\")");
+
+        checkResultDoesNotContain("Artist.java",
+                "addIndexableNestedProperties(\"zipCode\")");
+        checkResultDoesNotContain("Artist.java", "addIndexableNestedProperties(\"state\")");
+
+        checkEqualsGolden("Artist.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListImplicitlyInheritFromMultipleLevels()
+            throws Exception {
+        // Tests that the indexable list is inherited correctly across multiple java inheritance
+        // levels.
+        // ArtistEmployee.livesAt should index the nested properties defined in Person.livesAt.
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"}) Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Artist\", parent = {Person.class})\n"
+                        + "class Artist extends Person {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "}\n"
+                        + "@Document(name = \"ArtistEmployee\", parent = {Artist.class})\n"
+                        + "class ArtistEmployee extends Artist {\n"
+                        + "  @Document.StringProperty String worksAt;\n"
+                        + "  @Document.DocumentProperty("
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("ArtistEmployee.java",
+                "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultContains("ArtistEmployee.java", "addIndexableNestedProperties(\"streetName\")");
+
+        checkResultDoesNotContain("ArtistEmployee.java",
+                "addIndexableNestedProperties(\"zipCode\")");
+        checkResultDoesNotContain("ArtistEmployee.java", "addIndexableNestedProperties(\"state\")");
+
+        checkEqualsGolden("ArtistEmployee.java");
+    }
+
+    @Test
+    public void testIndexableNestedPropertiesListTopLevelInheritTrue() throws Exception {
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "class Address {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.LongProperty long streetNumber;\n"
+                        + "  @Document.StringProperty String streetName;\n"
+                        + "  @Document.StringProperty String state;\n"
+                        + "  @Document.LongProperty long zipCode;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Person {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty String name;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"streetNumber\", \"streetName\"},"
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"Artist\", parent = {Person.class})\n"
+                        + "class Artist extends Person {\n"
+                        + "  @Document.StringProperty String mostFamousWork;\n"
+                        + "  @Document.DocumentProperty(indexableNestedPropertiesList ="
+                        + "    {\"state\"}, inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n"
+                        + "@Document(name = \"ArtistEmployee\", parent = {Artist.class})\n"
+                        + "class ArtistEmployee extends Artist {\n"
+                        + "  @Document.StringProperty String worksAt;\n"
+                        + "  @Document.DocumentProperty("
+                        + "    inheritIndexableNestedPropertiesFromSuperclass = true)"
+                        + "  Address livesAt;\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+
+        checkResultContains("ArtistEmployee.java",
+                "addIndexableNestedProperties(\"streetNumber\")");
+        checkResultContains("ArtistEmployee.java", "addIndexableNestedProperties(\"streetName\")");
+        checkResultContains("ArtistEmployee.java", "addIndexableNestedProperties(\"state\")");
+
+        checkResultDoesNotContain("ArtistEmployee.java",
+                "addIndexableNestedProperties(\"zipCode\")");
+
+        checkEqualsGolden("ArtistEmployee.java");
+    }
+
+    @Test
     public void testAnnotationOnClassGetter() throws Exception {
         Compilation compilation = compile(
                 "@Document\n"
@@ -2343,6 +2678,48 @@
     }
 
     @Test
+    public void testBuilderThatUsesGenerics() throws Exception {
+        Compilation compilation = compile(
+                "@Document\n"
+                        + "public class Gift {\n"
+                        + "  @Document.Namespace private final String mNamespace;\n"
+                        + "  @Document.Id private final String mId;\n"
+                        + "  private Gift(String namespace, String id) {\n"
+                        + "    mNamespace = namespace;\n"
+                        + "    mId = id;\n"
+                        + "  }\n"
+                        + "  public String getNamespace() { return mNamespace; }\n"
+                        + "  public String getId() { return mId; }\n"
+                        + "  public static abstract class BaseBuilder<T> {\n"
+                        + "    public final T build() { return buildInternal(false); }\n"
+                        + "    // Give this a param to have zero methods with the signature\n"
+                        + "    // () -> DocumentClass\n"
+                        + "    protected abstract T buildInternal(boolean ignore);\n"
+                        + "  }\n"
+                        + "  @Document.BuilderProducer\n"
+                        + "  public static class Builder extends BaseBuilder<Gift> {\n"
+                        + "    private String mNamespace = \"\";\n"
+                        + "    private String mId = \"\";\n"
+                        + "    @Override\n"
+                        + "    protected Gift buildInternal(boolean ignore) {\n"
+                        + "      return new Gift(mNamespace, mId);\n"
+                        + "    }\n"
+                        + "    public Builder setNamespace(String namespace) {\n"
+                        + "      mNamespace = namespace;\n"
+                        + "      return this;\n"
+                        + "    }\n"
+                        + "    public Builder setId(String id) {\n"
+                        + "      mId = id;\n"
+                        + "      return this;\n"
+                        + "    }\n"
+                        + "  }\n"
+                        + "}");
+        assertThat(compilation).succeededWithoutWarnings();
+        checkResultContains("Gift.java", "Gift.Builder builder = new Gift.Builder()");
+        checkResultContains("Gift.java", "return builder.build()");
+    }
+
+    @Test
     public void testCreationByBuilderWithParameter() throws Exception {
         Compilation compilation = compile(
                 "@Document\n"
@@ -3192,14 +3569,21 @@
     }
 
     private void checkResultContains(String className, String content) throws IOException {
-        // Get the actual file contents
+        String fileContents = getClassFileContents(className);
+        Truth.assertThat(fileContents).contains(content);
+    }
+
+    private void checkResultDoesNotContain(String className, String content) throws IOException {
+        String fileContents = getClassFileContents(className);
+        Truth.assertThat(fileContents).doesNotContain(content);
+    }
+
+    private String getClassFileContents(String className) throws IOException {
         File actualPackageDir = new File(mGenFilesDir, "com/example/appsearch");
         File actualPath =
                 new File(actualPackageDir, IntrospectionHelper.GEN_CLASS_PREFIX + className);
         Truth.assertWithMessage("Path " + actualPath + " is not a file")
                 .that(actualPath.isFile()).isTrue();
-        String actual = Files.asCharSource(actualPath, StandardCharsets.UTF_8).read();
-
-        Truth.assertThat(actual).contains(content);
+        return Files.asCharSource(actualPath, StandardCharsets.UTF_8).read();
     }
 }
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListEmpty.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListEmpty.JAVA
new file mode 100644
index 0000000..553f36b
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListEmpty.JAVA
@@ -0,0 +1,85 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Person implements DocumentClassFactory<Person> {
+  public static final String SCHEMA_NAME = "Person";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Person document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Person fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    Person document = new Person();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListImplicitInheritance.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListImplicitInheritance.JAVA
new file mode 100644
index 0000000..ac8da6b
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListImplicitInheritance.JAVA
@@ -0,0 +1,105 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Artist implements DocumentClassFactory<Artist> {
+  public static final String SCHEMA_NAME = "Artist";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addParentType($$__AppSearch__Person.SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("streetNumber")
+            .addIndexableNestedProperties("streetName")
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("mostFamousWork")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Person.class);
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Artist document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    String mostFamousWorkCopy = document.mostFamousWork;
+    if (mostFamousWorkCopy != null) {
+      builder.setPropertyString("mostFamousWork", mostFamousWorkCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Artist fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    String[] mostFamousWorkCopy = genericDoc.getPropertyStringArray("mostFamousWork");
+    String mostFamousWorkConv = null;
+    if (mostFamousWorkCopy != null && mostFamousWorkCopy.length != 0) {
+      mostFamousWorkConv = mostFamousWorkCopy[0];
+    }
+    Artist document = new Artist();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    document.mostFamousWork = mostFamousWorkConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListImplicitlyInheritFromMultipleLevels.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListImplicitlyInheritFromMultipleLevels.JAVA
new file mode 100644
index 0000000..ce3287d
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListImplicitlyInheritFromMultipleLevels.JAVA
@@ -0,0 +1,121 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__ArtistEmployee implements DocumentClassFactory<ArtistEmployee> {
+  public static final String SCHEMA_NAME = "ArtistEmployee";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addParentType($$__AppSearch__Artist.SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("streetNumber")
+            .addIndexableNestedProperties("streetName")
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("mostFamousWork")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("worksAt")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Artist.class);
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(ArtistEmployee document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    String mostFamousWorkCopy = document.mostFamousWork;
+    if (mostFamousWorkCopy != null) {
+      builder.setPropertyString("mostFamousWork", mostFamousWorkCopy);
+    }
+    String worksAtCopy = document.worksAt;
+    if (worksAtCopy != null) {
+      builder.setPropertyString("worksAt", worksAtCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public ArtistEmployee fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    String[] mostFamousWorkCopy = genericDoc.getPropertyStringArray("mostFamousWork");
+    String mostFamousWorkConv = null;
+    if (mostFamousWorkCopy != null && mostFamousWorkCopy.length != 0) {
+      mostFamousWorkConv = mostFamousWorkCopy[0];
+    }
+    String[] worksAtCopy = genericDoc.getPropertyStringArray("worksAt");
+    String worksAtConv = null;
+    if (worksAtCopy != null && worksAtCopy.length != 0) {
+      worksAtConv = worksAtCopy[0];
+    }
+    ArtistEmployee document = new ArtistEmployee();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    document.mostFamousWork = mostFamousWorkConv;
+    document.worksAt = worksAtConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritSuperclassFalse.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritSuperclassFalse.JAVA
new file mode 100644
index 0000000..e4d5805
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritSuperclassFalse.JAVA
@@ -0,0 +1,104 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Artist implements DocumentClassFactory<Artist> {
+  public static final String SCHEMA_NAME = "Artist";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addParentType($$__AppSearch__Person.SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("state")
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("mostFamousWork")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Person.class);
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Artist document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    String mostFamousWorkCopy = document.mostFamousWork;
+    if (mostFamousWorkCopy != null) {
+      builder.setPropertyString("mostFamousWork", mostFamousWorkCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Artist fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    String[] mostFamousWorkCopy = genericDoc.getPropertyStringArray("mostFamousWork");
+    String mostFamousWorkConv = null;
+    if (mostFamousWorkCopy != null && mostFamousWorkCopy.length != 0) {
+      mostFamousWorkConv = mostFamousWorkCopy[0];
+    }
+    Artist document = new Artist();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    document.mostFamousWork = mostFamousWorkConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritSuperclassTrue.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritSuperclassTrue.JAVA
new file mode 100644
index 0000000..1620454
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritSuperclassTrue.JAVA
@@ -0,0 +1,106 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Artist implements DocumentClassFactory<Artist> {
+  public static final String SCHEMA_NAME = "Artist";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addParentType($$__AppSearch__Person.SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("streetNumber")
+            .addIndexableNestedProperties("state")
+            .addIndexableNestedProperties("streetName")
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("mostFamousWork")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Person.class);
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Artist document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    String mostFamousWorkCopy = document.mostFamousWork;
+    if (mostFamousWorkCopy != null) {
+      builder.setPropertyString("mostFamousWork", mostFamousWorkCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Artist fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    String[] mostFamousWorkCopy = genericDoc.getPropertyStringArray("mostFamousWork");
+    String mostFamousWorkConv = null;
+    if (mostFamousWorkCopy != null && mostFamousWorkCopy.length != 0) {
+      mostFamousWorkConv = mostFamousWorkCopy[0];
+    }
+    Artist document = new Artist();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    document.mostFamousWork = mostFamousWorkConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritWithMultipleParentsClasses.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritWithMultipleParentsClasses.JAVA
new file mode 100644
index 0000000..3c4c645
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListInheritWithMultipleParentsClasses.JAVA
@@ -0,0 +1,108 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__ArtistEmployee implements DocumentClassFactory<ArtistEmployee> {
+  public static final String SCHEMA_NAME = "ArtistEmployee";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addParentType($$__AppSearch__Artist.SCHEMA_NAME)
+          .addParentType($$__AppSearch__Employee.SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("streetNumber")
+            .addIndexableNestedProperties("state")
+            .addIndexableNestedProperties("streetName")
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("mostFamousWork")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Artist.class);
+    classSet.add(Employee.class);
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(ArtistEmployee document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    String mostFamousWorkCopy = document.mostFamousWork;
+    if (mostFamousWorkCopy != null) {
+      builder.setPropertyString("mostFamousWork", mostFamousWorkCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public ArtistEmployee fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    String[] mostFamousWorkCopy = genericDoc.getPropertyStringArray("mostFamousWork");
+    String mostFamousWorkConv = null;
+    if (mostFamousWorkCopy != null && mostFamousWorkCopy.length != 0) {
+      mostFamousWorkConv = mostFamousWorkCopy[0];
+    }
+    ArtistEmployee document = new ArtistEmployee();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    document.mostFamousWork = mostFamousWorkConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListSimple.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListSimple.JAVA
new file mode 100644
index 0000000..d7fe77d
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListSimple.JAVA
@@ -0,0 +1,87 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Person implements DocumentClassFactory<Person> {
+  public static final String SCHEMA_NAME = "Person";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("streetNumber")
+            .addIndexableNestedProperties("streetName")
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Person document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Person fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    Person document = new Person();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListTopLevelInheritTrue.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListTopLevelInheritTrue.JAVA
new file mode 100644
index 0000000..821dcc4
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexableNestedPropertiesListTopLevelInheritTrue.JAVA
@@ -0,0 +1,122 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__ArtistEmployee implements DocumentClassFactory<ArtistEmployee> {
+  public static final String SCHEMA_NAME = "ArtistEmployee";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addParentType($$__AppSearch__Artist.SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("name")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("livesAt", $$__AppSearch__Address.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .addIndexableNestedProperties("streetNumber")
+            .addIndexableNestedProperties("state")
+            .addIndexableNestedProperties("streetName")
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("mostFamousWork")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("worksAt")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getDependencyDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Artist.class);
+    classSet.add(Address.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(ArtistEmployee document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String nameCopy = document.name;
+    if (nameCopy != null) {
+      builder.setPropertyString("name", nameCopy);
+    }
+    Address livesAtCopy = document.livesAt;
+    if (livesAtCopy != null) {
+      GenericDocument livesAtConv = GenericDocument.fromDocumentClass(livesAtCopy);
+      builder.setPropertyDocument("livesAt", livesAtConv);
+    }
+    String mostFamousWorkCopy = document.mostFamousWork;
+    if (mostFamousWorkCopy != null) {
+      builder.setPropertyString("mostFamousWork", mostFamousWorkCopy);
+    }
+    String worksAtCopy = document.worksAt;
+    if (worksAtCopy != null) {
+      builder.setPropertyString("worksAt", worksAtCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public ArtistEmployee fromGenericDocument(GenericDocument genericDoc,
+      Map<String, List<String>> documentClassMap) throws AppSearchException {
+    String namespaceConv = genericDoc.getNamespace();
+    String idConv = genericDoc.getId();
+    String[] nameCopy = genericDoc.getPropertyStringArray("name");
+    String nameConv = null;
+    if (nameCopy != null && nameCopy.length != 0) {
+      nameConv = nameCopy[0];
+    }
+    GenericDocument livesAtCopy = genericDoc.getPropertyDocument("livesAt");
+    Address livesAtConv = null;
+    if (livesAtCopy != null) {
+      livesAtConv = livesAtCopy.toDocumentClass(Address.class, documentClassMap);
+    }
+    String[] mostFamousWorkCopy = genericDoc.getPropertyStringArray("mostFamousWork");
+    String mostFamousWorkConv = null;
+    if (mostFamousWorkCopy != null && mostFamousWorkCopy.length != 0) {
+      mostFamousWorkConv = mostFamousWorkCopy[0];
+    }
+    String[] worksAtCopy = genericDoc.getPropertyStringArray("worksAt");
+    String worksAtConv = null;
+    if (worksAtCopy != null && worksAtCopy.length != 0) {
+      worksAtConv = worksAtCopy[0];
+    }
+    ArtistEmployee document = new ArtistEmployee();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.name = nameConv;
+    document.livesAt = livesAtConv;
+    document.mostFamousWork = mostFamousWorkConv;
+    document.worksAt = worksAtConv;
+    return document;
+  }
+}
diff --git a/arch/core/core-runtime/src/main/java/androidx/arch/core/executor/DefaultTaskExecutor.java b/arch/core/core-runtime/src/main/java/androidx/arch/core/executor/DefaultTaskExecutor.java
index b164eb5..99433a0 100644
--- a/arch/core/core-runtime/src/main/java/androidx/arch/core/executor/DefaultTaskExecutor.java
+++ b/arch/core/core-runtime/src/main/java/androidx/arch/core/executor/DefaultTaskExecutor.java
@@ -82,7 +82,7 @@
     private static Handler createAsync(@NonNull Looper looper) {
         if (Build.VERSION.SDK_INT >= 28) {
             return Api28Impl.createAsync(looper);
-        } else if (Build.VERSION.SDK_INT >= 17) {
+        } else {
             try {
                 // This constructor was added as private in JB MR1:
                 // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/jb-mr1-release/core/java/android/os/Handler.java
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt
index fe8a394..40b06ab 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/MergeBaselineProfileTask.kt
@@ -20,6 +20,7 @@
 import androidx.baselineprofile.gradle.utils.TASK_NAME_SUFFIX
 import androidx.baselineprofile.gradle.utils.maybeRegister
 import java.io.File
+import kotlin.io.path.Path
 import org.gradle.api.DefaultTask
 import org.gradle.api.GradleException
 import org.gradle.api.Project
@@ -262,7 +263,7 @@
                         logger.warn(
                             """
                             A baseline profile was generated for the variant `${variantName.get()}`:
-                            $absolutePath
+                            ${Path(absolutePath).toUri()}
                         """.trimIndent()
                         )
                     }
@@ -312,7 +313,7 @@
                         logger.warn(
                             """
                             A startup profile was generated for the variant `${variantName.get()}`:
-                            $absolutePath
+                            ${Path(absolutePath).toUri()}
                         """.trimIndent()
                         )
                     }
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
index b7686bc..0fec0ff 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
@@ -35,6 +35,7 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import java.io.File
+import kotlin.io.path.Path
 import org.junit.Assume.assumeTrue
 import org.junit.Rule
 import org.junit.Test
@@ -68,6 +69,8 @@
         "src/$variantName/$EXPECTED_PROFILE_FOLDER/startup-prof.txt"
     )
 
+    private fun File.toUri() = Path(canonicalPath).toUri()
+
     private fun mergedArtProfile(variantName: String): File {
         // Task name folder in path was first observed in the update to AGP 8.3.0-alpha10.
         // Before that, the folder was omitted in path.
@@ -111,7 +114,7 @@
         gradleRunner.build("generateBaselineProfile") {
             val notFound = it.lines().requireInOrder(
                 "A baseline profile was generated for the variant `release`:",
-                baselineProfileFile("main").canonicalPath
+                "${baselineProfileFile("main").toUri()}"
             )
             assertThat(notFound).isEmpty()
         }
@@ -154,9 +157,9 @@
         gradleRunner.build("generateBaselineProfile") {
             val notFound = it.lines().requireInOrder(
                 "A baseline profile was generated for the variant `release`:",
-                baselineProfileFile("release").canonicalPath,
+                "${baselineProfileFile("release").toUri()}",
                 "A startup profile was generated for the variant `release`:",
-                startupProfileFile("release").canonicalPath
+                "${startupProfileFile("release").toUri()}"
             )
             assertThat(notFound).isEmpty()
         }
@@ -237,9 +240,9 @@
 
                 val notFound = it.lines().requireInOrder(
                     "A baseline profile was generated for the variant `$variantName`:",
-                    baselineProfileFile(variantName).canonicalPath,
+                    "${baselineProfileFile(variantName).toUri()}",
                     "A startup profile was generated for the variant `$variantName`:",
-                    startupProfileFile(variantName).canonicalPath
+                    "${startupProfileFile(variantName).toUri()}"
                 )
 
                 assertWithMessage(
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt
index 93b9fb4..798062a 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt
@@ -65,8 +65,6 @@
         val traceFilePath = linkRule.createReportedTracePath(Packages.TEST)
         val perfettoCapture = PerfettoCapture()
 
-        verifyTraceEnable(false)
-
         perfettoCapture.start(
             PerfettoConfig.Benchmark(
                 appTagPackages = listOf(Packages.TEST),
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt
index 41d9868..5b04350c 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt
@@ -28,11 +28,9 @@
 import androidx.benchmark.perfetto.PerfettoTraceProcessor
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
-import androidx.testutils.verifyWithPolling
 import androidx.tracing.Trace
 import androidx.tracing.trace
 import kotlin.test.assertEquals
-import kotlin.test.fail
 import org.junit.After
 import org.junit.Assert.assertTrue
 import org.junit.Assume.assumeTrue
@@ -94,8 +92,6 @@
         val traceFilePath = linkRule.createReportedTracePath(Packages.TEST)
         val perfettoCapture = PerfettoCapture(unbundled)
 
-        verifyTraceEnable(false)
-
         perfettoCapture.start(
             PerfettoConfig.Benchmark(
                 appTagPackages = listOf(Packages.TEST),
@@ -103,14 +99,10 @@
             )
         )
 
-        if (!Trace.isEnabled()) {
-            // Should be available immediately, but let's wait a while to see if it works slowly.
-            val delayMs = verifyTraceEnable(true)
-            fail(
-                "In-process tracing should be enabled immediately after trace " +
-                    "capture is started. Had to poll for approx $delayMs ms"
-            )
-        }
+        assertTrue(
+            "In-process tracing should be enabled immediately after trace capture is started",
+            Trace.isEnabled()
+        )
 
         /**
          * Trace section labels, in order
@@ -155,27 +147,3 @@
         }
     }
 }
-
-fun verifyTraceEnable(enabled: Boolean): Long {
-    // We poll here, since we may need to wait for enable flags to propagate to apps
-    return verifyWithPolling(
-        "Timeout waiting for Trace.isEnabled == $enabled, tags=${getTags()}",
-        periodMs = 50,
-        timeoutMs = 5000
-    ) {
-        Trace.isEnabled() == enabled
-    }
-}
-
-private fun getTags(): String {
-    val method = android.os.Trace::class.java.getMethod(
-        "isTagEnabled",
-        Long::class.javaPrimitiveType
-    )
-    val never = method.invoke(null, /*TRACE_TAG_NEVER*/ 0)
-    val always = method.invoke(null, /*TRACE_TAG_ALWAYS*/ 1L shl 0)
-    val view = method.invoke(null, /*TRACE_TAG_VIEW*/ 1L shl 3)
-    val app = method.invoke(null, /*TRACE_TAG_APP*/ 1L shl 12)
-
-    return "n $never, a $always, v $view, app $app"
-}
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
index 441f9ff..e888c7b 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
@@ -48,7 +48,7 @@
 import org.junit.runners.Parameterized
 import org.junit.runners.Parameterized.Parameters
 
-private const val tracingPerfettoVersion = "1.0.0-beta03" // TODO(224510255): get by 'reflection'
+private const val tracingPerfettoVersion = "1.0.0" // TODO(224510255): get by 'reflection'
 private const val minSupportedSdk = Build.VERSION_CODES.R // TODO(234351579): Support API < 30
 
 @RunWith(Parameterized::class)
diff --git a/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt b/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt
index 7b55cde..8e04606 100644
--- a/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt
+++ b/benchmark/integration-tests/baselineprofile-producer/src/main/java/androidx/benchmark/integration/baselineprofile/producer/BaselineProfileTest.kt
@@ -43,6 +43,7 @@
     fun standardBaselineProfile() = baselineRule.collect(
         packageName = PACKAGE_NAME,
         includeInStartupProfile = false,
+        maxIterations = 1,
         profileBlock = {
             startActivityAndWait(Intent(ACTION))
             device.waitForIdle()
@@ -53,6 +54,7 @@
     fun startupBaselineProfile() = baselineRule.collect(
         packageName = PACKAGE_NAME,
         includeInStartupProfile = true,
+        maxIterations = 1,
         profileBlock = {
             startActivityAndWait(Intent(ACTION))
             device.waitForIdle()
diff --git a/biometric/biometric/src/androidTest/java/androidx/biometric/BiometricPromptTest.java b/biometric/biometric/src/androidTest/java/androidx/biometric/BiometricPromptTest.java
index c8d92bc..8797f80 100644
--- a/biometric/biometric/src/androidTest/java/androidx/biometric/BiometricPromptTest.java
+++ b/biometric/biometric/src/androidTest/java/androidx/biometric/BiometricPromptTest.java
@@ -27,7 +27,6 @@
 import androidx.test.core.app.ActivityScenario;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.uiautomator.UiDevice;
 
@@ -47,11 +46,9 @@
     }
 
     @Test // prevents test runner from failing since all tests are ignored
-    @SdkSuppress(minSdkVersion = 18)
     public void dummy() {}
 
     @Test
-    @SdkSuppress(minSdkVersion = 18)
     public void testViewModel_inActivity() {
         try (ActivityScenario<TestActivity> scenario =
                      ActivityScenario.launch(TestActivity.class)) {
@@ -75,7 +72,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 18)
     public void testViewModel_inFragment() {
         try (FragmentScenario<TestFragment> scenario =
                      FragmentScenario.launchInContainer(TestFragment.class)) {
diff --git a/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java b/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java
index a0f89e9..0c4eff7 100644
--- a/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java
+++ b/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java
@@ -449,11 +449,6 @@
             return;
         }
 
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
-            Log.e(TAG, "Unable to show fingerprint dialog on API <19.");
-            return;
-        }
-
         if (isAdded()) {
             mViewModel.setFingerprintDialogDismissedInstantly(true);
             if (!DeviceUtils.shouldHideFingerprintDialog(context, Build.MODEL)) {
diff --git a/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java b/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java
index ac10446..878dfad 100644
--- a/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java
+++ b/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java
@@ -149,7 +149,6 @@
      *
      * @return A {@link FingerprintDialogFragment}.
      */
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     @NonNull
     static FingerprintDialogFragment newInstance(boolean hostedInActivity) {
         final FingerprintDialogFragment fragment = new FingerprintDialogFragment();
diff --git a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt
index aa07a73..6937dab 100644
--- a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt
+++ b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothDeviceTest.kt
@@ -17,10 +17,12 @@
 package androidx.bluetooth
 
 import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice as FwkBluetoothDevice
 import android.bluetooth.BluetoothManager
 import android.content.Context
 import android.os.Build
 import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SdkSuppress
 import androidx.test.rule.GrantPermissionRule
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assume.assumeNotNull
@@ -52,6 +54,7 @@
     private val bluetoothManager: BluetoothManager? =
         context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?
     private val bluetoothAdapter: BluetoothAdapter? = bluetoothManager?.adapter
+    private val bluetoothLe = BluetoothLe(context)
 
     @Before
     fun setUp() {
@@ -66,4 +69,60 @@
         assertThat(fwkBluetoothDevice.bondState).isEqualTo(bluetoothDevice.bondState)
         assertThat(fwkBluetoothDevice.name).isEqualTo(bluetoothDevice.name)
     }
+
+    @Test
+    fun equalIdWithEqualAddress() {
+        val address = "00:01:02:03:04:05"
+        val fwkBluetoothDevice1 = bluetoothAdapter!!.getRemoteDevice(address)
+        val fwkBluetoothDevice2 = bluetoothAdapter.getRemoteDevice(address)
+
+        val bluetoothDevice1 = BluetoothDevice(fwkBluetoothDevice1)
+        val bluetoothDevice2 = BluetoothDevice(fwkBluetoothDevice2)
+
+        assertThat(bluetoothDevice1.id).isEqualTo(bluetoothDevice2.id)
+    }
+
+    @Test
+    fun differentIdWithDifferentAddress() {
+        val address1 = "00:01:02:03:04:05"
+        val address2 = "05:04:03:02:01:00"
+        val fwkBluetoothDevice1 = bluetoothAdapter!!.getRemoteDevice(address1)
+        val fwkBluetoothDevice2 = bluetoothAdapter.getRemoteDevice(address2)
+
+        val bluetoothDevice1 = BluetoothDevice(fwkBluetoothDevice1)
+        val bluetoothDevice2 = BluetoothDevice(fwkBluetoothDevice2)
+
+        assertThat(bluetoothDevice1.id).isNotEqualTo(bluetoothDevice2.id)
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun differentIdWithSameAddressDifferentAddressType() {
+        val address = "00:01:02:03:04:05"
+        val fwkBluetoothDevice1 = bluetoothAdapter!!
+            .getRemoteLeDevice(address, FwkBluetoothDevice.ADDRESS_TYPE_PUBLIC)
+        val fwkBluetoothDevice2 = bluetoothAdapter
+            .getRemoteLeDevice(address, FwkBluetoothDevice.ADDRESS_TYPE_RANDOM)
+
+        val bluetoothDevice1 = BluetoothDevice(fwkBluetoothDevice1)
+        val bluetoothDevice2 = BluetoothDevice(fwkBluetoothDevice2)
+
+        assertThat(bluetoothDevice1.id).isNotEqualTo(bluetoothDevice2.id)
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun differentIdDifferentRandomAddressType() {
+        val address1 = "57:96:C7:1A:45:9C"
+        val address2 = "00:11:02:03:04:C0"
+        val fwkBluetoothDevice1 = bluetoothAdapter!!
+            .getRemoteLeDevice(address1, FwkBluetoothDevice.ADDRESS_TYPE_RANDOM)
+        val fwkBluetoothDevice2 = bluetoothAdapter
+            .getRemoteLeDevice(address2, FwkBluetoothDevice.ADDRESS_TYPE_RANDOM)
+
+        val bluetoothDevice1 = BluetoothDevice(fwkBluetoothDevice1)
+        val bluetoothDevice2 = BluetoothDevice(fwkBluetoothDevice2)
+
+        assertThat(bluetoothDevice1.id).isNotEqualTo(bluetoothDevice2.id)
+    }
 }
diff --git a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt
index 9236324..df5d8b1 100644
--- a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt
+++ b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt
@@ -17,11 +17,13 @@
 package androidx.bluetooth
 
 import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice as FwkBluetoothDevice
 import android.bluetooth.BluetoothManager
 import android.bluetooth.le.ScanResult as FwkScanResult
 import android.content.Context
 import android.os.Build
 import android.os.ParcelUuid
+import androidx.bluetooth.utils.addressType
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.SdkSuppress
 import androidx.test.rule.GrantPermissionRule
@@ -39,6 +41,7 @@
  */
 @RunWith(JUnit4::class)
 class ScanResultTest {
+
     @Rule
     @JvmField
     val permissionRule: GrantPermissionRule = if (Build.VERSION.SDK_INT >= 31) {
@@ -53,6 +56,7 @@
     private val bluetoothManager: BluetoothManager? =
         context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?
     private val bluetoothAdapter: BluetoothAdapter? = bluetoothManager?.adapter
+    private val bluetoothLe = BluetoothLe(context)
 
     @Before
     fun setUp() {
@@ -90,8 +94,13 @@
         assertThat(BluetoothDevice(fwkBluetoothDevice).bondState)
             .isEqualTo(scanResult.device.bondState)
         assertThat(address).isEqualTo(scanResult.deviceAddress.address)
-        assertThat(BluetoothAddress.ADDRESS_TYPE_UNKNOWN)
-            .isEqualTo(scanResult.deviceAddress.addressType)
+        val expectedAddressType = if (Build.VERSION.SDK_INT >= 34) {
+            BluetoothAddress.ADDRESS_TYPE_PUBLIC
+        } else {
+            BluetoothAddress.ADDRESS_TYPE_UNKNOWN
+        }
+        assertThat(scanResult.deviceAddress.addressType)
+            .isEqualTo(expectedAddressType)
         assertThat(true).isEqualTo(scanResult.isConnectable())
         assertThat(timeStampNanos).isEqualTo(scanResult.timestampNanos)
         assertThat(scanResult.getManufacturerSpecificData(1)).isNull()
@@ -129,4 +138,100 @@
         assertThat(scanResult.device).isEqualTo(scanResult.device)
         assertThat(scanResult.deviceAddress).isEqualTo(scanResult.deviceAddress)
     }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun frameworkScanResultAddressTypeRandomStatic() {
+        val address = "F0:43:A8:23:10:11"
+        val fwkBluetoothDevice = bluetoothAdapter!!
+            .getRemoteLeDevice(address, FwkBluetoothDevice.ADDRESS_TYPE_RANDOM)
+        val rssi = 34
+        val periodicAdvertisingInterval = 8
+        val timeStampNanos: Long = 1
+
+        val fwkScanResult = FwkScanResult(
+            fwkBluetoothDevice,
+            1,
+            0,
+            0,
+            0,
+            0,
+            rssi,
+            periodicAdvertisingInterval,
+            null,
+            timeStampNanos
+        )
+
+        val bluetoothAddress = BluetoothAddress(
+            fwkScanResult.device.address,
+            fwkScanResult.device.addressType()
+        )
+
+        assertThat(bluetoothAddress.addressType)
+            .isEqualTo(BluetoothAddress.ADDRESS_TYPE_RANDOM_STATIC)
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun frameworkScanResultAddressTypeRandomResolvable() {
+        val address = "40:01:02:03:04:05"
+        val fwkBluetoothDevice = bluetoothAdapter!!
+            .getRemoteLeDevice(address, FwkBluetoothDevice.ADDRESS_TYPE_RANDOM)
+        val rssi = 34
+        val periodicAdvertisingInterval = 8
+        val timeStampNanos: Long = 1
+
+        val fwkScanResult = FwkScanResult(
+            fwkBluetoothDevice,
+            1,
+            0,
+            0,
+            0,
+            0,
+            rssi,
+            periodicAdvertisingInterval,
+            null,
+            timeStampNanos
+        )
+
+        val bluetoothAddress = BluetoothAddress(
+            fwkScanResult.device.address,
+            fwkScanResult.device.addressType()
+        )
+
+        assertThat(bluetoothAddress.addressType)
+            .isEqualTo(BluetoothAddress.ADDRESS_TYPE_RANDOM_RESOLVABLE)
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun frameworkScanResultAddressTypeRandomNonResolvable() {
+        val address = "00:01:02:03:04:05"
+        val fwkBluetoothDevice = bluetoothAdapter!!
+            .getRemoteLeDevice(address, FwkBluetoothDevice.ADDRESS_TYPE_RANDOM)
+        val rssi = 34
+        val periodicAdvertisingInterval = 8
+        val timeStampNanos: Long = 1
+
+        val fwkScanResult = FwkScanResult(
+            fwkBluetoothDevice,
+            1,
+            0,
+            0,
+            0,
+            0,
+            rssi,
+            periodicAdvertisingInterval,
+            null,
+            timeStampNanos
+        )
+
+        val bluetoothAddress = BluetoothAddress(
+            fwkScanResult.device.address,
+            fwkScanResult.device.addressType()
+        )
+
+        assertThat(bluetoothAddress.addressType)
+            .isEqualTo(BluetoothAddress.ADDRESS_TYPE_RANDOM_NON_RESOLVABLE)
+    }
 }
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AdvertiseException.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AdvertiseException.kt
index 4556aee..68feef1 100644
--- a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AdvertiseException.kt
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AdvertiseException.kt
@@ -20,6 +20,11 @@
 import androidx.annotation.IntDef
 import androidx.annotation.RestrictTo
 
+/**
+ * Exception indicating a failure to start an advertise operation.
+ *
+ * @property errorCode the error code for indicating the reason why the exception is thrown.
+ */
 class AdvertiseException(errorCode: Int) : BluetoothException(errorCode) {
 
     companion object {
@@ -52,6 +57,7 @@
     )
     annotation class AdvertiseFail
 
+    /** The error code associated with this exception. */
     override val errorCode: @AdvertiseFail Int = when (errorCode) {
         FwkAdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE -> DATA_TOO_LARGE
 
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothAddress.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothAddress.kt
index a8f4a99..c104d69 100644
--- a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothAddress.kt
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothAddress.kt
@@ -46,6 +46,12 @@
         const val ADDRESS_TYPE_UNKNOWN: Int = 0xFFFF
     }
 
+    @Target(
+        AnnotationTarget.PROPERTY,
+        AnnotationTarget.LOCAL_VARIABLE,
+        AnnotationTarget.VALUE_PARAMETER,
+        AnnotationTarget.TYPE
+    )
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @Retention(AnnotationRetention.SOURCE)
     @IntDef(
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt
index 9275145..6abe21f 100644
--- a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothDevice.kt
@@ -19,6 +19,7 @@
 import android.bluetooth.BluetoothDevice as FwkBluetoothDevice
 import androidx.annotation.RequiresPermission
 import androidx.annotation.RestrictTo
+import androidx.bluetooth.utils.deviceId
 import java.util.UUID
 
 /**
@@ -33,7 +34,8 @@
 class BluetoothDevice @RestrictTo(RestrictTo.Scope.LIBRARY) constructor(
     internal val fwkDevice: FwkBluetoothDevice
 ) {
-    val id: UUID = UUID.randomUUID()
+
+    val id: UUID = deviceId(BluetoothLe.packageName, fwkDevice)
 
     @get:RequiresPermission(
         anyOf = ["android.permission.BLUETOOTH",
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothLe.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothLe.kt
index 19416fc..31e8252 100644
--- a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothLe.kt
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/BluetoothLe.kt
@@ -36,6 +36,13 @@
     companion object {
         /** Advertise started successfully. */
         const val ADVERTISE_STARTED: Int = 10100
+
+        internal lateinit var packageName: String
+            private set
+    }
+
+    init {
+        packageName = context.applicationContext.packageName
     }
 
     @Target(
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanException.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanException.kt
index db142e0..cd7e2f0 100644
--- a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanException.kt
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanException.kt
@@ -20,6 +20,11 @@
 import androidx.annotation.IntDef
 import androidx.annotation.RestrictTo
 
+/**
+ * Exception indicating a failure to start a scan operation.
+ *
+ * @property errorCode the error code for indicating the reason why the exception is thrown.
+ */
 class ScanException(errorCode: Int) : BluetoothException(errorCode) {
 
     companion object {
@@ -56,6 +61,7 @@
     )
     annotation class ScanFail
 
+    /** The error code associated with this exception. */
     override val errorCode: @ScanFail Int = when (errorCode) {
         FwkScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED ->
             APPLICATION_REGISTRATION_FAILED
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt
index b9af5f7..2e3cf987 100644
--- a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt
@@ -22,6 +22,7 @@
 import androidx.annotation.DoNotInline
 import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
+import androidx.bluetooth.utils.addressType
 import java.util.UUID
 
 /**
@@ -74,12 +75,10 @@
     /** Remote Bluetooth device found. */
     val device: BluetoothDevice = BluetoothDevice(fwkScanResult.device)
 
-    // TODO(kihongs) Find a way to get address type from framework scan result
     /** Bluetooth address for the remote device found. */
-
     val deviceAddress: BluetoothAddress = BluetoothAddress(
         fwkScanResult.device.address,
-        BluetoothAddress.ADDRESS_TYPE_UNKNOWN
+        fwkScanResult.device.addressType()
     )
 
     /** Device timestamp when the advertisement was last seen. */
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/utils/FwkBluetoothDevice.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/utils/FwkBluetoothDevice.kt
new file mode 100644
index 0000000..3e39c67
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/utils/FwkBluetoothDevice.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.bluetooth.utils
+
+import android.bluetooth.BluetoothDevice as FwkBluetoothDevice
+import android.os.Build
+import android.os.Parcel
+import androidx.annotation.RequiresApi
+import androidx.bluetooth.BluetoothAddress
+
+/** Address type random static bits value */
+private const val ADDRESS_TYPE_RANDOM_STATIC_BITS_VALUE: Int = 3
+
+/** Address type random resolvable bits value */
+private const val ADDRESS_TYPE_RANDOM_RESOLVABLE_BITS_VALUE: Int = 1
+
+/** Address type random non resolvable bits value */
+private const val ADDRESS_TYPE_RANDOM_NON_RESOLVABLE_BITS_VALUE: Int = 0
+
+// mAddressType is added to the parcel in API 34
+internal fun FwkBluetoothDevice.addressType(): @BluetoothAddress.AddressType Int {
+    return if (Build.VERSION.SDK_INT >= 34) {
+        return addressType34()
+    } else {
+        BluetoothAddress.ADDRESS_TYPE_UNKNOWN
+    }
+}
+
+@RequiresApi(34)
+private fun FwkBluetoothDevice.addressType34(): @BluetoothAddress.AddressType Int {
+    val parcel = Parcel.obtain()
+    writeToParcel(parcel, 0)
+    parcel.setDataPosition(0)
+    parcel.readString() // Skip address
+    val mAddressType = parcel.readInt()
+    parcel.recycle()
+
+    return when (mAddressType) {
+        FwkBluetoothDevice.ADDRESS_TYPE_PUBLIC -> BluetoothAddress.ADDRESS_TYPE_PUBLIC
+        FwkBluetoothDevice.ADDRESS_TYPE_RANDOM ->
+            when (address.substring(0, 1).toInt(16).shr(2)) {
+                ADDRESS_TYPE_RANDOM_STATIC_BITS_VALUE ->
+                    BluetoothAddress.ADDRESS_TYPE_RANDOM_STATIC
+
+                ADDRESS_TYPE_RANDOM_RESOLVABLE_BITS_VALUE ->
+                    BluetoothAddress.ADDRESS_TYPE_RANDOM_RESOLVABLE
+
+                ADDRESS_TYPE_RANDOM_NON_RESOLVABLE_BITS_VALUE ->
+                    BluetoothAddress.ADDRESS_TYPE_RANDOM_NON_RESOLVABLE
+
+                else -> BluetoothAddress.ADDRESS_TYPE_UNKNOWN
+            }
+
+        FwkBluetoothDevice.ADDRESS_TYPE_UNKNOWN -> BluetoothAddress.ADDRESS_TYPE_UNKNOWN
+        else -> BluetoothAddress.ADDRESS_TYPE_UNKNOWN
+    }
+}
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/utils/Utils.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/utils/Utils.kt
new file mode 100644
index 0000000..ed4f1dd
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/utils/Utils.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.bluetooth.utils
+
+import android.bluetooth.BluetoothDevice as FwkBluetoothDevice
+import androidx.annotation.RestrictTo
+import java.security.MessageDigest
+import java.util.UUID
+import kotlin.experimental.and
+import kotlin.experimental.or
+
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+internal fun deviceId(
+    packageName: String,
+    fwkDevice: FwkBluetoothDevice
+): UUID {
+    val name = packageName + fwkDevice.address + fwkDevice.addressType()
+    val md = MessageDigest.getInstance("SHA-1")
+    md.update(name.toByteArray())
+    val hash = md.digest()
+
+    // Set to version 5
+    hash[6] = hash[6] and (0x0F).toByte()
+    hash[6] = hash[6] or (0x50).toByte()
+    // Set to IETF variant
+    hash[8] = hash[8] and (0x3F).toByte()
+    hash[8] = hash[8] or (0x80).toByte()
+
+    var msb: Long = 0
+    var lsb: Long = 0
+
+    for (i in 0..7) {
+        msb = (msb.shl(8) or (hash[i].toLong() and 0xFF))
+    }
+    for (i in 8..15) {
+        lsb = (lsb.shl(8) or (hash[i].toLong() and 0xFF))
+    }
+
+    return UUID(msb, lsb)
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/connections/ConnectionsViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/connections/ConnectionsViewModel.kt
index 0305623..8ca27ee 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/connections/ConnectionsViewModel.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/connections/ConnectionsViewModel.kt
@@ -101,8 +101,12 @@
                     Log.d(TAG, "bluetoothLe.connectGatt result: services() = $services")
 
                     deviceConnection.status = Status.CONNECTED
-                    deviceConnection.services = services
-                    updateUi()
+                    launch {
+                        servicesFlow.collect {
+                            deviceConnection.services = it
+                            updateUi()
+                        }
+                    }
 
                     deviceConnection.onCharacteristicActionClick =
                         object : OnCharacteristicActionClick {
@@ -111,14 +115,6 @@
                                 characteristic: GattCharacteristic,
                                 action: @OnCharacteristicActionClick.Action Int
                             ) {
-                                Log.d(
-                                    TAG,
-                                    "onClick() called with: " +
-                                        "deviceConnection = $deviceConnection, " +
-                                        "characteristic = $characteristic, " +
-                                        "action = $action"
-                                )
-
                                 when (action) {
                                     OnCharacteristicActionClick.READ -> readCharacteristic(
                                         this@connectGatt,
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
index 21a00d9..6a62b40 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
@@ -24,6 +24,7 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import dagger.hilt.android.lifecycle.HiltViewModel
+import java.util.UUID
 import javax.inject.Inject
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -46,7 +47,7 @@
         private const val TAG = "ScannerViewModel"
     }
 
-    private val scanResultsMap = mutableMapOf<String, ScanResult>()
+    private val scanResultsMap = mutableMapOf<UUID, ScanResult>()
 
     var scanJob: Job? = null
 
@@ -64,7 +65,7 @@
                     it.copy(isScanning = true, resultMessage = "Scan started")
                 }
             }
-            .filterNot { scanResultsMap.containsKey(it.deviceAddress.address) }
+            .filterNot { scanResultsMap.containsKey(it.device.id) }
             .catch { throwable ->
                 Log.e(TAG, "bluetoothLe.scan() catch", throwable)
 
@@ -98,7 +99,7 @@
             }
             .onEach { scanResult ->
                 Log.d(TAG, "bluetoothLe.scan() onEach: $scanResult")
-                scanResultsMap[scanResult.deviceAddress.address] = scanResult
+                scanResultsMap[scanResult.device.id] = scanResult
                 _uiState.update {
                     it.copy(scanResults = scanResultsMap.values.toList())
                 }
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/item_scan_result.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/item_scan_result.xml
index 5ec2347..0630145 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/item_scan_result.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/item_scan_result.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   Copyright 2023 The Android Open Source Project
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,10 +19,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:gravity="center_vertical"
-    android:paddingStart="16dp"
-    android:paddingTop="8dp"
-    android:paddingEnd="16dp"
-    android:paddingBottom="8dp">
+    android:padding="8dp">
 
     <ImageView
         android:layout_width="wrap_content"
@@ -35,20 +31,21 @@
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:gravity="center"
         android:orientation="vertical"
-        android:paddingStart="8dp"
-        android:paddingEnd="8dp">
+        android:paddingStart="4dp"
+        android:paddingEnd="4dp">
 
         <TextView
             android:id="@+id/text_view_device_id"
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textColor="@color/black"
-            tools:text="AB:CD:12:34:56:78" />
+            tools:text="054ee8fe-8ccf-11ee-b9d1-0242ac120002" />
 
         <TextView
             android:id="@+id/text_view_device_name"
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             tools:text="Omer S23 Ultra" />
 
@@ -56,9 +53,11 @@
 
     <Button
         android:id="@+id/button_connect"
-        android:layout_width="wrap_content"
+        android:layout_width="90dp"
         android:layout_height="wrap_content"
+        android:padding="0dp"
         android:text="@string/connect"
+        android:textSize="13sp"
         app:backgroundTint="@color/green_500" />
 
 </LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/tab_item_device.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/tab_item_device.xml
index 238672c..41b4081 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/tab_item_device.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/tab_item_device.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   Copyright 2023 The Android Open Source Project
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,34 +18,39 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:gravity="center">
+    android:gravity="center_vertical">
 
     <LinearLayout
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="vertical">
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
 
         <TextView
             android:id="@+id/text_view_device_id"
-            android:layout_width="wrap_content"
+            android:layout_width="136dp"
             android:layout_height="wrap_content"
             android:textColor="@color/black"
-            tools:text="70:04:13:03:98:B9" />
+            tools:text="054ee8fe-8ccf-11ee-b9d1-0242ac120002" />
 
         <TextView
             android:id="@+id/text_view_name"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            tools:text="R33-0473" />
+            android:gravity="center"
+            tools:text="Pixel 7" />
 
     </LinearLayout>
 
     <com.google.android.material.button.MaterialButton
         android:id="@+id/image_button_remove"
         style="@style/Widget.MaterialComponents.Button.TextButton"
-        android:layout_width="48dp"
-        android:layout_height="wrap_content"
-        app:icon="@drawable/baseline_clear_24" />
+        android:layout_width="40dp"
+        android:layout_height="match_parent"
+        app:icon="@drawable/baseline_clear_24"
+        app:iconGravity="textStart"
+        app:iconPadding="0dp" />
 
 </LinearLayout>
diff --git a/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt b/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt
index da267c6..e4e2046e 100644
--- a/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt
+++ b/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt
@@ -78,7 +78,7 @@
       <groupId>androidx.collection</groupId>
       <artifactId>collection-jvm</artifactId>
       <version>1.3.0-alpha05</version>
-      <scope>runtime</scope>
+      <scope>compile</scope>
     </dependency>
   </dependencies>
 </project>
@@ -136,7 +136,7 @@
       <artifactId>ui-geometry-android</artifactId>
       <version>1.6.0-alpha01</version>
       <type>aar</type>
-      <scope>runtime</scope>
+      <scope>compile</scope>
     </dependency>
   </dependencies>
 </project>
diff --git a/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
index b1b65e6..88bc085 100644
--- a/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
+++ b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
@@ -18,11 +18,11 @@
 
 import java.io.File
 import java.util.function.BiFunction
-import java.util.function.Predicate
 import org.gradle.api.Project
 import org.gradle.api.Transformer
 import org.gradle.api.plugins.ExtraPropertiesExtension
 import org.gradle.api.provider.Provider
+import org.gradle.api.specs.Spec
 import org.gradle.testfixtures.ProjectBuilder
 import org.hamcrest.CoreMatchers
 import org.hamcrest.MatcherAssert
@@ -171,26 +171,24 @@
     class TestProvider(private val list: List<String>) : Provider<List<String>> {
         override fun get(): List<String> = list
         override fun getOrNull(): List<String> = list
-        override fun isPresent(): Boolean = TODO("used")
-        override fun forUseAtConfigurationTime(): Provider<List<String>> = TODO("used")
+        override fun isPresent(): Boolean = TODO("unused")
+        override fun forUseAtConfigurationTime(): Provider<List<String>> = TODO("unused")
         override fun <U : Any?, R : Any?> zip(
             right: Provider<U>,
             combiner: BiFunction<in List<String>, in U, out R?>
-        ): Provider<R> = TODO("used")
+        ): Provider<R> = TODO("unused")
         override fun orElse(provider: Provider<out List<String>>): Provider<List<String>> {
-            TODO("used")
+            TODO("unused")
         }
-        override fun orElse(value: List<String>): Provider<List<String>> = TODO("used")
+        override fun orElse(value: List<String>): Provider<List<String>> = TODO("unused")
         override fun <S : Any?> flatMap(
             transformer: Transformer<out Provider<out S>?, in List<String>>
-        ): Provider<S> = TODO("used")
-        override fun filter(predicate: Predicate<in List<String>>): Provider<List<String>> {
-            TODO("used")
-        }
+        ): Provider<S> = TODO("unused")
+        override fun filter(spec: Spec<in List<String>>): Provider<List<String>> = TODO("unused")
         override fun <S : Any?> map(
             transformer: Transformer<out S?, in List<String>>
-        ): Provider<S> = TODO("used")
-        override fun getOrElse(defaultValue: List<String>): List<String> = TODO("used")
+        ): Provider<S> = TODO("unused")
+        override fun getOrElse(defaultValue: List<String>): List<String> = TODO("unused")
     }
 
     @Test
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
index 3fdff5f4..df4017b 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
@@ -45,6 +45,8 @@
     "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination"
 const val zipComposeReportsTaskName = "zipComposeCompilerReports"
 const val zipComposeMetricsTaskName = "zipComposeCompilerMetrics"
+const val composeStrongSkippingOption =
+    "plugin:androidx.compose.compiler.plugins.kotlin:experimentalStrongSkipping"
 
 /** Plugin to apply common configuration for Compose projects. */
 class AndroidXComposeImplPlugin : Plugin<Project> {
@@ -242,6 +244,10 @@
             compile.doFirst {
                 compile.kotlinOptions.freeCompilerArgs += "-Xplugin=${kotlinPlugin.first()}"
 
+                // Enable Compose strong skipping mode
+                compile.kotlinOptions.freeCompilerArgs +=
+                    listOf("-P", "$composeStrongSkippingOption=true")
+
                 if (shouldPublish) {
                     compile.kotlinOptions.freeCompilerArgs += listOf("-P", composeSourceOption)
                 }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
index abeaaac..55441d96 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
@@ -542,7 +542,7 @@
         if (platformId == PlatformIdentifier.ANDROID.id) {
             appendElement("type", "aar")
         }
-        appendElement("scope", "runtime")
+        appendElement("scope", "compile")
     }
 }
 
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/SdkResourceGenerator.kt b/buildSrc/public/src/main/kotlin/androidx/build/SdkResourceGenerator.kt
index 1a4dc97..991a22c 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/SdkResourceGenerator.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/SdkResourceGenerator.kt
@@ -61,7 +61,7 @@
     @get:Input val agpDependency: String = AGP_LATEST
 
     @get:Input
-    val navigationRuntime: String = "androidx.navigation:navigation-runtime:2.4.0-alpha01"
+    val navigationRuntime: String = "androidx.navigation:navigation-runtime:2.4.0"
 
     @get:Input abstract val kotlinStdlib: Property<String>
 
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
index 57ccca4..05fed81 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
@@ -24,13 +24,13 @@
 import android.hardware.camera2.CameraCharacteristics.CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION
 import android.hardware.camera2.CameraMetadata
 import android.hardware.camera2.params.DynamicRangeProfiles
-import android.os.Build
 import android.util.Range
 import android.util.Size
 import android.view.Surface
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.CameraPipe
 import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.integration.compat.DynamicRangeProfilesCompat
 import androidx.camera.camera2.pipe.integration.compat.StreamConfigurationMapCompat
 import androidx.camera.camera2.pipe.integration.compat.quirk.CameraQuirks
 import androidx.camera.camera2.pipe.integration.compat.workaround.isFlashAvailable
@@ -57,6 +57,7 @@
 import androidx.camera.core.ZoomState
 import androidx.camera.core.impl.CameraCaptureCallback
 import androidx.camera.core.impl.CameraInfoInternal
+import androidx.camera.core.impl.DynamicRanges
 import androidx.camera.core.impl.EncoderProfilesProvider
 import androidx.camera.core.impl.Quirks
 import androidx.camera.core.impl.Timebase
@@ -199,17 +200,16 @@
         return false
     }
 
-    @SuppressLint("ClassVerificationFailure")
     override fun getSupportedDynamicRanges(): Set<DynamicRange> {
-        // TODO: use DynamicRangesCompat instead after it is migrates from camera-camera2.
-        if (Build.VERSION.SDK_INT >= 33) {
-            val availableProfiles = cameraProperties.metadata[
-                CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES]
-            if (availableProfiles != null) {
-                return profileSetToDynamicRangeSet(availableProfiles.supportedProfiles)
-            }
-        }
-        return setOf(SDR)
+        return DynamicRangeProfilesCompat
+            .fromCameraMetaData(cameraProperties.metadata)
+            .supportedDynamicRanges
+    }
+
+    override fun querySupportedDynamicRanges(
+        candidateDynamicRanges: Set<DynamicRange>
+    ): Set<DynamicRange> {
+        return DynamicRanges.findAllPossibleMatches(candidateDynamicRanges, supportedDynamicRanges)
     }
 
     override fun isPreviewStabilizationSupported(): Boolean {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompat.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompat.kt
index 4d1fddd6..37150eb 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompat.kt
@@ -29,14 +29,18 @@
  */
 @RequiresApi(21)
 class DynamicRangeProfilesCompat internal constructor(
-    private val mImpl: DynamicRangeProfilesCompatImpl
+    private val impl: DynamicRangeProfilesCompatImpl
 ) {
+    /** The set of supported dynamic ranges. */
+    val supportedDynamicRanges: Set<DynamicRange>
+        get() = impl.supportedDynamicRanges
+
     /**
      * Returns a set of supported [DynamicRange] that can be referenced in a single
      * capture request.
      *
      * For example if a particular 10-bit output capable device returns (STANDARD,
-     * HLG10, HDR10) as result from calling [getSupportedDynamicRanges] and
+     * HLG10, HDR10) as result from calling [supportedDynamicRanges] and
      * [DynamicRangeProfiles.getProfileCaptureRequestConstraints]
      * returns (STANDARD, HLG10) when given an argument
      * of STANDARD. This means that the corresponding camera device will only accept and process
@@ -50,21 +54,12 @@
      * @param dynamicRange The dynamic range that will be checked for constraints
      * @return non-modifiable set of dynamic ranges
      * @throws IllegalArgumentException If the dynamic range argument is not within the set
-     * returned by [getSupportedDynamicRanges].
+     * returned by [supportedDynamicRanges].
      */
     fun getDynamicRangeCaptureRequestConstraints(
         dynamicRange: DynamicRange
     ): Set<DynamicRange> {
-        return mImpl.getDynamicRangeCaptureRequestConstraints(dynamicRange)
-    }
-
-    /**
-     * Returns a set of supported dynamic ranges.
-     *
-     * @return a non-modifiable set of dynamic ranges.
-     */
-    fun getSupportedDynamicRanges(): Set<DynamicRange> {
-        return mImpl.getSupportedDynamicRanges()
+        return impl.getDynamicRangeCaptureRequestConstraints(dynamicRange)
     }
 
     /**
@@ -80,10 +75,10 @@
      * @return `true` if the given profile is not suitable for latency sensitive use cases,
      * `false` otherwise.
      * @throws IllegalArgumentException If the dynamic range argument is not within the set
-     * returned by [getSupportedDynamicRanges].
+     * returned by [supportedDynamicRanges].
      */
     fun isExtraLatencyPresent(dynamicRange: DynamicRange): Boolean {
-        return mImpl.isExtraLatencyPresent(dynamicRange)
+        return impl.isExtraLatencyPresent(dynamicRange)
     }
 
     /**
@@ -99,16 +94,15 @@
             33, "DynamicRangesCompat can only be " +
                 "converted to DynamicRangeProfiles on API 33 or higher."
         )
-        return mImpl.unwrap()
+        return impl.unwrap()
     }
 
     internal interface DynamicRangeProfilesCompatImpl {
+        val supportedDynamicRanges: Set<DynamicRange>
         fun getDynamicRangeCaptureRequestConstraints(
             dynamicRange: DynamicRange
         ): Set<DynamicRange>
 
-        fun getSupportedDynamicRanges(): Set<DynamicRange>
-
         fun isExtraLatencyPresent(dynamicRange: DynamicRange): Boolean
         fun unwrap(): DynamicRangeProfiles?
     }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatApi33Impl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatApi33Impl.kt
index 12a5687..0197afe 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatApi33Impl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatApi33Impl.kt
@@ -26,6 +26,10 @@
 internal class DynamicRangeProfilesCompatApi33Impl(
     private val dynamicRangeProfiles: DynamicRangeProfiles
 ) : DynamicRangeProfilesCompat.DynamicRangeProfilesCompatImpl {
+    override val supportedDynamicRanges: Set<DynamicRange>
+        get() = profileSetToDynamicRangeSet(
+            dynamicRangeProfiles.supportedProfiles
+        )
 
     override fun getDynamicRangeCaptureRequestConstraints(
         dynamicRange: DynamicRange
@@ -39,10 +43,6 @@
         )
     }
 
-    override fun getSupportedDynamicRanges() = profileSetToDynamicRangeSet(
-        dynamicRangeProfiles.supportedProfiles
-    )
-
     override fun isExtraLatencyPresent(dynamicRange: DynamicRange): Boolean {
         val dynamicRangeProfile = dynamicRangeToFirstSupportedProfile(dynamicRange)
         require(
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatBaseImpl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatBaseImpl.kt
index b9a0cad..2d5cc50 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatBaseImpl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatBaseImpl.kt
@@ -24,6 +24,9 @@
 @RequiresApi(21)
 internal class DynamicRangeProfilesCompatBaseImpl :
     DynamicRangeProfilesCompat.DynamicRangeProfilesCompatImpl {
+    override val supportedDynamicRanges: Set<DynamicRange>
+        get() = SDR_ONLY
+
     override fun getDynamicRangeCaptureRequestConstraints(
         dynamicRange: DynamicRange
     ): Set<DynamicRange> {
@@ -34,10 +37,6 @@
         return SDR_ONLY
     }
 
-    override fun getSupportedDynamicRanges(): Set<DynamicRange> {
-        return SDR_ONLY
-    }
-
     override fun isExtraLatencyPresent(dynamicRange: DynamicRange): Boolean {
         Preconditions.checkArgument(
             DynamicRange.SDR == dynamicRange,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeResolver.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeResolver.kt
index 947d31c..7871614 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeResolver.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeResolver.kt
@@ -54,7 +54,7 @@
         }
 
         // Get the supported dynamic ranges from the device
-        val supportedDynamicRanges = dynamicRangesInfo.getSupportedDynamicRanges()
+        val supportedDynamicRanges = dynamicRangesInfo.supportedDynamicRanges
 
         // Collect initial dynamic range constraints. This set will potentially shrink as we add
         // more dynamic ranges. We start with the initial set of supported dynamic ranges to
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt
index e845092..d352ea7 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapterTest.kt
@@ -24,6 +24,8 @@
 import android.util.Range
 import android.util.Size
 import androidx.camera.camera2.pipe.integration.impl.ZoomControl
+import androidx.camera.camera2.pipe.integration.internal.DOLBY_VISION_10B_UNCONSTRAINED
+import androidx.camera.camera2.pipe.integration.internal.HLG10_UNCONSTRAINED
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraInfoAdapterCreator.createCameraInfoAdapter
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraInfoAdapterCreator.useCaseThreads
 import androidx.camera.camera2.pipe.integration.testing.FakeCameraProperties
@@ -31,6 +33,12 @@
 import androidx.camera.camera2.pipe.integration.testing.FakeZoomCompat
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
 import androidx.camera.core.CameraInfo
+import androidx.camera.core.DynamicRange
+import androidx.camera.core.DynamicRange.DOLBY_VISION_10_BIT
+import androidx.camera.core.DynamicRange.DOLBY_VISION_8_BIT
+import androidx.camera.core.DynamicRange.HDR10_10_BIT
+import androidx.camera.core.DynamicRange.HDR10_PLUS_10_BIT
+import androidx.camera.core.DynamicRange.HLG_10_BIT
 import androidx.camera.core.FocusMeteringAction
 import androidx.camera.core.SurfaceOrientedMeteringPointFactory
 import androidx.camera.core.ZoomState
@@ -256,4 +264,131 @@
 
         assertThat(cameraInfo.isVideoStabilizationSupported).isFalse()
     }
+
+    // Analog to Camera2CameraInfoImplTest#apiVersionMet_canReturnSupportedHdrDynamicRanges()
+    @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    fun cameraInfo_hdrDynamicRangeSupported() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter(
+            cameraProperties = FakeCameraProperties(
+                FakeCameraMetadata(
+                    characteristics = mapOf(
+                        CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES to
+                            HLG10_UNCONSTRAINED
+                    )
+                )
+            )
+        )
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(
+            setOf(
+                HLG_10_BIT, HDR10_10_BIT, HDR10_PLUS_10_BIT, DOLBY_VISION_10_BIT, DOLBY_VISION_8_BIT
+            )
+        )).containsExactly(HLG_10_BIT)
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(
+            setOf(DynamicRange.HDR_UNSPECIFIED_10_BIT)
+        )).containsExactly(HLG_10_BIT)
+    }
+
+    @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    fun cameraInfo_tenBitHdrDynamicRangeSupported_whenAlsoQuerying8Bit() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter(
+            cameraProperties = FakeCameraProperties(
+                FakeCameraMetadata(
+                    characteristics = mapOf(
+                        CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES to
+                            DOLBY_VISION_10B_UNCONSTRAINED
+                    )
+                )
+            )
+        )
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(
+            setOf(DOLBY_VISION_10_BIT, DOLBY_VISION_8_BIT)
+        )).containsExactly(DOLBY_VISION_10_BIT)
+    }
+
+    // Analog to Camera2CameraInfoImplTest#apiVersionMet_canReturnSupportedDynamicRanges()
+    @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    fun cameraInfo_returnsAllSupportedDynamicRanges_whenQueryingWithUnspecified() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter(
+            cameraProperties = FakeCameraProperties(
+                FakeCameraMetadata(
+                    characteristics = mapOf(
+                        CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES to
+                            HLG10_UNCONSTRAINED
+                    )
+                )
+            )
+        )
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(
+            setOf(DynamicRange.UNSPECIFIED)
+        )).containsExactly(DynamicRange.SDR, HLG_10_BIT)
+    }
+
+    // Analog to
+    // Camera2CameraInfoImplTest#apiVersionMet_canReturnSupportedDynamicRanges_fromFullySpecified()
+    @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    fun cameraInfo_hdrAndSdrDynamicRangesSupported_whenQueryingWithFullySpecified() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter(
+            cameraProperties = FakeCameraProperties(
+                FakeCameraMetadata(
+                    characteristics = mapOf(
+                        CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES to
+                            HLG10_UNCONSTRAINED
+                    )
+                )
+            )
+        )
+
+        assertThat(
+            cameraInfo.querySupportedDynamicRanges(
+                setOf(
+                    DynamicRange.SDR,
+                    HLG_10_BIT
+                )
+            )
+        ).containsExactly(DynamicRange.SDR, HLG_10_BIT)
+    }
+
+    // Analog to Camera2CameraInfoImplTest#apiVersionNotMet_canReturnSupportedDynamicRanges()
+    @Test
+    fun cameraInfo_queryUnspecifiedDynamicRangeSupported() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter()
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(
+            setOf(DynamicRange.UNSPECIFIED))).containsExactly(DynamicRange.SDR)
+    }
+
+    // Analog to Camera2CameraInfoImplTest#apiVersionNotMet_queryHdrDynamicRangeNotSupported()
+    @Test
+    fun cameraInfo_queryForHdrWhenUnsupported_returnsEmptySet() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter()
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(
+            setOf(DynamicRange.HDR_UNSPECIFIED_10_BIT))).isEmpty()
+    }
+
+    // Analog to Camera2CameraInfoImplTest#querySdrDynamicRange_alwaysSupported()
+    @Test
+    fun cameraInfo_querySdrSupported() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter()
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(setOf(DynamicRange.SDR))).containsExactly(
+            DynamicRange.SDR
+        )
+    }
+
+    // Analog to Camera2CameraInfoImplTest#queryDynamicRangeWithEmptySet_returnsEmptySet()
+    @Test
+    fun cameraInfo_queryWithEmptySet_returnsEmptySet() {
+        val cameraInfo: CameraInfo = createCameraInfoAdapter()
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(emptySet())).isEmpty()
+    }
 }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatTest.kt
index b06ab92..73172a95 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/DynamicRangeProfilesCompatTest.kt
@@ -64,7 +64,7 @@
     fun canSupportDynamicRangeFromHlg10Profile() {
         val dynamicRangeProfilesCompat =
             DynamicRangeProfilesCompat.toDynamicRangesCompat(HLG10_UNCONSTRAINED)
-        Truth.assertThat(dynamicRangeProfilesCompat?.getSupportedDynamicRanges())
+        Truth.assertThat(dynamicRangeProfilesCompat?.supportedDynamicRanges)
             .contains(DynamicRange.HLG_10_BIT)
     }
 
@@ -73,7 +73,7 @@
     fun canSupportDynamicRangeFromHdr10Profile() {
         val dynamicRangeProfilesCompat =
             DynamicRangeProfilesCompat.toDynamicRangesCompat(HDR10_UNCONSTRAINED)
-        Truth.assertThat(dynamicRangeProfilesCompat?.getSupportedDynamicRanges())
+        Truth.assertThat(dynamicRangeProfilesCompat?.supportedDynamicRanges)
             .contains(DynamicRange.HDR10_10_BIT)
     }
 
@@ -82,7 +82,7 @@
     fun canSupportDynamicRangeFromHdr10PlusProfile() {
         val dynamicRangeProfilesCompat =
             DynamicRangeProfilesCompat.toDynamicRangesCompat(HDR10_PLUS_UNCONSTRAINED)
-        Truth.assertThat(dynamicRangeProfilesCompat?.getSupportedDynamicRanges())
+        Truth.assertThat(dynamicRangeProfilesCompat?.supportedDynamicRanges)
             .contains(DynamicRange.HDR10_PLUS_10_BIT)
     }
 
@@ -91,7 +91,7 @@
     fun canSupportDynamicRangeFromDolbyVision10bProfile() {
         val dynamicRangeProfilesCompat =
             DynamicRangeProfilesCompat.toDynamicRangesCompat(DOLBY_VISION_10B_UNCONSTRAINED)
-        Truth.assertThat(dynamicRangeProfilesCompat?.getSupportedDynamicRanges())
+        Truth.assertThat(dynamicRangeProfilesCompat?.supportedDynamicRanges)
             .contains(DynamicRange.DOLBY_VISION_10_BIT)
     }
 
@@ -100,7 +100,7 @@
     fun canSupportDynamicRangeFromDolbyVision8bProfile() {
         val dynamicRangeProfilesCompat =
             DynamicRangeProfilesCompat.toDynamicRangesCompat(DOLBY_VISION_8B_UNCONSTRAINED)
-        Truth.assertThat(dynamicRangeProfilesCompat?.getSupportedDynamicRanges())
+        Truth.assertThat(dynamicRangeProfilesCompat?.supportedDynamicRanges)
             .contains(DynamicRange.DOLBY_VISION_8_BIT)
     }
 
@@ -203,7 +203,7 @@
         val dynamicRangeProfilesCompat =
             DynamicRangeProfilesCompat.fromCameraMetaData(cameraMetadata)
 
-        Truth.assertThat(dynamicRangeProfilesCompat.getSupportedDynamicRanges())
+        Truth.assertThat(dynamicRangeProfilesCompat.supportedDynamicRanges)
             .containsExactly(DynamicRange.SDR)
         Truth.assertThat(
             dynamicRangeProfilesCompat.getDynamicRangeCaptureRequestConstraints(DynamicRange.SDR)
@@ -225,10 +225,10 @@
             DynamicRangeProfilesCompat.fromCameraMetaData(cameraMetadata)
 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
-            Truth.assertThat(dynamicRangeProfilesCompat.getSupportedDynamicRanges())
+            Truth.assertThat(dynamicRangeProfilesCompat.supportedDynamicRanges)
                 .containsExactly(DynamicRange.SDR)
         } else {
-            Truth.assertThat(dynamicRangeProfilesCompat.getSupportedDynamicRanges())
+            Truth.assertThat(dynamicRangeProfilesCompat.supportedDynamicRanges)
                 .containsExactly(
                     DynamicRange.SDR, DynamicRange.DOLBY_VISION_8_BIT
                 )
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeTestCases.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeTestCases.kt
index bcaae5a..9f2b153 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeTestCases.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/internal/DynamicRangeTestCases.kt
@@ -27,7 +27,7 @@
 import androidx.annotation.RequiresApi
 
 val HLG10_UNCONSTRAINED by lazy {
-    DynamicRangeProfiles(longArrayOf(HLG10, 0, 0))
+    DynamicRangeProfiles(longArrayOf(HLG10, CONSTRAINTS_NONE, LATENCY_NONE))
 }
 
 val HLG10_CONSTRAINED by lazy {
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeImage.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeImage.kt
index c579ad3..3a38d47 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeImage.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeImage.kt
@@ -16,8 +16,6 @@
 
 package androidx.camera.camera2.pipe.testing
 
-import android.os.Build
-import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.media.ImagePlane
 import androidx.camera.camera2.pipe.media.ImageWrapper
 import kotlin.reflect.KClass
@@ -26,7 +24,6 @@
 /**
  * FakeImage that can be used for testing classes that accept [ImageWrapper].
  */
-@RequiresApi(Build.VERSION_CODES.KITKAT)
 class FakeImage(
     override val width: Int,
     override val height: Int,
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
index 396ace8..1726cce 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExternalRequestProcessor.kt
@@ -138,9 +138,12 @@
         )
     }
 
-    override fun submit(captureSequence: ExternalCaptureSequence): Int {
-        check(!closed.value)
+    override fun submit(captureSequence: ExternalCaptureSequence): Int? {
         check(captureSequence.captureRequestList.isNotEmpty())
+        if (closed.value) {
+            Log.warn { "Cannot submit $captureSequence because $this is closed" }
+            return null
+        }
 
         if (captureSequence.repeating) {
             check(captureSequence.captureRequestList.size == 1)
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/ImageWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/ImageWrapper.kt
index 6ccedd7..923652f 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/ImageWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/ImageWrapper.kt
@@ -16,15 +16,12 @@
 
 package androidx.camera.camera2.pipe.media
 
-import android.os.Build
-import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.UnsafeWrapper
 import java.nio.ByteBuffer
 
 /**
  * Wrapper interfaces that mirrors the primary read-only properties of {@link android.media.Image}.
  */
-@RequiresApi(Build.VERSION_CODES.KITKAT)
 interface ImageWrapper : UnsafeWrapper, AutoCloseable {
     /**
      * @see {@link android.media.Image.getWidth}
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/OutputImage.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/OutputImage.kt
index 5ef904c..98c6d0d 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/OutputImage.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/media/OutputImage.kt
@@ -16,8 +16,6 @@
 
 package androidx.camera.camera2.pipe.media
 
-import android.os.Build
-import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.OutputId
 import androidx.camera.camera2.pipe.StreamId
 import kotlin.reflect.KClass
@@ -26,7 +24,6 @@
  * An OutputImage is a reference to an [ImageWrapper] that was produced from CameraPipe for a
  * specific [StreamId]/[OutputId] combination.
  */
-@RequiresApi(Build.VERSION_CODES.KITKAT)
 interface OutputImage : ImageWrapper {
     val streamId: StreamId
     val outputId: OutputId
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/CaptureSessionTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/CaptureSessionTest.java
index bfb685b..9e116f4 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/CaptureSessionTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/CaptureSessionTest.java
@@ -24,7 +24,6 @@
 import static android.hardware.DataSpace.TRANSFER_SMPTE_170M;
 import static android.hardware.DataSpace.TRANSFER_SRGB;
 import static android.hardware.DataSpace.TRANSFER_UNSPECIFIED;
-import static android.os.Build.VERSION.SDK_INT;
 
 import static androidx.camera.core.DynamicRange.HLG_10_BIT;
 
@@ -114,9 +113,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
-import org.junit.runner.Description;
 import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
@@ -194,26 +191,9 @@
 
     @Rule
     public TestRule getUseCameraRule() {
-        if (SDK_INT >= 19) {
-            return CameraUtil.grantCameraPermissionAndPreTest(
-                    new CameraUtil.PreTestCameraIdList(Camera2Config.defaultConfig())
-            );
-        } else {
-            // Camera2Config.defaultConfig() requires API 19, so returning
-            // a noop rule so it doesn't crash when run on API <19
-            return new NoopRule();
-        }
-    }
-
-    public static class NoopRule implements TestRule {
-        @NonNull
-        @Override
-        public Statement apply(@NonNull Statement base, @NonNull Description description) {
-            return new Statement() {
-                @Override
-                public void evaluate() {}
-            };
-        }
+        return CameraUtil.grantCameraPermissionAndPreTest(
+                new CameraUtil.PreTestCameraIdList(Camera2Config.defaultConfig())
+        );
     }
 
     @BeforeClass
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java
index 9016fda..25f1192 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControlImpl.java
@@ -736,12 +736,24 @@
      * <p><pre>If preferredMode is not supported, fallback with the following priority (highest to
      * lowest).
      * 1) {@link CaptureRequest#CONTROL_AE_MODE_ON}
-     * 2) {@link CaptureRequest#CONTROL_AE_MODE_OFF)}
+     * 2) {@link CaptureRequest#CONTROL_AE_MODE_OFF}
      * </pre>
      */
     @ExecutedBy("mExecutor")
     int getSupportedAeMode(int preferredMode) {
-        int[] modes = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+        return getSupportedAeMode(mCameraCharacteristics, preferredMode);
+    }
+
+    /**
+     * Returns a supported AE mode which will be preferredMode if it is supported.
+     *
+     * @see #getSupportedAeMode(int preferredMode)
+     */
+    public static int getSupportedAeMode(
+            @NonNull CameraCharacteristicsCompat cameraCharacteristics,
+            int preferredMode
+    ) {
+        int[] modes = cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
 
         if (modes == null) {
             return CaptureRequest.CONTROL_AE_MODE_OFF;
@@ -791,7 +803,7 @@
     }
 
     @ExecutedBy("mExecutor")
-    private boolean isModeInList(int mode, int[] modeList) {
+    private static boolean isModeInList(int mode, int[] modeList) {
         for (int m : modeList) {
             if (mode == m) {
                 return true;
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
index ffffd60..5dd2cf2 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraInfoImpl.java
@@ -59,6 +59,7 @@
 import androidx.camera.core.ZoomState;
 import androidx.camera.core.impl.CameraCaptureCallback;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.core.impl.DynamicRanges;
 import androidx.camera.core.impl.EncoderProfilesProvider;
 import androidx.camera.core.impl.ImageOutputConfig.RotationValue;
 import androidx.camera.core.impl.Quirks;
@@ -451,6 +452,14 @@
         return dynamicRangesCompat.getSupportedDynamicRanges();
     }
 
+    @NonNull
+    @Override
+    public Set<DynamicRange> querySupportedDynamicRanges(
+            @NonNull Set<DynamicRange> candidateDynamicRanges) {
+        return DynamicRanges.findAllPossibleMatches(candidateDynamicRanges,
+                getSupportedDynamicRanges());
+    }
+
     @Override
     public void addSessionCaptureCallback(@NonNull Executor executor,
             @NonNull CameraCaptureCallback callback) {
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
index 57e535d..a77732e 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
@@ -47,6 +47,7 @@
 import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
 import androidx.camera.camera2.internal.compat.workaround.FlashAvailabilityChecker;
 import androidx.camera.camera2.internal.compat.workaround.OverrideAeModeForStillCapture;
+import androidx.camera.camera2.internal.compat.workaround.UseFlashModeTorchFor3aUpdate;
 import androidx.camera.camera2.internal.compat.workaround.UseTorchAsFlash;
 import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
 import androidx.camera.core.ImageCapture;
@@ -199,7 +200,8 @@
         }
 
         if (flashMode == FLASH_MODE_SCREEN) {
-            pipeline.addTask(new ScreenFlashTask(mCameraControl, mExecutor, mScheduler));
+            pipeline.addTask(new ScreenFlashTask(mCameraControl, mExecutor, mScheduler,
+                    new UseFlashModeTorchFor3aUpdate(mCameraQuirk)));
         } else {
             if (mHasFlashUnit) {
                 if (isTorchAsFlash(flashType)) {
@@ -685,12 +687,15 @@
         private final Executor mExecutor;
         private final ScheduledExecutorService mScheduler;
         private final ImageCapture.ScreenFlashUiControl mScreenFlashUiControl;
+        private final UseFlashModeTorchFor3aUpdate mUseFlashModeTorchFor3aUpdate;
 
-        ScreenFlashTask(@NonNull Camera2CameraControlImpl cameraControl,
-                @NonNull Executor executor, @NonNull ScheduledExecutorService scheduler) {
+        ScreenFlashTask(@NonNull Camera2CameraControlImpl cameraControl, @NonNull Executor executor,
+                @NonNull ScheduledExecutorService scheduler,
+                @NonNull UseFlashModeTorchFor3aUpdate useFlashModeTorchFor3aUpdate) {
             mCameraControl = cameraControl;
             mExecutor = executor;
             mScheduler = scheduler;
+            mUseFlashModeTorchFor3aUpdate = useFlashModeTorchFor3aUpdate;
 
             mScreenFlashUiControl =
                     Objects.requireNonNull(mCameraControl.getScreenFlashUiControl());
@@ -728,11 +733,13 @@
                             true),
                     mExecutor
             ).transformAsync(
-                    // Won't have any effect if CONTROL_AE_MODE_ON_EXTERNAL_FLASH is supported
                     input -> CallbackToFutureAdapter.getFuture(
                             completer -> {
+                                if (!mUseFlashModeTorchFor3aUpdate.shouldUseFlashModeTorch()) {
+                                    completer.set(null);
+                                    return "EnableTorchInternal";
+                                }
                                 Logger.d(TAG, "ScreenFlashTask#preCapture: enable torch");
-                                // TODO: Enable torch only if actual flash unit doesn't exist
                                 mCameraControl.enableTorchInternal(true);
                                 completer.set(null);
                                 return "EnableTorchInternal";
@@ -763,7 +770,9 @@
         @Override
         public void postCapture() {
             Logger.d(TAG, "ScreenFlashTask#postCapture");
-            mCameraControl.enableTorchInternal(false);
+            if (mUseFlashModeTorchFor3aUpdate.shouldUseFlashModeTorch()) {
+                mCameraControl.enableTorchInternal(false);
+            }
             mCameraControl.getFocusMeteringControl().enableExternalFlashAeMode(false).addListener(
                     () -> Log.d(TAG, "enableExternalFlashAeMode disabled"), mExecutor
             );
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/ProcessingCaptureSession.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/ProcessingCaptureSession.java
index a95a720..cfba49c 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/ProcessingCaptureSession.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/ProcessingCaptureSession.java
@@ -425,49 +425,41 @@
         updateParameters(mSessionOptions, mStillCaptureOptions);
         mSessionProcessor.startCapture(captureConfig.isPostviewEnabled(),
                 new SessionProcessor.CaptureCallback() {
-            @Override
-            public void onCaptureStarted(int captureSequenceId, long timestamp) {
-                mExecutor.execute(() -> {
-                    for (CameraCaptureCallback cameraCaptureCallback :
-                            captureConfig.getCameraCaptureCallbacks()) {
-                        cameraCaptureCallback.onCaptureStarted();
+                    @Override
+                    public void onCaptureStarted(int captureSequenceId, long timestamp) {
+                        for (CameraCaptureCallback cameraCaptureCallback :
+                                captureConfig.getCameraCaptureCallbacks()) {
+                            cameraCaptureCallback.onCaptureStarted();
+                        }
                     }
-                });
-            }
 
-            @Override
-            public void onCaptureFailed(
-                    int captureSequenceId) {
-                mExecutor.execute(() -> {
-                    for (CameraCaptureCallback cameraCaptureCallback :
-                            captureConfig.getCameraCaptureCallbacks()) {
-                        cameraCaptureCallback.onCaptureFailed(new CameraCaptureFailure(
-                                CameraCaptureFailure.Reason.ERROR));
+                    @Override
+                    public void onCaptureFailed(
+                            int captureSequenceId) {
+                        for (CameraCaptureCallback cameraCaptureCallback :
+                                captureConfig.getCameraCaptureCallbacks()) {
+                            cameraCaptureCallback.onCaptureFailed(new CameraCaptureFailure(
+                                    CameraCaptureFailure.Reason.ERROR));
+                        }
                     }
-                });
-            }
 
-            @Override
-            public void onCaptureSequenceCompleted(int captureSequenceId) {
-                mExecutor.execute(() -> {
-                    for (CameraCaptureCallback cameraCaptureCallback :
-                            captureConfig.getCameraCaptureCallbacks()) {
-                        cameraCaptureCallback.onCaptureCompleted(
-                                new CameraCaptureResult.EmptyCameraCaptureResult());
+                    @Override
+                    public void onCaptureSequenceCompleted(int captureSequenceId) {
+                        for (CameraCaptureCallback cameraCaptureCallback :
+                                captureConfig.getCameraCaptureCallbacks()) {
+                            cameraCaptureCallback.onCaptureCompleted(
+                                    new CameraCaptureResult.EmptyCameraCaptureResult());
+                        }
                     }
-                });
-            }
 
-            @Override
-            public void onCaptureProcessProgressed(int progress) {
-                mExecutor.execute(() -> {
-                    for (CameraCaptureCallback cameraCaptureCallback :
-                            captureConfig.getCameraCaptureCallbacks()) {
-                        cameraCaptureCallback.onCaptureProcessProgressed(progress);
+                    @Override
+                    public void onCaptureProcessProgressed(int progress) {
+                        for (CameraCaptureCallback cameraCaptureCallback :
+                                captureConfig.getCameraCaptureCallbacks()) {
+                            cameraCaptureCallback.onCaptureProcessProgressed(progress);
+                        }
                     }
                 });
-            }
-        });
     }
 
     /**
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java
index a185882..efffb01 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java
@@ -97,6 +97,9 @@
         if (IncorrectCaptureStateQuirk.load(cameraCharacteristicsCompat)) {
             quirks.add(new IncorrectCaptureStateQuirk());
         }
+        if (TorchFlashRequiredFor3aUpdateQuirk.load(cameraCharacteristicsCompat)) {
+            quirks.add(new TorchFlashRequiredFor3aUpdateQuirk(cameraCharacteristicsCompat));
+        }
 
         return new Quirks(quirks);
     }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/TorchFlashRequiredFor3aUpdateQuirk.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/TorchFlashRequiredFor3aUpdateQuirk.java
new file mode 100644
index 0000000..9da886f
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/TorchFlashRequiredFor3aUpdateQuirk.java
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+package androidx.camera.camera2.internal.compat.quirk;
+
+import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT;
+
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureRequest;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.camera.camera2.internal.Camera2CameraControlImpl;
+import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
+import androidx.camera.core.impl.Quirk;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * <p>QuirkSummary
+ *     Bug Id: 294870640
+ *     Description: Quirk denoting the devices where {@link CaptureRequest#FLASH_MODE_TORCH} has
+ *                  to be set for 3A states to be updated with good values (in some cases, AWB
+ *                  scanning is not triggered at all). This results in problems like color tint
+ *                  or bad exposure in captured image during captures where lighting condition
+ *                  changes (e.g. screen flash capture). This maybe required even if a flash unit
+ *                  is not available (e.g. with front camera) and
+ *                  {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER} has been requested. If
+ *                  {@link CaptureRequest#CONTROL_AE_MODE_ON_EXTERNAL_FLASH} is supported, it can
+ *                  be used instead and thus setting {@code FLASH_MODE_TORCH} won't be required.
+ *     Device(s): Pixel 6A, 6 PRO, 7, 7A, 7 PRO, 8, 8 PRO
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+public class TorchFlashRequiredFor3aUpdateQuirk implements Quirk {
+    private static final List<String> AFFECTED_PIXEL_MODELS = Arrays.asList(
+            "PIXEL 6A",
+            "PIXEL 6 PRO",
+            "PIXEL 7",
+            "PIXEL 7A",
+            "PIXEL 7 PRO",
+            "PIXEL 8",
+            "PIXEL 8 PRO"
+    );
+
+    @NonNull
+    private final CameraCharacteristicsCompat mCameraCharacteristics;
+
+    public TorchFlashRequiredFor3aUpdateQuirk(
+            @NonNull CameraCharacteristicsCompat cameraCharacteristics) {
+        mCameraCharacteristics = cameraCharacteristics;
+    }
+
+    /**
+     * Checks if the quirk should be loaded based on device model info and camera lens facing.
+     */
+    static boolean load(@NonNull CameraCharacteristicsCompat cameraCharacteristics) {
+        return isAffectedModel(cameraCharacteristics);
+    }
+
+    /**
+     * Returns whether {@link CaptureRequest#FLASH_MODE_TORCH} is required to be set.
+     *
+     * <p> This will also check if the {@link CaptureRequest#CONTROL_AE_MODE_ON_EXTERNAL_FLASH} is
+     * supported, which is more recommended than using a quirk like using {@code FLASH_MODE_TORCH}.
+     */
+    public boolean isFlashModeTorchRequired() {
+        return !isExternalFlashAeModeSupported(mCameraCharacteristics);
+    }
+
+    private static boolean isAffectedModel(
+            @NonNull CameraCharacteristicsCompat cameraCharacteristics) {
+        return isAffectedPixelModel() && isFrontCamera(cameraCharacteristics);
+    }
+
+    private static boolean isAffectedPixelModel() {
+        for (String model : AFFECTED_PIXEL_MODELS) {
+            if (Build.MODEL.toUpperCase(Locale.US).equals(model)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isFrontCamera(
+            @NonNull CameraCharacteristicsCompat cameraCharacteristics) {
+        return cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == LENS_FACING_FRONT;
+    }
+
+    private static boolean isExternalFlashAeModeSupported(
+            @NonNull CameraCharacteristicsCompat cameraCharacteristics
+    ) {
+        if (Build.VERSION.SDK_INT < 28) {
+            return false;
+        }
+
+        return Camera2CameraControlImpl.getSupportedAeMode(cameraCharacteristics,
+                CaptureRequest.CONTROL_AE_MODE_ON_EXTERNAL_FLASH)
+                == CaptureRequest.CONTROL_AE_MODE_ON_EXTERNAL_FLASH;
+    }
+}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/workaround/UseFlashModeTorchFor3aUpdate.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/workaround/UseFlashModeTorchFor3aUpdate.java
new file mode 100644
index 0000000..379ef3b
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/workaround/UseFlashModeTorchFor3aUpdate.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package androidx.camera.camera2.internal.compat.workaround;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.camera.camera2.internal.compat.quirk.TorchFlashRequiredFor3aUpdateQuirk;
+import androidx.camera.core.Logger;
+import androidx.camera.core.impl.Quirks;
+
+/**
+ * Workaround to use torch as flash.
+ *
+ * @see TorchFlashRequiredFor3aUpdateQuirk
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+public class UseFlashModeTorchFor3aUpdate {
+    private static final String TAG = "UseFlashModeTorchFor3aUpdate";
+
+    @Nullable
+    private final TorchFlashRequiredFor3aUpdateQuirk mTorchFlashRequiredFor3AUpdateQuirk;
+
+    public UseFlashModeTorchFor3aUpdate(@NonNull Quirks quirks) {
+        mTorchFlashRequiredFor3AUpdateQuirk = quirks.get(TorchFlashRequiredFor3aUpdateQuirk.class);
+    }
+
+    /** Returns if torch should be used as flash. */
+    public boolean shouldUseFlashModeTorch() {
+        boolean shouldUse = mTorchFlashRequiredFor3AUpdateQuirk != null
+                && mTorchFlashRequiredFor3AUpdateQuirk.isFlashModeTorchRequired();
+        Logger.d(TAG, "shouldUseFlashModeTorch: " + shouldUse);
+        return shouldUse;
+    }
+}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CameraInfoImplTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CameraInfoImplTest.java
index 8a876ca..96f94bd 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CameraInfoImplTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CameraInfoImplTest.java
@@ -20,9 +20,18 @@
 import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF;
 import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON;
 import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION;
+
+import static androidx.camera.core.DynamicRange.DOLBY_VISION_10_BIT;
+import static androidx.camera.core.DynamicRange.DOLBY_VISION_8_BIT;
+import static androidx.camera.core.DynamicRange.HDR10_10_BIT;
+import static androidx.camera.core.DynamicRange.HDR10_PLUS_10_BIT;
+import static androidx.camera.core.DynamicRange.HDR_UNSPECIFIED_10_BIT;
 import static androidx.camera.core.DynamicRange.HLG_10_BIT;
 import static androidx.camera.core.DynamicRange.SDR;
+import static androidx.camera.core.DynamicRange.UNSPECIFIED;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -77,6 +86,7 @@
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -728,13 +738,44 @@
 
     @Config(minSdk = 33)
     @Test
-    public void apiVersionMet_canReturnSupportedDynamicRanges() throws CameraAccessExceptionCompat {
+    public void apiVersionMet_canReturnOnlySupportedHdrDynamicRanges()
+            throws CameraAccessExceptionCompat {
         init(/* hasAvailableCapabilities = */ true);
 
-        final Camera2CameraInfoImpl cameraInfo = new Camera2CameraInfoImpl(
-                CAMERA0_ID, mCameraManagerCompat);
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
 
-        Set<DynamicRange> supportedDynamicRanges = cameraInfo.getSupportedDynamicRanges();
+        Set<DynamicRange> supportedDynamicRanges = cameraInfo.querySupportedDynamicRanges(
+                new HashSet<>(Arrays.asList(HLG_10_BIT, HDR10_10_BIT, HDR10_PLUS_10_BIT,
+                        DOLBY_VISION_10_BIT, DOLBY_VISION_8_BIT)));
+        assertThat(supportedDynamicRanges).containsExactly(HLG_10_BIT);
+        supportedDynamicRanges = cameraInfo.querySupportedDynamicRanges(
+                Collections.singleton(HDR_UNSPECIFIED_10_BIT));
+        assertThat(supportedDynamicRanges).containsExactly(HLG_10_BIT);
+    }
+
+    @Config(minSdk = 33)
+    @Test
+    public void apiVersionMet_canReturnSupportedDynamicRanges()
+            throws CameraAccessExceptionCompat {
+        init(/* hasAvailableCapabilities = */ true);
+
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
+
+        Set<DynamicRange> supportedDynamicRanges = cameraInfo.querySupportedDynamicRanges(
+                Collections.singleton(UNSPECIFIED));
+        assertThat(supportedDynamicRanges).containsExactly(SDR, HLG_10_BIT);
+    }
+
+    @Config(minSdk = 33)
+    @Test
+    public void apiVersionMet_canReturnSupportedDynamicRanges_fromFullySpecified()
+            throws CameraAccessExceptionCompat {
+        init(/* hasAvailableCapabilities = */ true);
+
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
+
+        Set<DynamicRange> supportedDynamicRanges = cameraInfo.querySupportedDynamicRanges(
+                new HashSet<>(Arrays.asList(SDR, HLG_10_BIT)));
         assertThat(supportedDynamicRanges).containsExactly(SDR, HLG_10_BIT);
     }
 
@@ -744,13 +785,44 @@
             throws CameraAccessExceptionCompat {
         init(/* hasAvailableCapabilities = */ true);
 
-        final Camera2CameraInfoImpl cameraInfo = new Camera2CameraInfoImpl(
-                CAMERA0_ID, mCameraManagerCompat);
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
 
-        Set<DynamicRange> supportedDynamicRanges = cameraInfo.getSupportedDynamicRanges();
+        Set<DynamicRange> supportedDynamicRanges = cameraInfo.querySupportedDynamicRanges(
+                Collections.singleton(UNSPECIFIED));
         assertThat(supportedDynamicRanges).containsExactly(SDR);
     }
 
+    @Config(maxSdk = 32)
+    @Test
+    public void apiVersionNotMet_queryHdrDynamicRangeNotSupported()
+            throws CameraAccessExceptionCompat {
+        init(/* hasAvailableCapabilities = */ true);
+
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
+
+        Set<DynamicRange> supportedDynamicRanges = cameraInfo.querySupportedDynamicRanges(
+                Collections.singleton(HDR_UNSPECIFIED_10_BIT));
+        assertThat(supportedDynamicRanges).isEmpty();
+    }
+
+    @Test
+    public void querySdrDynamicRange_alwaysSupported() throws CameraAccessExceptionCompat {
+        init(/* hasAvailableCapabilities = */ true);
+
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(Collections.singleton(SDR))).isNotEmpty();
+    }
+
+    @Test
+    public void queryDynamicRangeWithEmptySet_returnsEmptySet() throws CameraAccessExceptionCompat {
+        init(/* hasAvailableCapabilities = */ true);
+
+        final CameraInfo cameraInfo = new Camera2CameraInfoImpl(CAMERA0_ID, mCameraManagerCompat);
+
+        assertThat(cameraInfo.querySupportedDynamicRanges(Collections.emptySet())).isEmpty();
+    }
+
     private CameraManagerCompat initCameraManagerWithPhysicalIds(
             List<Pair<String, CameraCharacteristics>> cameraIdsAndCharacteristicsList) {
         FakeCameraManagerImpl cameraManagerImpl = new FakeCameraManagerImpl();
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CapturePipelineTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CapturePipelineTest.kt
index 3d5f2e0..74be647 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CapturePipelineTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/Camera2CapturePipelineTest.kt
@@ -36,6 +36,7 @@
 import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat
 import androidx.camera.camera2.internal.compat.quirk.AutoFlashUnderExposedQuirk
 import androidx.camera.camera2.internal.compat.quirk.CameraQuirks
+import androidx.camera.camera2.internal.compat.quirk.TorchFlashRequiredFor3aUpdateQuirk
 import androidx.camera.camera2.internal.compat.quirk.UseTorchAsFlashQuirk
 import androidx.camera.camera2.internal.compat.workaround.OverrideAeModeForStillCapture
 import androidx.camera.core.ImageCapture
@@ -53,6 +54,7 @@
 import androidx.camera.core.impl.CaptureConfig
 import androidx.camera.core.impl.DeferrableSurface
 import androidx.camera.core.impl.ImmediateSurface
+import androidx.camera.core.impl.Quirk
 import androidx.camera.core.impl.Quirks
 import androidx.camera.core.impl.SessionConfig
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
@@ -359,8 +361,21 @@
         screenFlash_screenFlashUiControlInvokedProperly(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
     }
 
-    private fun screenFlash_screenFlashUiControlInvokedProperly(imageCaptureMode: Int) {
-        val cameraControl = createCameraControl().apply {
+    @Test
+    fun maxQuality_screenFlashCapture_withFlashModeTorchQuirk_screenFlashTaskInvokedProperly() {
+        screenFlash_screenFlashUiControlInvokedProperly(
+            ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY,
+            addFlashModeTorchQuirk = true
+        )
+    }
+
+    private fun screenFlash_screenFlashUiControlInvokedProperly(
+        imageCaptureMode: Int,
+        addFlashModeTorchQuirk: Boolean = false
+    ) {
+        val cameraControl = createCameraControl(
+            addTorchFlashRequiredFor3aUpdateQuirk = addFlashModeTorchQuirk
+        ).apply {
             // Arrange.
             flashMode = FLASH_MODE_SCREEN
 
@@ -401,6 +416,20 @@
             }
         }
 
+        if (addFlashModeTorchQuirk) {
+            // Submit a repeating request for FLASH_MODE_TORCH
+            CountDownLatch(5).let {
+                cameraControl.simulateRepeatingResult(
+                    initialDelay = 100,
+                    period = 50,
+                    resultParameters = mapOf(CaptureResult.FLASH_MODE
+                        to CaptureResult.FLASH_MODE_TORCH),
+                    requestCountLatch = it
+                )
+                it.await(1, TimeUnit.SECONDS)
+            }
+        }
+
         // Assert, verify AE precapture is triggered
         immediateCompleteCapture.verifyRequestResult {
             it.requestContains(
@@ -1177,12 +1206,23 @@
         cameraId: String = CAMERA_ID_0,
         quirks: Quirks? = null,
         updateCallback: CameraControlInternal.ControlUpdateCallback = immediateCompleteCapture,
+        addTorchFlashRequiredFor3aUpdateQuirk: Boolean = false,
     ): Camera2CameraControlImpl {
         val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
         val characteristics = cameraManager.getCameraCharacteristics(cameraId)
         val characteristicsCompat = CameraCharacteristicsCompat
             .toCameraCharacteristicsCompat(characteristics, cameraId)
-        val cameraQuirk = quirks ?: CameraQuirks.get(cameraId, characteristicsCompat)
+        var cameraQuirk = quirks ?: CameraQuirks.get(cameraId, characteristicsCompat)
+
+        if (addTorchFlashRequiredFor3aUpdateQuirk) {
+            cameraQuirk = Quirks(cameraQuirk.getAll(Quirk::class.java).apply {
+                add(
+                    TorchFlashRequiredFor3aUpdateQuirk(
+                        characteristicsCompat
+                    )
+                )
+            })
+        }
 
         return Camera2CameraControlImpl(
             characteristicsCompat,
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/TorchFlashRequiredFor3AUpdateQuirkTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/TorchFlashRequiredFor3AUpdateQuirkTest.kt
new file mode 100644
index 0000000..c356459
--- /dev/null
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/TorchFlashRequiredFor3AUpdateQuirkTest.kt
@@ -0,0 +1,101 @@
+/*
+ * 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.camera.camera2.internal.compat.quirk
+
+import android.hardware.camera2.CameraCharacteristics
+import android.hardware.camera2.CameraMetadata.CONTROL_AE_MODE_ON
+import android.hardware.camera2.CameraMetadata.CONTROL_AE_MODE_ON_EXTERNAL_FLASH
+import android.os.Build
+import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat
+import androidx.camera.core.impl.Quirks
+import com.google.common.truth.Truth
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.ParameterizedRobolectricTestRunner
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+import org.robolectric.shadow.api.Shadow
+import org.robolectric.shadows.ShadowBuild
+import org.robolectric.shadows.ShadowCameraCharacteristics
+
+private const val CAMERA_ID_0 = "0"
+
+@RunWith(ParameterizedRobolectricTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+class TorchFlashRequiredFor3AUpdateQuirkTest(
+    private val model: String,
+    private val lensFacing: Int,
+    private val externalFlashAeModeSupported: Boolean,
+    private val enabled: Boolean
+) {
+    companion object {
+        @JvmStatic
+        @ParameterizedRobolectricTestRunner.Parameters(
+            name = "Model: {0}, lens facing: {1}, external ae mode: {2}, enabled: {3}"
+        )
+        fun data() = listOf(
+            arrayOf("Pixel 3a", CameraCharacteristics.LENS_FACING_FRONT, false, false),
+            arrayOf("Pixel 4", CameraCharacteristics.LENS_FACING_FRONT, true, false),
+            arrayOf("Pixel 6", CameraCharacteristics.LENS_FACING_FRONT, false, false),
+            arrayOf("Pixel 6A", CameraCharacteristics.LENS_FACING_BACK, false, false),
+            arrayOf("Pixel 6A", CameraCharacteristics.LENS_FACING_FRONT, false, true),
+            arrayOf("Pixel 7 pro", CameraCharacteristics.LENS_FACING_FRONT, false, true),
+            arrayOf("Pixel 8", CameraCharacteristics.LENS_FACING_FRONT, false, true),
+            arrayOf("SM-A320FL", CameraCharacteristics.LENS_FACING_FRONT, false, false),
+        )
+    }
+
+    private fun getCameraQuirks(
+        lensFacing: Int,
+        externalFlashAeModeSupported: Boolean,
+    ): Quirks {
+        val characteristics = ShadowCameraCharacteristics.newCameraCharacteristics()
+        val shadowCharacteristics = Shadow.extract<ShadowCameraCharacteristics>(characteristics)
+        shadowCharacteristics.set(
+            CameraCharacteristics.LENS_FACING,
+            lensFacing
+        )
+        shadowCharacteristics.set(
+            CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES,
+            if (externalFlashAeModeSupported) {
+                intArrayOf(CONTROL_AE_MODE_ON_EXTERNAL_FLASH)
+            } else intArrayOf(
+                CONTROL_AE_MODE_ON
+            )
+        )
+        val characteristicsCompat =
+            CameraCharacteristicsCompat.toCameraCharacteristicsCompat(characteristics, CAMERA_ID_0)
+        return CameraQuirks.get(CAMERA_ID_0, characteristicsCompat)
+    }
+
+    @Test
+    fun canEnableQuirkCorrectly() {
+        // Arrange
+        ShadowBuild.setModel(model)
+
+        // Act
+        val cameraQuirks = getCameraQuirks(lensFacing, externalFlashAeModeSupported)
+
+        // Verify
+        Truth.assertThat(
+            cameraQuirks.get(
+                TorchFlashRequiredFor3aUpdateQuirk::class.java
+            )?.isFlashModeTorchRequired ?: false
+        ).isEqualTo(enabled)
+    }
+}
diff --git a/camera/camera-core/api/current.txt b/camera/camera-core/api/current.txt
index 57be5be..4a977b9 100644
--- a/camera/camera-core/api/current.txt
+++ b/camera/camera-core/api/current.txt
@@ -288,11 +288,14 @@
   @RequiresApi(21) public final class ImageCapture extends androidx.camera.core.UseCase {
     method public int getCaptureMode();
     method public int getFlashMode();
+    method public static androidx.camera.core.ImageCaptureCapabilities getImageCaptureCapabilities(androidx.camera.core.CameraInfo);
     method @IntRange(from=1, to=100) public int getJpegQuality();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getPostviewResolutionSelector();
     method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
     method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
     method public androidx.camera.core.ImageCapture.ScreenFlashUiControl? getScreenFlashUiControl();
     method public int getTargetRotation();
+    method public boolean isPostviewEnabled();
     method public void setCropAspectRatio(android.util.Rational);
     method public void setFlashMode(int);
     method public void setScreenFlashUiControl(androidx.camera.core.ImageCapture.ScreenFlashUiControl?);
@@ -321,6 +324,8 @@
     method public androidx.camera.core.ImageCapture.Builder setFlashMode(int);
     method public androidx.camera.core.ImageCapture.Builder setIoExecutor(java.util.concurrent.Executor);
     method public androidx.camera.core.ImageCapture.Builder setJpegQuality(@IntRange(from=1, to=100) int);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewEnabled(boolean);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
     method public androidx.camera.core.ImageCapture.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
     method public androidx.camera.core.ImageCapture.Builder setScreenFlashUiControl(androidx.camera.core.ImageCapture.ScreenFlashUiControl);
     method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetAspectRatio(int);
@@ -341,15 +346,19 @@
 
   public abstract static class ImageCapture.OnImageCapturedCallback {
     ctor public ImageCapture.OnImageCapturedCallback();
+    method public void onCaptureProcessProgressed(int);
     method public void onCaptureStarted();
     method public void onCaptureSuccess(androidx.camera.core.ImageProxy);
     method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onPostviewBitmapAvailable(android.graphics.Bitmap);
   }
 
   public static interface ImageCapture.OnImageSavedCallback {
+    method public default void onCaptureProcessProgressed(int);
     method public default void onCaptureStarted();
     method public void onError(androidx.camera.core.ImageCaptureException);
     method public void onImageSaved(androidx.camera.core.ImageCapture.OutputFileResults);
+    method public default void onPostviewBitmapAvailable(android.graphics.Bitmap);
   }
 
   public static final class ImageCapture.OutputFileOptions {
@@ -376,6 +385,11 @@
     method @UiThread public void clearScreenFlashUi();
   }
 
+  public interface ImageCaptureCapabilities {
+    method public boolean isCaptureProcessProgressSupported();
+    method public boolean isPostviewSupported();
+  }
+
   @RequiresApi(21) public class ImageCaptureException extends java.lang.Exception {
     ctor public ImageCaptureException(int, String, Throwable?);
     method public int getImageCaptureError();
@@ -491,6 +505,7 @@
 
   public interface SurfaceOutput extends java.io.Closeable {
     method public void close();
+    method public default android.graphics.Matrix getSensorToBufferTransform();
     method public android.util.Size getSize();
     method public android.view.Surface getSurface(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceOutput.Event!>);
     method public int getTargets();
@@ -531,7 +546,10 @@
 
   @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.TransformationInfo {
     method public abstract android.graphics.Rect getCropRect();
+    method public abstract boolean getMirroring();
     method public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract boolean hasCameraTransform();
   }
 
   public static interface SurfaceRequest.TransformationInfoListener {
diff --git a/camera/camera-core/api/restricted_current.txt b/camera/camera-core/api/restricted_current.txt
index 57be5be..4a977b9 100644
--- a/camera/camera-core/api/restricted_current.txt
+++ b/camera/camera-core/api/restricted_current.txt
@@ -288,11 +288,14 @@
   @RequiresApi(21) public final class ImageCapture extends androidx.camera.core.UseCase {
     method public int getCaptureMode();
     method public int getFlashMode();
+    method public static androidx.camera.core.ImageCaptureCapabilities getImageCaptureCapabilities(androidx.camera.core.CameraInfo);
     method @IntRange(from=1, to=100) public int getJpegQuality();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getPostviewResolutionSelector();
     method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
     method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
     method public androidx.camera.core.ImageCapture.ScreenFlashUiControl? getScreenFlashUiControl();
     method public int getTargetRotation();
+    method public boolean isPostviewEnabled();
     method public void setCropAspectRatio(android.util.Rational);
     method public void setFlashMode(int);
     method public void setScreenFlashUiControl(androidx.camera.core.ImageCapture.ScreenFlashUiControl?);
@@ -321,6 +324,8 @@
     method public androidx.camera.core.ImageCapture.Builder setFlashMode(int);
     method public androidx.camera.core.ImageCapture.Builder setIoExecutor(java.util.concurrent.Executor);
     method public androidx.camera.core.ImageCapture.Builder setJpegQuality(@IntRange(from=1, to=100) int);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewEnabled(boolean);
+    method public androidx.camera.core.ImageCapture.Builder setPostviewResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
     method public androidx.camera.core.ImageCapture.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
     method public androidx.camera.core.ImageCapture.Builder setScreenFlashUiControl(androidx.camera.core.ImageCapture.ScreenFlashUiControl);
     method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetAspectRatio(int);
@@ -341,15 +346,19 @@
 
   public abstract static class ImageCapture.OnImageCapturedCallback {
     ctor public ImageCapture.OnImageCapturedCallback();
+    method public void onCaptureProcessProgressed(int);
     method public void onCaptureStarted();
     method public void onCaptureSuccess(androidx.camera.core.ImageProxy);
     method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onPostviewBitmapAvailable(android.graphics.Bitmap);
   }
 
   public static interface ImageCapture.OnImageSavedCallback {
+    method public default void onCaptureProcessProgressed(int);
     method public default void onCaptureStarted();
     method public void onError(androidx.camera.core.ImageCaptureException);
     method public void onImageSaved(androidx.camera.core.ImageCapture.OutputFileResults);
+    method public default void onPostviewBitmapAvailable(android.graphics.Bitmap);
   }
 
   public static final class ImageCapture.OutputFileOptions {
@@ -376,6 +385,11 @@
     method @UiThread public void clearScreenFlashUi();
   }
 
+  public interface ImageCaptureCapabilities {
+    method public boolean isCaptureProcessProgressSupported();
+    method public boolean isPostviewSupported();
+  }
+
   @RequiresApi(21) public class ImageCaptureException extends java.lang.Exception {
     ctor public ImageCaptureException(int, String, Throwable?);
     method public int getImageCaptureError();
@@ -491,6 +505,7 @@
 
   public interface SurfaceOutput extends java.io.Closeable {
     method public void close();
+    method public default android.graphics.Matrix getSensorToBufferTransform();
     method public android.util.Size getSize();
     method public android.view.Surface getSurface(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceOutput.Event!>);
     method public int getTargets();
@@ -531,7 +546,10 @@
 
   @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.TransformationInfo {
     method public abstract android.graphics.Rect getCropRect();
+    method public abstract boolean getMirroring();
     method public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract boolean hasCameraTransform();
   }
 
   public static interface SurfaceRequest.TransformationInfoListener {
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt
index ac60c54..128a2c3 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt
@@ -16,6 +16,7 @@
 
 package androidx.camera.core.imagecapture
 
+import android.graphics.Bitmap
 import androidx.camera.core.ImageCapture.OutputFileResults
 import androidx.camera.core.ImageCaptureException
 import androidx.camera.core.ImageProxy
@@ -33,7 +34,7 @@
     private var onDiskResult: OutputFileResults? = null
     private var onDiskResultCont: Continuation<OutputFileResults>? = null
 
-    override fun onPostviewImageAvailable(imageProxy: ImageProxy) {
+    override fun onPostviewBitmapAvailable(bitmap: Bitmap) {
     }
 
     override fun onCaptureProcessProgressed(progress: Int) {
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/Image2BitmapTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/Image2BitmapTest.kt
new file mode 100644
index 0000000..71e4ad9
--- /dev/null
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/Image2BitmapTest.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.camera.core.imagecapture
+
+import android.graphics.BitmapFactory
+import android.graphics.Matrix
+import android.graphics.Rect
+import androidx.camera.core.internal.utils.ImageUtil
+import androidx.camera.core.processing.Packet
+import androidx.camera.testing.impl.ExifUtil
+import androidx.camera.testing.impl.TestImageUtil
+import androidx.camera.testing.impl.fakes.FakeImageInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 21)
+class Image2BitmapTest {
+    private val operation = Image2Bitmap()
+
+    @Test
+    fun processYuvImage_rotation0_assertOutput() {
+        processYuvImage_assertOutput(rotationDegrees = 0)
+    }
+    @Test
+    fun processYuvImage_rotation90_assertOutput() {
+        processYuvImage_assertOutput(rotationDegrees = 90)
+    }
+
+    @Test
+    fun processYuvImage_rotation180_assertOutput() {
+        processYuvImage_assertOutput(rotationDegrees = 180)
+    }
+
+    @Test
+    fun processYuvImage_rotation270_assertOutput() {
+        processYuvImage_assertOutput(rotationDegrees = 270)
+    }
+
+    private fun processYuvImage_assertOutput(rotationDegrees: Int) {
+        // Arrange.
+        val imageInfo = FakeImageInfo()
+        val yuvImage = TestImageUtil.createYuvFakeImageProxy(imageInfo, Utils.WIDTH, Utils.HEIGHT)
+        val input = Packet.of(
+            yuvImage,
+            null, // YuvImage doesn't have exif info.
+            Rect(0, 0, Utils.WIDTH, Utils.HEIGHT),
+            rotationDegrees,
+            Matrix(),
+            Utils.CAMERA_CAPTURE_RESULT
+        )
+        val inputDecodedBitmap = ImageUtil.createBitmapFromImageProxy(yuvImage)
+
+        // Act.
+        val outputBitmap = operation.apply(input)
+
+        // Assert: the image is the same.
+        val inputRotatedBitmap = TestImageUtil.rotateBitmap(inputDecodedBitmap, rotationDegrees)
+        Truth.assertThat(TestImageUtil.getAverageDiff(
+            inputRotatedBitmap, outputBitmap)).isEqualTo(0)
+
+        // Assert: image is closed.
+        Truth.assertThat(yuvImage.isClosed).isTrue()
+    }
+
+    @Test
+    fun processJpegImage_rotation0_assertOutput() {
+        processJpegImage_assertOutput(rotationDegrees = 0)
+    }
+
+    @Test
+    fun processJpegImage_rotation90_assertOutput() {
+        processJpegImage_assertOutput(rotationDegrees = 90)
+    }
+
+    @Test
+    fun processJpegImage_rotation180_assertOutput() {
+        processJpegImage_assertOutput(rotationDegrees = 180)
+    }
+
+    @Test
+    fun processJpegImage_rotation270_assertOutput() {
+        processJpegImage_assertOutput(rotationDegrees = 270)
+    }
+
+    private fun processJpegImage_assertOutput(rotationDegrees: Int) {
+        // Arrange.
+        val imageInfo = FakeImageInfo()
+        val jpegBytes = TestImageUtil.createJpegBytes(Utils.WIDTH, Utils.HEIGHT)
+        val jpegImage = TestImageUtil.createJpegFakeImageProxy(imageInfo, jpegBytes)
+        val exif = ExifUtil.createExif(jpegBytes)
+        val input = Packet.of(
+            jpegImage,
+            exif,
+            Rect(0, 0, Utils.WIDTH, Utils.HEIGHT),
+            rotationDegrees,
+            Matrix(),
+            Utils.CAMERA_CAPTURE_RESULT
+        )
+        val inputDecodedBitmap = BitmapFactory.decodeByteArray(jpegBytes, 0, jpegBytes.size)
+
+        // Act.
+        val outputBitmap = operation.apply(input)
+
+        // Assert: the image is the same.
+        val inputRotatedBitmap = TestImageUtil.rotateBitmap(inputDecodedBitmap, rotationDegrees)
+        Truth.assertThat(TestImageUtil.getAverageDiff(
+            inputRotatedBitmap, outputBitmap)).isEqualTo(0)
+
+        // Assert: image is closed.
+        Truth.assertThat(jpegImage.isClosed).isTrue()
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java
index 311d07f..ce442af 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraEffect.java
@@ -20,6 +20,7 @@
 import static androidx.core.util.Preconditions.checkArgument;
 
 import android.graphics.ImageFormat;
+import android.view.Display;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
@@ -84,6 +85,16 @@
 public abstract class CameraEffect {
 
     /**
+     * Options for the transformation handled by the effect.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @IntDef(flag = true, value = {TRANSFORMATION_ARBITRARY,
+            TRANSFORMATION_CAMERA_AND_SURFACE_ROTATION})
+    public @interface Transformations {
+    }
+
+    /**
      * Bitmask options for the effect targets.
      */
     @Retention(RetentionPolicy.SOURCE)
@@ -93,7 +104,7 @@
     }
 
     /**
-     * Bitmask options for the effect targets.
+     * Bitmask options for the effect buffer formats.
      */
     @Retention(RetentionPolicy.SOURCE)
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -123,8 +134,39 @@
             PREVIEW | VIDEO_CAPTURE,
             PREVIEW | VIDEO_CAPTURE | IMAGE_CAPTURE);
 
+    /**
+     * Flag to indicate that the implementation will handle arbitrary transformation.
+     *
+     * <p>When this flag is used, CameraX may suggest arbitrary transformation via
+     * {@link SurfaceOutput#updateTransformMatrix} for the {@link SurfaceProcessor} to handle,
+     * including mirroring, rotating, cropping and/or scaling.
+     *
+     * <p>Use this flag if the {@link CameraEffect} implementation can handle arbitrary
+     * transformation.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public static final int TRANSFORMATION_ARBITRARY = 0;
+
+    /**
+     * Flag to indicate that the implementation will handle the camera and the Surface rotation.
+     *
+     * <p>When this flag is used, the value of {@link SurfaceOutput#updateTransformMatrix} will
+     * be a combination of the camera sensor orientation and the Surface rotation. The camera
+     * rotation is the value written by camera framework, which can be retrieved via
+     * {@link android.graphics.SurfaceTexture#getTransformMatrix(float[])} if the consumer is a
+     * {@link android.graphics.SurfaceTexture}. The Surface rotation is the value of the default
+     * {@link Display#getRotation()}.
+     *
+     * <p>Use this flag if the {@link CameraEffect} implementation handles the camera and the
+     * Surface rotation.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public static final int TRANSFORMATION_CAMERA_AND_SURFACE_ROTATION = 1;
+
     @Targets
     private final int mTargets;
+    @Transformations
+    private final int mTransformation;
     @NonNull
     private final Executor mExecutor;
     @Nullable
@@ -155,6 +197,7 @@
         checkArgument(targets == IMAGE_CAPTURE,
                 "Currently ImageProcessor can only target IMAGE_CAPTURE.");
         mTargets = targets;
+        mTransformation = TRANSFORMATION_ARBITRARY;
         mExecutor = executor;
         mSurfaceProcessor = null;
         mImageProcessor = imageProcessor;
@@ -173,6 +216,46 @@
      *                         </ul>
      *                         Targeting other {@link UseCase} combinations will throw
      *                         {@link IllegalArgumentException}.
+     * @param transformation   the transformation that the {@link SurfaceProcessor} will handle.
+     * @param executor         the {@link Executor} on which the {@param imageProcessor} and
+     *                         {@param errorListener} will be invoked.
+     * @param surfaceProcessor a {@link SurfaceProcessor} implementation. Once the effect is
+     *                         active, CameraX will send frames to the {@link SurfaceProcessor}
+     *                         on the {@param executor}, and deliver the processed frames to the
+     *                         app.
+     * @param errorListener    invoked if the effect runs into unrecoverable errors. The
+     *                         {@link Throwable} will be the error thrown by this
+     *                         {@link CameraEffect}. For example, {@link ProcessingException}.
+     *                         This is invoked on the provided {@param executor}.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    protected CameraEffect(
+            @Targets int targets,
+            @Transformations int transformation,
+            @NonNull Executor executor,
+            @NonNull SurfaceProcessor surfaceProcessor,
+            @NonNull Consumer<Throwable> errorListener) {
+        checkSupportedTargets(SURFACE_PROCESSOR_TARGETS, targets);
+        mTargets = targets;
+        mTransformation = transformation;
+        mExecutor = executor;
+        mSurfaceProcessor = surfaceProcessor;
+        mImageProcessor = null;
+        mErrorListener = errorListener;
+    }
+
+    /**
+     * @param targets          the target {@link UseCase} to which this effect should be applied.
+     *                         Currently {@link SurfaceProcessor} can target the following
+     *                         combinations:
+     *                         <ul>
+     *                         <li>{@link #PREVIEW}
+     *                         <li>{@link #PREVIEW} | {@link #VIDEO_CAPTURE}
+     *                         <li>{@link #PREVIEW} | {@link #VIDEO_CAPTURE} |
+     *                         {@link #IMAGE_CAPTURE}
+     *                         </ul>
+     *                         Targeting other {@link UseCase} combinations will throw
+     *                         {@link IllegalArgumentException}.
      * @param executor         the {@link Executor} on which the {@param imageProcessor} and
      *                         {@param errorListener} will be invoked.
      * @param surfaceProcessor a {@link SurfaceProcessor} implementation. Once the effect is
@@ -191,6 +274,7 @@
             @NonNull Consumer<Throwable> errorListener) {
         checkSupportedTargets(SURFACE_PROCESSOR_TARGETS, targets);
         mTargets = targets;
+        mTransformation = TRANSFORMATION_ARBITRARY;
         mExecutor = executor;
         mSurfaceProcessor = surfaceProcessor;
         mImageProcessor = null;
@@ -206,6 +290,15 @@
     }
 
     /**
+     * Gets the transformation that the {@link SurfaceProcessor} will handle.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @Transformations
+    public int getTransformation() {
+        return mTransformation;
+    }
+
+    /**
      * Gets the {@link Executor} associated with this effect.
      *
      * <p>This method returns the value set in the constructor.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
index 57fd948..e712179 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraInfo.java
@@ -27,6 +27,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.annotation.StringDef;
+import androidx.camera.core.impl.DynamicRanges;
 import androidx.camera.core.impl.ImageOutputConfig;
 import androidx.camera.core.internal.compat.MediaActionSoundCompat;
 import androidx.lifecycle.LifecycleOwner;
@@ -340,6 +341,71 @@
         return false;
     }
 
+    /**
+     * Returns the supported dynamic ranges of this camera from a set of candidate dynamic ranges.
+     *
+     * <p>Dynamic range specifies how the range of colors, highlights and shadows captured by
+     * the frame producer are represented on a display. Some dynamic ranges allow the preview
+     * surface to make full use of the extended range of brightness of the display.
+     *
+     * <p>The returned dynamic ranges are those which the camera can produce. However, because
+     * care usually needs to be taken to ensure the frames produced can be displayed correctly,
+     * the returned dynamic ranges will be limited to those passed in to {@code
+     * candidateDynamicRanges}. For example, if the device display supports HLG, HDR10 and
+     * HDR10+, and you're attempting to use a UI component to receive frames from those dynamic
+     * ranges that you know will be display correctly, you would use a {@code
+     * candidateDynamicRanges} set consisting of {@code {DynamicRange.HLG_10_BIT,
+     * DynamicRange.HDR10_10_BIT, DynamicRange.HDR10_PLUS_10_BIT}}. If the only 10-bit/HDR {@code
+     * DynamicRange} the camera can produce is {@code HLG_10_BIT}, then that will be the only
+     * dynamic range returned by this method given the above candidate list.
+     *
+     * <p>Consult the documentation of each use case to determine whether using the dynamic ranges
+     * published here are appropriate. Some use cases may have complex requirements that prohibit
+     * them from publishing a candidate list for use with this method, such as
+     * {@link androidx.camera.video.Recorder Recorder}. For those cases, alternative APIs may be
+     * present for querying the supported dynamic ranges that can be set on the use case.
+     *
+     * <p>The dynamic ranges published as return values by this method are fully-defined. That is,
+     * the resulting set will not contain dynamic ranges such as {@link DynamicRange#UNSPECIFIED} or
+     * {@link DynamicRange#HDR_UNSPECIFIED_10_BIT}. However, non-fully-defined dynamic ranges can
+     * be used in {@code candidateDynamicRanges}, and will resolve to fully-defined dynamic ranges
+     * in the resulting set. To query all dynamic ranges the camera can produce, {@code
+     * Collections.singleton(DynamicRange.UNSPECIFIED}} can be used as the candidate set.
+     *
+     * <p>Because SDR is always supported, including {@link DynamicRange#SDR} in {@code
+     * candidateDynamicRanges} will always result in {@code SDR} being present in the result set.
+     * If an empty candidate set is provided, it is treated as a no-op, and an empty set will be
+     * returned.
+     *
+     * @param candidateDynamicRanges a set of dynamic ranges representing the dynamic ranges the
+     *                               consumer of frames can support. Note that each use case may
+     *                               have its own requirements on which dynamic ranges it can
+     *                               consume based on how it is configured, and those dynamic
+     *                               ranges may not be published as a set of candidate dynamic
+     *                               ranges. In that case, this API may not be appropriate. An
+     *                               example of this is
+     *                               {@link androidx.camera.video.VideoCapture VideoCapture}'s
+     *                               {@link androidx.camera.video.Recorder Recorder} class, which
+     *                               must also take into account the dynamic ranges supported by
+     *                               the media codecs on the device, and the quality of the video
+     *                               being recorded. For that class, it is recommended to use
+     *            {@link androidx.camera.video.RecorderVideoCapabilities#getSupportedDynamicRanges()
+     *                               RecorderVideoCapabilities.getSupportedDynamicRanges()}
+     *                               instead.
+     * @return a set of dynamic ranges supported by the camera based on the candidate dynamic ranges
+     *
+     * @see Preview.Builder#setDynamicRange(DynamicRange)
+     * @see androidx.camera.video.RecorderVideoCapabilities#getSupportedDynamicRanges()
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    default Set<DynamicRange> querySupportedDynamicRanges(
+            @NonNull Set<DynamicRange> candidateDynamicRanges) {
+        // For the default implementation, only assume SDR is supported.
+        return DynamicRanges.findAllPossibleMatches(candidateDynamicRanges,
+                Collections.singleton(DynamicRange.SDR));
+    }
+
     @StringDef(open = true, value = {IMPLEMENTATION_TYPE_UNKNOWN,
             IMPLEMENTATION_TYPE_CAMERA2_LEGACY, IMPLEMENTATION_TYPE_CAMERA2,
             IMPLEMENTATION_TYPE_FAKE})
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index 683aab2..58a3170 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -59,6 +59,7 @@
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
+import android.graphics.Bitmap;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
 import android.location.Location;
@@ -883,7 +884,6 @@
      *
      * @return {@link ImageCaptureCapabilities}
      */
-    @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
     public static ImageCaptureCapabilities getImageCaptureCapabilities(
             @NonNull CameraInfo cameraInfo) {
@@ -1174,6 +1174,7 @@
         boolean isPostviewEnabled =
                 getCurrentConfig().retrieveOption(OPTION_POSTVIEW_ENABLED, false);
         Size postViewSize = null;
+        int postviewFormat = ImageFormat.YUV_420_888;
 
         if (isPostviewEnabled) {
             SessionProcessor sessionProcessor = getSessionProcessor();
@@ -1183,9 +1184,14 @@
                                 null);
                 Map<Integer, List<Size>> map =
                         sessionProcessor.getSupportedPostviewSize(resolution);
-                List<Size> sizes = map.get(ImageFormat.JPEG);
+                // Prefer YUV because it takes less time to decode to bitmap.
+                List<Size> sizes = map.get(ImageFormat.YUV_420_888);
+                if (sizes == null || sizes.isEmpty()) {
+                    sizes = map.get(ImageFormat.JPEG);
+                    postviewFormat = ImageFormat.JPEG;
+                }
 
-                if (sizes != null) {
+                if (sizes != null && !sizes.isEmpty()) {
                     if (postviewSizeSelector != null) {
                         Collections.sort(sizes, new CompareSizesByArea(true));
                         CameraInternal camera = getCamera();
@@ -1215,7 +1221,7 @@
         }
 
         mImagePipeline = new ImagePipeline(config, resolution, getEffect(), isVirtualCamera,
-                postViewSize);
+                postViewSize, postviewFormat);
 
         if (mTakePictureManager == null) {
             // mTakePictureManager is reused when the Surface is reset.
@@ -1420,6 +1426,26 @@
     }
 
     /**
+     * Returns if postview is enabled or not.
+     *
+     * @see Builder#setPostviewEnabled(boolean)
+     */
+    public boolean isPostviewEnabled() {
+        return getCurrentConfig().retrieveOption(OPTION_POSTVIEW_ENABLED, false);
+    }
+
+    /**
+     * Returns the {@link ResolutionSelector} used to select the postview size.
+     *
+     * @see Builder#setPostviewResolutionSelector(ResolutionSelector)
+     */
+    @Nullable
+    public ResolutionSelector getPostviewResolutionSelector() {
+        return getCurrentConfig().retrieveOption(OPTION_POSTVIEW_RESOLUTION_SELECTOR,
+                null);
+    }
+
+    /**
      * Describes the error that occurred during an image capture operation (such as {@link
      * ImageCapture#takePicture(Executor, OnImageCapturedCallback)}).
      *
@@ -1503,46 +1529,38 @@
          *
          * <p>To know in advanced if this callback will be invoked or not, check the
          * capabilities by {@link #getImageCaptureCapabilities(CameraInfo)} and
-         * {@link ImageCaptureCapabilities#isCaptureProcessProgressSupported()}.
+         * {@link ImageCaptureCapabilities#isCaptureProcessProgressSupported()}. If supported,
+         * this callback will be called multiple times with monotonically increasing
+         * values. At the minimum the callback will be called once with value 100 to
+         * indicate the processing is finished. This callback will always be called before
+         * {@link #onImageSaved(OutputFileResults)}.
          *
          * @param progress the progress ranging from 0 to 100.
          */
-        @RestrictTo(Scope.LIBRARY_GROUP)
         default void onCaptureProcessProgressed(int progress) {
         }
 
         /**
-         * Callback to notify that the postview image is available. The postview is intended to be
+         * Callback to notify that the postview bitmap is available. The postview is intended to be
          * shown on UI before the long-processing capture is completed in order to provide a
-         * better UX. The image format is {@link ImageFormat#JPEG}.
+         * better UX.
          *
          * <p>The postview is only available when the
          * {@link ImageCaptureCapabilities#isPostviewSupported()} returns true for the specified
          * {@link CameraInfo} and applications must explicitly enable the postview using the
-         * {@link Builder#setPostviewEnabled(boolean)}. Please note that if something goes wrong
-         * when processing the postview, this callback method won't be invoked.
+         * {@link Builder#setPostviewEnabled(boolean)}. This callback will be called before
+         * {@link #onImageSaved(OutputFileResults)}. But if something goes wrong when processing
+         * the postview, this callback method could be skipped.
          *
-         * <p>Please close the {@link ImageProxy} once you no longer need it. The default
-         * implementation of this method will close it in case apps don't implement the method.
-         *
-         * <p>The image is provided as captured by the underlying {@link ImageReader} without
-         * rotation applied. The value in {@code image.getImageInfo().getRotationDegrees()}
-         * describes the magnitude of clockwise rotation, which if applied to the image will make
-         * it match the currently configured target rotation.
-         *
-         * <p>For example, if the current target rotation is set to the display rotation,
-         * rotationDegrees is the rotation to apply to the image to match the display orientation.
-         * A rotation of 90 degrees would mean rotating the image 90 degrees clockwise produces an
-         * image that will match the display orientation.
+         * <p>The bitmap is rotated according to the target rotation set to the {@link ImageCapture}
+         * to make it upright. If target rotation is not set, the display rotation is used.
          *
          * <p>See also {@link ImageCapture.Builder#setTargetRotation(int)} and
          * {@link #setTargetRotation(int)}.
          *
-         * @param image the postview {@link ImageProxy}
+         * @param bitmap the postview bitmap.
          */
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-        default void onPostviewImageAvailable(@NonNull ImageProxy image) {
-            image.close();
+        default void onPostviewBitmapAvailable(@NonNull Bitmap bitmap) {
         }
     }
 
@@ -1610,46 +1628,39 @@
          *
          * <p>To know in advanced if this callback will be invoked or not, check the
          * capabilities by {@link #getImageCaptureCapabilities(CameraInfo)} and
-         * {@link ImageCaptureCapabilities#isCaptureProcessProgressSupported()}.
+         * {@link ImageCaptureCapabilities#isCaptureProcessProgressSupported()}. If supported,
+         * this callback will be called multiple times with monotonically increasing
+         * values. At the minimum the callback will be called once with value 100 to
+         * indicate the processing is finished. This callback will always be called before
+         * {@link #onCaptureSuccess(ImageProxy)}.
          *
          * @param progress the progress ranging from 0 to 100.
          */
-        @RestrictTo(Scope.LIBRARY_GROUP)
         public void onCaptureProcessProgressed(int progress) {
         }
 
         /**
-         * Callback to notify that the postview image is available. The postview is intended to be
+         * Callback to notify that the postview bitmap is available. The postview is intended to be
          * shown on UI before the long-processing capture is completed in order to provide a
-         * better UX. The image format is {@link ImageFormat#JPEG}.
+         * better UX.
          *
          * <p>The postview is only available when the
          * {@link ImageCaptureCapabilities#isPostviewSupported()} returns true for the specified
          * {@link CameraInfo} and applications must explicitly enable the postview using the
-         * {@link Builder#setPostviewEnabled(boolean)}. Please note that if something goes wrong
-         * when processing the postview, this callback method won't be invoked.
+         * {@link Builder#setPostviewEnabled(boolean)}. This callback will be called before
+         * {@link #onCaptureSuccess(ImageProxy)}. But if something goes wrong when processing the
+         * postview, this callback method could be skipped.
          *
-         * <p>Please close the {@link ImageProxy} once you no longer need it. The default
-         * implementation of this method will close it in case apps don't implement the method.
-         *
-         * <p>The image is provided as captured by the underlying {@link ImageReader} without
-         * rotation applied. The value in {@code image.getImageInfo().getRotationDegrees()}
-         * describes the magnitude of clockwise rotation, which if applied to the image will make
-         * it match the currently configured target rotation.
-         *
-         * <p>For example, if the current target rotation is set to the display rotation,
-         * rotationDegrees is the rotation to apply to the image to match the display orientation.
-         * A rotation of 90 degrees would mean rotating the image 90 degrees clockwise produces an
-         * image that will match the display orientation.
+         * <p>The bitmap is rotated according to the target rotation set to the {@link ImageCapture}
+         * to make it upright. If target rotation is not set, the display rotation is used.
          *
          * <p>See also {@link ImageCapture.Builder#setTargetRotation(int)} and
          * {@link #setTargetRotation(int)}.
          *
-         * @param image the postview {@link ImageProxy}
+         * @param bitmap the postview bitmap.
+
          */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public void onPostviewImageAvailable(@NonNull ImageProxy image) {
-            image.close();
+        public void onPostviewBitmapAvailable(@NonNull Bitmap bitmap) {
         }
     }
 
@@ -2533,22 +2544,27 @@
         }
 
         /**
-         * Enables the postview which allows you to get the unprocessed image before the processing
-          * is done during the <code>takePicture</code> call.
+         * Enables postview image generation. A postview image is a low-quality image
+         * that's produced earlier during image capture than the final high-quality image,
+         * and can be used as a thumbnail or placeholder until the final image is ready.
          *
-         * <p>By default the largest available postview size that are smaller or equal to the
+         * <p>When the postview is available,
+         * {@link OnImageCapturedCallback#onPostviewBitmapAvailable(Bitmap)} or
+         * {@link OnImageSavedCallback#onPostviewBitmapAvailable(Bitmap)} will be called.
+         *
+         * <p>By default the largest available postview size that is smaller or equal to the
          * ImagaeCapture size will be used to configure the postview. The {@link ResolutionSelector}
          * can also be used to select a specific size via
          * {@link #setPostviewResolutionSelector(ResolutionSelector)}.
          *
-         * <p>It is recommended to query the capture capability via
-         * {@link #getImageCaptureCapabilities(CameraInfo)} before enabling this feature to avoid
-         * unnecessary initializations.
+         * <p>You can query the postview capability by invoking
+         * {@link #getImageCaptureCapabilities(CameraInfo)}. If
+         * {@link ImageCaptureCapabilities#isPostviewSupported()} returns false and you still
+         * enable the postview, the postview image won't be generated.
          *
          * @param postviewEnabled whether postview is enabled or not
          * @return the current Builder.
          */
-        @RestrictTo(Scope.LIBRARY_GROUP)
         @NonNull
         public Builder setPostviewEnabled(boolean postviewEnabled) {
             getMutableConfig().insertOption(OPTION_POSTVIEW_ENABLED,
@@ -2558,15 +2574,17 @@
 
         /**
          * Set the {@link ResolutionSelector} to select the postview size from the available
-         * postview sizes. Please note the selected size will be smaller or equal to the
-         * ImageCapture size.
+         * postview sizes. These available postview sizes are smaller or equal to the
+         * ImageCapture size. You can implement the
+         * {@link androidx.camera.core.resolutionselector.ResolutionFilter} and set it to the
+         * {@link ResolutionSelector} to get the list of available sizes and determine which size
+         * to use.
          *
          * <p>If no sizes can be selected using the given {@link ResolutionSelector}, it will throw
          * an {@link IllegalArgumentException} when {@code bindToLifecycle()} is invoked.
          *
          * @return the current Builder.
          */
-        @RestrictTo(Scope.LIBRARY_GROUP)
         @NonNull
         public Builder setPostviewResolutionSelector(
                 @NonNull ResolutionSelector resolutionSelector) {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureCapabilities.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureCapabilities.java
index 1c81d44..9c05020 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureCapabilities.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCaptureCapabilities.java
@@ -16,24 +16,29 @@
 
 package androidx.camera.core;
 
-import androidx.annotation.RestrictTo;
-
 /**
  * ImageCaptureCapabilities is used to query {@link ImageCapture} use case capabilities on the
  * device.
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public interface ImageCaptureCapabilities {
     /**
-     * Returns if the takePicture() call in {@link ImageCapture} is capable of outputting post
-     * view images ahead of final images. If supported, apps can enable the postview using
+     * Returns if the takePicture() call in {@link ImageCapture} is capable of outputting
+     * postview images.
+     *
+     * <p>A postview image is a low-quality image that's produced earlier during image capture
+     * than the final high-quality image, and can be used as a thumbnail or placeholder until the
+     * final image is ready.
+     *
+     * If supported, apps can enable the postview using
      * {@link ImageCapture.Builder#setPostviewEnabled(boolean)}.
      */
     boolean isPostviewSupported();
 
     /**
      * Returns if the takePicture() call in {@link ImageCapture} is capable of notifying the
-     * onCaptureProcessProgressed callback to the apps.
+     * {@link ImageCapture.OnImageSavedCallback#onCaptureProcessProgressed(int)} or
+     * {@link ImageCapture.OnImageCapturedCallback#onCaptureProcessProgressed(int)} callback to
+     * the apps.
      */
     boolean isCaptureProcessProgressSupported();
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessingUtil.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessingUtil.java
index dc55aec..e448993 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessingUtil.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageProcessingUtil.java
@@ -146,11 +146,25 @@
     }
 
     /**
-     * Convert a YUV_420_888 ImageProxy to a JPEG bytes data as an Image into the Surface.
+     * Convert a YUV_420_888 Image to a JPEG bytes data as an Image into the Surface.
      *
      * <p>Returns true if it succeeds and false otherwise.
      */
     public static boolean convertYuvToJpegBytesIntoSurface(
+            @NonNull Image image,
+            @IntRange(from = 1, to = 100) int jpegQuality,
+            @ImageOutputConfig.RotationDegreesValue int rotationDegrees,
+            @NonNull Surface outputSurface) {
+        return convertYuvToJpegBytesIntoSurface(new AndroidImageProxy(image), jpegQuality,
+                rotationDegrees, outputSurface);
+    }
+
+        /**
+         * Convert a YUV_420_888 ImageProxy to a JPEG bytes data as an Image into the Surface.
+         *
+         * <p>Returns true if it succeeds and false otherwise.
+         */
+    public static boolean convertYuvToJpegBytesIntoSurface(
             @NonNull ImageProxy imageProxy,
             @IntRange(from = 1, to = 100) int jpegQuality,
             @ImageOutputConfig.RotationDegreesValue int rotationDegrees,
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
index 8bc0b73..d804dab 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
@@ -19,6 +19,7 @@
 import static androidx.camera.core.CameraEffect.PREVIEW;
 import static androidx.camera.core.MirrorMode.MIRROR_MODE_ON_FRONT_ONLY;
 import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
+import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_DYNAMIC_RANGE;
 import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_FORMAT;
 import static androidx.camera.core.impl.ImageOutputConfig.OPTION_APP_TARGET_ROTATION;
 import static androidx.camera.core.impl.ImageOutputConfig.OPTION_CUSTOM_ORDERED_RESOLUTIONS;
@@ -62,7 +63,6 @@
 import android.view.SurfaceView;
 import android.view.TextureView;
 
-import androidx.annotation.IntRange;
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -77,6 +77,7 @@
 import androidx.camera.core.impl.Config;
 import androidx.camera.core.impl.ConfigProvider;
 import androidx.camera.core.impl.DeferrableSurface;
+import androidx.camera.core.impl.ImageInputConfig;
 import androidx.camera.core.impl.ImageOutputConfig;
 import androidx.camera.core.impl.MutableConfig;
 import androidx.camera.core.impl.MutableOptionsBundle;
@@ -288,20 +289,6 @@
         }
     }
 
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @IntRange(from = 0, to = 359)
-    protected int getRelativeRotation(@NonNull CameraInternal cameraInternal,
-            boolean requireMirroring) {
-        if (cameraInternal.getHasTransform()) {
-            return super.getRelativeRotation(cameraInternal, requireMirroring);
-        } else {
-            // If there is a virtual parent camera, the buffer is already rotated because
-            // SurfaceView cannot handle additional rotation.
-            return 0;
-        }
-    }
-
     private boolean shouldMirror(@NonNull CameraInternal camera) {
         // Since PreviewView cannot mirror, we will always mirror preview stream during buffer
         // copy. If there has been a buffer copy, it means it's already mirrored. Otherwise,
@@ -673,6 +660,37 @@
     }
 
     /**
+     * Returns the dynamic range.
+     *
+     * <p>The dynamic range is set by {@link Preview.Builder#setDynamicRange(DynamicRange)}.
+     * If the dynamic range set is not a fully defined dynamic range, such as
+     * {@link DynamicRange#HDR_UNSPECIFIED_10_BIT}, then it will be returned just as provided,
+     * and will not be returned as a fully defined dynamic range. The fully defined dynamic
+     * range, which is determined by resolving the combination of requested dynamic ranges from
+     * other use cases according to the device capabilities, will be
+     * communicated to the {@link Preview.SurfaceProvider} via
+     * {@link SurfaceRequest#getDynamicRange()}}.
+     *
+     * <p>If the dynamic range was not provided to
+     * {@link Preview.Builder#setDynamicRange(DynamicRange)}, this will return the default of
+     * {@link DynamicRange#UNSPECIFIED}
+     *
+     * @return the dynamic range set for this {@code Preview} use case.
+     *
+     * @see Preview.Builder#setDynamicRange(DynamicRange)
+     */
+    // Internal implementation note: this method should not be used to retrieve the dynamic range
+    // that will be sent to the SurfaceProvider. That should always be retrieved from the StreamSpec
+    // since that will be the final DynamicRange chosen by the camera based on other use case
+    // combinations.
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @NonNull
+    public DynamicRange getDynamicRange() {
+        return getCurrentConfig().hasDynamicRange() ? getCurrentConfig().getDynamicRange() :
+                Defaults.DEFAULT_DYNAMIC_RANGE;
+    }
+
+    /**
      * Returns {@link PreviewCapabilities} to query preview stream related device capability.
      *
      * @return {@link PreviewCapabilities}
@@ -776,11 +794,19 @@
 
         private static final PreviewConfig DEFAULT_CONFIG;
 
+        /**
+         * Preview uses an UNSPECIFIED dynamic range by default. This means the dynamic range can be
+         * inherited from other use cases during dynamic range resolution when the use case is
+         * bound.
+         */
+        private static final DynamicRange DEFAULT_DYNAMIC_RANGE = DynamicRange.UNSPECIFIED;
+
         static {
             Builder builder = new Builder()
                     .setSurfaceOccupancyPriority(DEFAULT_SURFACE_OCCUPANCY_PRIORITY)
                     .setTargetAspectRatio(DEFAULT_ASPECT_RATIO)
-                    .setResolutionSelector(DEFAULT_RESOLUTION_SELECTOR);
+                    .setResolutionSelector(DEFAULT_RESOLUTION_SELECTOR)
+                    .setDynamicRange(DEFAULT_DYNAMIC_RANGE);
             DEFAULT_CONFIG = builder.getUseCaseConfig();
         }
 
@@ -796,6 +822,7 @@
     public static final class Builder
             implements UseCaseConfig.Builder<Preview, PreviewConfig, Builder>,
             ImageOutputConfig.Builder<Builder>,
+            ImageInputConfig.Builder<Builder>,
             ThreadConfig.Builder<Builder> {
 
         private final MutableOptionsBundle mMutableConfig;
@@ -1125,6 +1152,88 @@
             return this;
         }
 
+        // Implementations of ImageInputConfig.Builder default methods
+
+        /**
+         * Sets the {@link DynamicRange}.
+         *
+         * <p>Dynamic range specifies how the range of colors, highlights and shadows captured by
+         * the frame producer are represented on a display. Some dynamic ranges allow the preview
+         * surface to make full use of the extended range of brightness of the display.
+         *
+         * <p>The supported dynamic ranges for preview depend on the capabilities of the
+         * camera and the ability of the {@link Surface} provided by the
+         * {@link Preview.SurfaceProvider} to consume the dynamic range. The supported dynamic
+         * ranges of the camera can be queried using
+         * {@link CameraInfo#querySupportedDynamicRanges(Set)}.
+         *
+         * <p>As an example, if the {@link Surface} provided by {@link Preview.SurfaceProvider}
+         * comes from a {@link SurfaceView}, such as with
+         * {@link androidx.camera.viewfinder.CameraViewfinder CameraViewfinder} set to
+         * implementation mode
+         * {@link androidx.camera.viewfinder.CameraViewfinder.ImplementationMode#PERFORMANCE
+         * PERFORMANCE}, you may want to query the dynamic ranges supported by the display:
+         * <pre>
+         *   <code>
+         *
+         *        // Get supported HDR dynamic ranges from the display
+         *        Display display = requireContext().getDisplay();
+         *        List&lt;Integer&gt; displayHdrTypes =
+         *                display.getHdrCapabilities().getSupportedHdrTypes();
+         *        Set&lt;DynamicRange&gt; displayHighDynamicRanges =
+         *                // Simple map of Display.HdrCapabilities enums to CameraX DynamicRange
+         *                convertToDynamicRangeSet(displayHdrTypes);
+         *
+         *        // Query dynamic ranges supported by the camera from our
+         *        // dynamic ranges supported by the display.
+         *        mSupportedHighDynamicRanges =
+         *                mCameraInfo.querySupportedDynamicRanges(
+         *                        displayHighDynamicRanges);
+         *
+         *        // Update our UI picker for dynamic range.
+         *        ...
+         *
+         *
+         *        // Create the Preview use case from the dynamic range
+         *        // selected by the UI picker.
+         *        mPreview = new Preview.Builder()
+         *                .setDynamicRange(mSelectedDynamicRange)
+         *                .build();
+         *   </code>
+         * </pre>
+         *
+         * <p>If the dynamic range is not provided, the returned {@code Preview} use case will use
+         * a default of {@link DynamicRange#UNSPECIFIED}. When a {@code Preview} is bound with
+         * other use cases that specify a dynamic range, such as
+         * {@link androidx.camera.video.VideoCapture}, and the preview dynamic range is {@code
+         * UNSPECIFIED}, the resulting dynamic range of the preview will usually match the other
+         * use case's dynamic range. If no other use cases are bound with the preview, an
+         * {@code UNSPECIFIED} dynamic range will resolve to {@link DynamicRange#SDR}. When
+         * using a {@code Preview} with another use case, it is recommended to leave the dynamic
+         * range of the {@code Preview} as {@link DynamicRange#UNSPECIFIED}, so the camera can
+         * choose the best supported dynamic range that satisfies the requirements of both use
+         * cases.
+         *
+         * <p>If an unspecified dynamic range is used, the resolved fully-defined dynamic range of
+         * frames sent from the camera will be communicated to the
+         * {@link Preview.SurfaceProvider} via {@link SurfaceRequest#getDynamicRange()}, and the
+         * provided {@link Surface} should be configured to use that dynamic range.
+         *
+         * <p>It is possible to choose a high dynamic range (HDR) with unspecified encoding by
+         * providing {@link DynamicRange#HDR_UNSPECIFIED_10_BIT}.
+         *
+         * @return The current Builder.
+         * @see DynamicRange
+         * @see CameraInfo#querySupportedDynamicRanges(Set)
+         */
+        @RestrictTo(Scope.LIBRARY_GROUP)
+        @NonNull
+        @Override
+        public Builder setDynamicRange(@NonNull DynamicRange dynamicRange) {
+            getMutableConfig().insertOption(OPTION_INPUT_DYNAMIC_RANGE, dynamicRange);
+            return this;
+        }
+
         // Implementations of ThreadConfig.Builder default methods
 
         /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java
index 1c24d84e..943b069 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java
@@ -156,8 +156,7 @@
      *
      * <p>The value is a mapping from sensor coordinates to buffer coordinates, which is,
      * from the rect of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE} to the
-     * rect defined by {@code (0, 0, SurfaceRequest#getResolution#getWidth(),
-     * SurfaceRequest#getResolution#getHeight())}. The matrix can
+     * rect defined by {@code (0, 0, #getSize()#getWidth(), #getSize()#getHeight())}. The matrix can
      * be used to map the coordinates from one {@link UseCase} to another. For example,
      * detecting face with {@link ImageAnalysis}, and then highlighting the face in
      * {@link Preview}.
@@ -174,7 +173,6 @@
      *  analysisToEffect.postConcat(sensorToEffect);
      * </pre></code>
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
     default Matrix getSensorToBufferTransform() {
         return new Matrix();
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java
index e2d2292..e110e52 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java
@@ -892,23 +892,45 @@
         /**
          * Whether the {@link Surface} contains the camera transform.
          *
-         * <p>The {@link Surface} may contain a transformation, which will be used by Android
-         * components such as {@link TextureView} and {@link SurfaceView} to transform the output.
-         * The app may need to handle the transformation differently based on whether this value
-         * exists.
+         * <p>When the Surface is connected to the camera directly, camera writes the
+         * camera orientation value to the Surface. For example, the value can be retrieved via
+         * {@link SurfaceTexture#getTransformMatrix(float[])}. Android components such
+         * as {@link TextureView} and {@link SurfaceView} use the value to transform the output.
+         * When the Surface is not connect to the camera directly, for example, when it was
+         * copied with OpenGL, the Surface will not contain the camera orientation value.
          *
-         * <ul>
-         * <li>If the producer is the camera, then the {@link Surface} will contain a
-         * transformation that represents the camera orientation. In that case, this method will
-         * return {@code true}.
-         * <li>If the producer is not the camera, for example, if the stream has been edited by
-         * CameraX, then the {@link Surface} will not contain any transformation. In that case,
-         * this method will return {@code false}.
-         * </ul>
+         * <p>The app may need to transform the UI differently based on this flag. If this value
+         * is true, the app only needs to apply the Surface transformation; otherwise, the app
+         * needs to apply the value of {@link #getRotationDegrees()}. For example, if the preview
+         * is displayed in a {@link TextureView}:
          *
-         * @return true if the producer writes the camera transformation to the {@link Surface}.
+         * <pre><code>
+         * int rotationDegrees;
+         * if (surfaceRequest.hasCameraTransform()) {
+         *   switch (textureView.getDisplay().getRotation()) {
+         *     case Surface.ROTATION_0:
+         *       rotationDegrees = 0;
+         *       break;
+         *     case Surface.ROTATION_90:
+         *       rotationDegrees = 90;
+         *       break;
+         *     case Surface.ROTATION_180:
+         *       rotationDegrees = 180;
+         *       break;
+         *     case Surface.ROTATION_270:
+         *       rotationDegrees = 270;
+         *       break;
+         *     }
+         * } else {
+         *   rotationDegrees = transformationInfo.getRotationDegrees();
+         * }
+         * Matrix textureViewTransform = new Matrix();
+         * textureViewTransform.postRotate(rotationDegrees);
+         * textureView.setTransform(textureViewTransform);
+         * </code></pre>
+         *
+         * @return true if the {@link Surface} contains the camera transformation.
          */
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public abstract boolean hasCameraTransform();
 
         /**
@@ -916,15 +938,24 @@
          *
          * <p>The value is a mapping from sensor coordinates to buffer coordinates, which is,
          * from the rect of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE} to the
-         * rect defined by {@code (0, 0, SurfaceRequest#getResolution#getWidth(),
-         * SurfaceRequest#getResolution#getHeight())}. The matrix can
-         * be used to map the coordinates from one {@link UseCase} to another. For example,
-         * detecting face with {@link ImageAnalysis}, and then highlighting the face in
+         * rect defined by {@code (0, 0, #getResolution#getWidth(), #getResolution#getHeight())}.
+         * The matrix can be used to map the coordinates from one {@link UseCase} to another. For
+         * example, detecting face with {@link ImageAnalysis}, and then highlighting the face in
          * {@link Preview}.
+         *
+         * <p>Code sample
+         * <code><pre>
+         *  // Get the transformation from sensor to effect input.
+         *  Matrix sensorToEffect = surfaceRequest.getSensorToBufferTransform();
+         *  // Get the transformation from sensor to ImageAnalysis.
+         *  Matrix sensorToAnalysis = imageProxy.getSensorToBufferTransform();
+         *  // Concatenate the two matrices to get the transformation from ImageAnalysis to effect.
+         *  Matrix analysisToEffect = Matrix()
+         *  sensorToAnalysis.invert(analysisToEffect);
+         *  analysisToEffect.postConcat(sensorToEffect);
+         * </pre></code>
          */
-        // TODO(b/292286071): make this public in 1.4 alpha.
         @NonNull
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public abstract Matrix getSensorToBufferTransform();
 
         /**
@@ -934,8 +965,6 @@
          * example, for front camera preview, the buffer should usually be mirrored. The
          * mirroring should be applied after the {@link #getRotationDegrees()} is applied.
          */
-        // TODO(b/292286071): make this public in 1.4 alpha.
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public abstract boolean getMirroring();
 
         /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/CaptureNode.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/CaptureNode.java
index 0bfb216..2baba27 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/CaptureNode.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/CaptureNode.java
@@ -177,7 +177,7 @@
                     createImageReaderProxy(inputEdge.getImageReaderProxyProvider(),
                             inputEdge.getPostviewSize().getWidth(),
                             inputEdge.getPostviewSize().getHeight(),
-                            ImageFormat.JPEG);
+                            inputEdge.getPostviewImageFormat());
             postviewImageReader.setOnImageAvailableListener(imageReader -> {
                 try {
                     ImageProxy image = imageReader.acquireLatestImage();
@@ -191,7 +191,8 @@
 
             mSafeCloseImageReaderForPostview = new SafeCloseImageReaderProxy(postviewImageReader);
             inputEdge.setPostviewSurface(
-                    postviewImageReader.getSurface(), inputEdge.getPostviewSize());
+                    postviewImageReader.getSurface(),
+                    inputEdge.getPostviewSize(), inputEdge.getPostviewImageFormat());
         }
 
         inputEdge.getRequestEdge().setListener(requestConsumer);
@@ -393,6 +394,11 @@
         abstract Size getPostviewSize();
 
         /**
+         * The image format of the postview.
+         */
+        abstract int getPostviewImageFormat();
+
+        /**
          * Edge that accepts {@link ProcessingRequest}.
          */
         @NonNull
@@ -428,8 +434,8 @@
             mSurface = new ImmediateSurface(surface, getSize(), getInputFormat());
         }
 
-        void setPostviewSurface(@NonNull Surface surface, @NonNull Size size) {
-            mPostviewSurface = new ImmediateSurface(surface, size, ImageFormat.JPEG);
+        void setPostviewSurface(@NonNull Surface surface, @NonNull Size size, int imageFormat) {
+            mPostviewSurface = new ImmediateSurface(surface, size, imageFormat);
         }
 
         /**
@@ -448,10 +454,19 @@
 
         @NonNull
         static In of(Size size, int inputFormat, int outputFormat, boolean isVirtualCamera,
-                @Nullable ImageReaderProxyProvider imageReaderProxyProvider,
-                @Nullable Size postviewSize) {
+                @Nullable ImageReaderProxyProvider imageReaderProxyProvider) {
             return new AutoValue_CaptureNode_In(size, inputFormat, outputFormat, isVirtualCamera,
-                    imageReaderProxyProvider, postviewSize, new Edge<>(), new Edge<>());
+                    imageReaderProxyProvider, null, ImageFormat.YUV_420_888,
+                    new Edge<>(), new Edge<>());
+        }
+
+        @NonNull
+        static In of(Size size, int inputFormat, int outputFormat, boolean isVirtualCamera,
+                @Nullable ImageReaderProxyProvider imageReaderProxyProvider,
+                @Nullable Size postviewSize, int postviewImageFormat) {
+            return new AutoValue_CaptureNode_In(size, inputFormat, outputFormat, isVirtualCamera,
+                    imageReaderProxyProvider, postviewSize, postviewImageFormat,
+                    new Edge<>(), new Edge<>());
         }
     }
 
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/Image2Bitmap.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/Image2Bitmap.java
new file mode 100644
index 0000000..1f0dd6051
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/Image2Bitmap.java
@@ -0,0 +1,107 @@
+/*
+ * 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.camera.core.imagecapture;
+
+import static androidx.camera.core.ImageCapture.ERROR_UNKNOWN;
+import static androidx.camera.core.ImageProcessingUtil.convertYUVToRGB;
+
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.graphics.PixelFormat;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.ImageCaptureException;
+import androidx.camera.core.ImageProxy;
+import androidx.camera.core.ImageReaderProxys;
+import androidx.camera.core.SafeCloseImageReaderProxy;
+import androidx.camera.core.internal.utils.ImageUtil;
+import androidx.camera.core.processing.Operation;
+import androidx.camera.core.processing.Packet;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Convert an {@link ImageProxy} to a {@link Bitmap}.
+ *
+ * <p>An {@link ImageCaptureException} will be thrown if the conversion failed.
+ * Currently it supports only {@link ImageFormat#YUV_420_888} and
+ * {@link ImageFormat#JPEG} image. {@link IllegalArgumentException} will be thrown if the input
+ * image format is not supported.
+ */
+@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+public class Image2Bitmap implements
+        Operation<Packet<ImageProxy>, Bitmap> {
+    @NonNull
+    @Override
+    public Bitmap apply(@NonNull Packet<ImageProxy> imageProxyPacket)
+            throws ImageCaptureException {
+        Bitmap result;
+        SafeCloseImageReaderProxy rgbImageReader = null;
+        try {
+            if (imageProxyPacket.getFormat() == ImageFormat.YUV_420_888) {
+                ImageProxy yuvImage = imageProxyPacket.getData();
+                boolean needFlip = (imageProxyPacket.getRotationDegrees() % 180) != 0;
+                int tempImageReaderWidth = needFlip ? yuvImage.getHeight() : yuvImage.getWidth();
+                int tempImageReaderHeight = needFlip ? yuvImage.getWidth() : yuvImage.getHeight();
+
+                // TODO(b/313548792): remove the usage of ImageReader by creating a version of
+                //  convertYUVToBitmap that also rotates the output.
+                rgbImageReader = new SafeCloseImageReaderProxy(
+                        ImageReaderProxys.createIsolatedReader(
+                                tempImageReaderWidth, tempImageReaderHeight,
+                                PixelFormat.RGBA_8888, 2)
+                );
+
+                ByteBuffer rgbConvertedBuffer = ByteBuffer.allocateDirect(
+                        yuvImage.getWidth() * yuvImage.getHeight() * 4);
+                ImageProxy imageProxyRGB = convertYUVToRGB(
+                        yuvImage,
+                        rgbImageReader,
+                        rgbConvertedBuffer,
+                        imageProxyPacket.getRotationDegrees(),
+                        /* onePixelShiftEnabled */false);
+                yuvImage.close();
+                if (imageProxyRGB == null) {
+                    throw new ImageCaptureException(ERROR_UNKNOWN, "Can't covert YUV to RGB", null);
+                }
+                Bitmap bitmap = ImageUtil.createBitmapFromImageProxy(imageProxyRGB);
+                imageProxyRGB.close();
+                result = bitmap;
+            } else if (imageProxyPacket.getFormat() == ImageFormat.JPEG) {
+                ImageProxy jpegImage = imageProxyPacket.getData();
+                Bitmap bitmap = ImageUtil.createBitmapFromImageProxy(jpegImage);
+                jpegImage.close();
+                result = ImageUtil.rotateBitmap(bitmap, imageProxyPacket.getRotationDegrees());
+            } else {
+                throw new IllegalArgumentException("Invalid postview image format : "
+                        + imageProxyPacket.getFormat());
+            }
+            return result;
+        } catch (UnsupportedOperationException e) {
+            String format = imageProxyPacket.getFormat() == ImageFormat.YUV_420_888
+                    ? "YUV" : "JPEG";
+            throw new ImageCaptureException(ERROR_UNKNOWN,
+                    "Can't convert " + format + " to bitmap", e);
+        } finally {
+            if (rgbImageReader != null) {
+                rgbImageReader.close();
+            }
+        }
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ImagePipeline.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ImagePipeline.java
index 9aeb2b3..6b17899 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ImagePipeline.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ImagePipeline.java
@@ -91,7 +91,17 @@
             @NonNull ImageCaptureConfig useCaseConfig,
             @NonNull Size cameraSurfaceSize) {
         this(useCaseConfig, cameraSurfaceSize, /*cameraEffect=*/ null,
-                /*isVirtualCamera=*/ false, /* postviewSize */ null);
+                /*isVirtualCamera=*/ false, /* postviewSize */ null, ImageFormat.YUV_420_888);
+    }
+
+    @MainThread
+    public ImagePipeline(
+            @NonNull ImageCaptureConfig useCaseConfig,
+            @NonNull Size cameraSurfaceSize,
+            @Nullable CameraEffect cameraEffect,
+            boolean isVirtualCamera) {
+        this(useCaseConfig, cameraSurfaceSize, cameraEffect, isVirtualCamera,
+                null, ImageFormat.YUV_420_888);
     }
 
     @MainThread
@@ -100,7 +110,8 @@
             @NonNull Size cameraSurfaceSize,
             @Nullable CameraEffect cameraEffect,
             boolean isVirtualCamera,
-            @Nullable Size postviewSize) {
+            @Nullable Size postviewSize,
+            int postviewImageFormat) {
         checkMainThread();
         mUseCaseConfig = useCaseConfig;
         mCaptureConfig = CaptureConfig.Builder.createFrom(useCaseConfig).build();
@@ -119,7 +130,8 @@
                 getOutputFormat(),
                 isVirtualCamera,
                 mUseCaseConfig.getImageReaderProxyProvider(),
-                postviewSize);
+                postviewSize,
+                postviewImageFormat);
         CaptureNode.Out captureOut = mCaptureNode.transform(mPipelineIn);
         ProcessingNode.In processingIn = mBundlingNode.transform(captureOut);
         mProcessingNode.transform(processingIn);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingNode.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingNode.java
index e889383..5b57a4f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingNode.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingNode.java
@@ -74,6 +74,7 @@
     private Operation<Packet<byte[]>, Packet<Bitmap>> mJpegBytes2CroppedBitmap;
     private Operation<Packet<ImageProxy>, ImageProxy> mJpegImage2Result;
     private Operation<Packet<byte[]>, Packet<ImageProxy>> mJpegBytes2Image;
+    private Operation<Packet<ImageProxy>, Bitmap> mImage2Bitmap;
     private Operation<Packet<Bitmap>, Packet<Bitmap>> mBitmapEffect;
 
     /**
@@ -110,6 +111,7 @@
                 inputPacket -> {
                     if (inputPacket.getProcessingRequest().isAborted()) {
                         // No-ops if the request is aborted.
+                        inputPacket.getImageProxy().close();
                         return;
                     }
                     mBlockingExecutor.execute(() -> processInputPacket(inputPacket));
@@ -131,6 +133,7 @@
         mBitmap2JpegBytes = new Bitmap2JpegBytes();
         mJpegBytes2Disk = new JpegBytes2Disk();
         mJpegImage2Result = new JpegImage2Result();
+        mImage2Bitmap = new Image2Bitmap();
         if (inputEdge.getInputFormat() == YUV_420_888 || mImageProcessor != null) {
             // Convert JPEG bytes to ImageProxy for:
             // - YUV input: YUV -> JPEG -> ImageProxy
@@ -178,8 +181,8 @@
         ProcessingRequest request = inputPacket.getProcessingRequest();
         try {
             Packet<ImageProxy> image = mInput2Packet.apply(inputPacket);
-            ImageProxy result =  mJpegImage2Result.apply(image);
-            mainThreadExecutor().execute(() -> request.onPostviewImageAvailable(result));
+            Bitmap bitmap = mImage2Bitmap.apply(image);
+            mainThreadExecutor().execute(() -> request.onPostviewBitmapAvailable(bitmap));
         } catch (Exception e) {
             inputPacket.getImageProxy().close();
             Logger.e(TAG, "process postview input packet failed.", e);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingRequest.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingRequest.java
index 807a54f..f112e2d 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingRequest.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/ProcessingRequest.java
@@ -18,6 +18,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.Build;
@@ -149,8 +150,8 @@
         mCallback.onFinalResult(outputFileResults);
     }
 
-    void onPostviewImageAvailable(@NonNull ImageProxy imageProxy) {
-        mCallback.onPostviewImageAvailable(imageProxy);
+    void onPostviewBitmapAvailable(@NonNull Bitmap bitmap) {
+        mCallback.onPostviewBitmapAvailable(bitmap);
     }
 
     /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java
index e01ba85..6cbd546 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java
@@ -21,6 +21,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.graphics.Bitmap;
 import android.os.Build;
 
 import androidx.annotation.MainThread;
@@ -143,6 +144,7 @@
     public void onFinalResult(@NonNull ImageProxy imageProxy) {
         checkMainThread();
         if (mIsAborted) {
+            imageProxy.close();
             // Do not deliver result if the request has been aborted.
             return;
         }
@@ -162,14 +164,14 @@
     }
 
     @Override
-    public void onPostviewImageAvailable(@NonNull ImageProxy imageProxy) {
+    public void onPostviewBitmapAvailable(@NonNull Bitmap bitmap) {
         checkMainThread();
         if (mIsAborted) {
             // Do not deliver result if the request has been aborted.
             return;
         }
 
-        mTakePictureRequest.onPostviewImageAvailable(imageProxy);
+        mTakePictureRequest.onPostviewBitmapAvailable(bitmap);
     }
 
     @MainThread
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/SingleBundlingNode.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/SingleBundlingNode.java
index 73cd04b..8c95d23 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/SingleBundlingNode.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/SingleBundlingNode.java
@@ -103,7 +103,12 @@
     @MainThread
     private void matchPostviewImageWithRequest(@NonNull ImageProxy imageProxy) {
         checkMainThread();
-        checkState(mPendingRequest != null);
+        // if the final image arrives earlier than the post image, mPendingRequest will be set to
+        // null in matchImageWithRequest. In this case, we will ignore the postview processing.
+        if (mPendingRequest == null) {
+            imageProxy.close();
+            return;
+        }
         mOutputEdge.getPostviewEdge().accept(
                 ProcessingNode.InputPacket.of(mPendingRequest, imageProxy));
     }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureCallback.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureCallback.java
index 5b61165..ce23053 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureCallback.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureCallback.java
@@ -16,6 +16,8 @@
 
 package androidx.camera.core.imagecapture;
 
+import android.graphics.Bitmap;
+
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.camera.core.ImageCapture;
@@ -70,9 +72,9 @@
     void onFinalResult(@NonNull ImageProxy imageProxy);
 
     /**
-     * Invoked when the postview image is available.
+     * Invoked when the postview bitmap is available.
      */
-    void onPostviewImageAvailable(@NonNull ImageProxy imageProxy);
+    void onPostviewBitmapAvailable(@NonNull Bitmap bitmap);
 
     /**
      * Invoked when camera fails to return the image.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureRequest.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureRequest.java
index 1851232..5feb8a4 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureRequest.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/TakePictureRequest.java
@@ -21,6 +21,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.Build;
@@ -212,14 +213,14 @@
     }
 
     /**
-     * Delivers postview image result to the app.
+     * Delivers postview bitmap result to the app.
      */
-    void onPostviewImageAvailable(@NonNull ImageProxy imageProxy) {
+    void onPostviewBitmapAvailable(@NonNull Bitmap bitmap) {
         getAppExecutor().execute(() -> {
             if (getOnDiskCallback() != null) {
-                getOnDiskCallback().onPostviewImageAvailable(imageProxy);
+                getOnDiskCallback().onPostviewBitmapAvailable(bitmap);
             } else if (getInMemoryCallback() != null) {
-                getInMemoryCallback().onPostviewImageAvailable(imageProxy);
+                getInMemoryCallback().onPostviewBitmapAvailable(bitmap);
             }
         });
     }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/DynamicRanges.kt b/camera/camera-core/src/main/java/androidx/camera/core/impl/DynamicRanges.kt
new file mode 100644
index 0000000..3137051
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/DynamicRanges.kt
@@ -0,0 +1,130 @@
+/*
+ * 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.camera.core.impl
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.camera.core.DynamicRange
+import androidx.core.util.Preconditions
+
+/**
+ * Utility methods for handling dynamic range.
+ */
+@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+object DynamicRanges {
+
+    /**
+     * Returns `true` if the test dynamic range can resolve to the fully specified dynamic
+     * range set.
+     *
+     * A range can resolve if test fields are unspecified and appropriately match the fields
+     * of the fully specified dynamic range, or the test fields exactly match the fields of
+     * the fully specified dynamic range.
+     */
+    @JvmStatic
+    fun canResolve(
+        dynamicRangeToTest: DynamicRange,
+        fullySpecifiedDynamicRanges: Set<DynamicRange>,
+
+    ): Boolean {
+        return if (dynamicRangeToTest.isFullySpecified) {
+            fullySpecifiedDynamicRanges.contains(dynamicRangeToTest)
+        } else {
+            fullySpecifiedDynamicRanges.firstOrNull { fullySpecifiedDynamicRange ->
+                canResolveUnderSpecifiedTo(
+                    dynamicRangeToTest,
+                    fullySpecifiedDynamicRange
+                )
+            } != null
+        }
+    }
+    /**
+     * Returns a set of all possible matches from a set of dynamic ranges that may contain
+     * under-specified dynamic ranges to a set that contains only fully-specified dynamic ranges.
+     *
+     * A dynamic range can resolve if test fields are unspecified and appropriately match the fields
+     * of the fully specified dynamic range, or the test fields exactly match the fields of
+     * the fully specified dynamic range.
+     */
+    @JvmStatic
+    fun findAllPossibleMatches(
+        dynamicRangesToTest: Set<DynamicRange>,
+        fullySpecifiedDynamicRanges: Set<DynamicRange>
+    ): Set<DynamicRange> {
+        return buildSet {
+            dynamicRangesToTest.forEach {
+                if (it.isFullySpecified) {
+                    // Add matching fully-specified dynamic ranges directly
+                    if (fullySpecifiedDynamicRanges.contains(it)) {
+                        add(it)
+                    }
+                } else {
+                    // Iterate through fully-specified dynamic ranges to find which could be used
+                    // by the corresponding under-specified dynamic ranges
+                    fullySpecifiedDynamicRanges.forEach { fullySpecifiedDynamicRange ->
+                        if (canResolveUnderSpecifiedTo(it, fullySpecifiedDynamicRange)) {
+                            add(fullySpecifiedDynamicRange)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private fun canResolveUnderSpecifiedTo(
+        underSpecifiedDynamicRange: DynamicRange,
+        fullySpecifiedDynamicRange: DynamicRange
+    ): Boolean {
+        return canMatchBitDepth(underSpecifiedDynamicRange, fullySpecifiedDynamicRange) &&
+               canMatchEncoding(underSpecifiedDynamicRange, fullySpecifiedDynamicRange)
+    }
+
+    private fun canMatchBitDepth(
+        dynamicRangeToTest: DynamicRange,
+        fullySpecifiedDynamicRange: DynamicRange
+    ): Boolean {
+        Preconditions.checkState(
+            fullySpecifiedDynamicRange.isFullySpecified, "Fully specified " +
+                "range is not actually fully specified."
+        )
+        return if (dynamicRangeToTest.bitDepth == DynamicRange.BIT_DEPTH_UNSPECIFIED) {
+            true
+        } else {
+            dynamicRangeToTest.bitDepth == fullySpecifiedDynamicRange.bitDepth
+        }
+    }
+
+    private fun canMatchEncoding(
+        dynamicRangeToTest: DynamicRange,
+        fullySpecifiedDynamicRange: DynamicRange
+    ): Boolean {
+        Preconditions.checkState(
+            fullySpecifiedDynamicRange.isFullySpecified, "Fully specified " +
+                "range is not actually fully specified."
+        )
+        val encodingToTest = dynamicRangeToTest.encoding
+        if (encodingToTest == DynamicRange.ENCODING_UNSPECIFIED) {
+            return true
+        }
+        val fullySpecifiedEncoding = fullySpecifiedDynamicRange.encoding
+        return if (encodingToTest == DynamicRange.ENCODING_HDR_UNSPECIFIED &&
+            fullySpecifiedEncoding != DynamicRange.ENCODING_SDR) {
+            true
+        } else {
+            encodingToTest == fullySpecifiedEncoding
+        }
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java
index 5ce2595..fc397ff3 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ForwardingCameraInfo.java
@@ -183,6 +183,13 @@
 
     @NonNull
     @Override
+    public Set<DynamicRange> querySupportedDynamicRanges(
+            @NonNull Set<DynamicRange> candidateDynamicRanges) {
+        return mCameraInfoInternal.querySupportedDynamicRanges(candidateDynamicRanges);
+    }
+
+    @NonNull
+    @Override
     public CameraInfoInternal getImplementation() {
         return mCameraInfoInternal.getImplementation();
     }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/utils/ImageUtil.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/utils/ImageUtil.java
index c198150..3ca31bf 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/utils/ImageUtil.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/utils/ImageUtil.java
@@ -114,6 +114,17 @@
     }
 
     /**
+     * Rotates the bitmap by the given rotation degrees.
+     */
+    @NonNull
+    public static Bitmap rotateBitmap(@NonNull Bitmap bitmap, int rotationDegrees) {
+        Matrix matrix = new Matrix();
+        matrix.postRotate(rotationDegrees);
+        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,
+                true);
+    }
+
+    /**
      * Creates a direct {@link ByteBuffer} and copy the content of the {@link Bitmap}.
      */
     @NonNull
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
index 94583c4..5477b9c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
@@ -26,7 +26,6 @@
 import android.graphics.Bitmap;
 import android.graphics.ImageFormat;
 import android.graphics.SurfaceTexture;
-import android.opengl.Matrix;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.util.Size;
@@ -314,17 +313,13 @@
     private Bitmap getBitmap(@NonNull Size size,
             @NonNull float[] textureTransform,
             int rotationDegrees) {
-        float[] snapshotTransform = new float[16];
-        Matrix.setIdentityM(snapshotTransform, 0);
-
-        // Flip the snapshot. This is for reverting the GL transform added in SurfaceOutputImpl.
-        MatrixExt.preVerticalFlip(snapshotTransform, 0.5f);
+        float[] snapshotTransform = textureTransform.clone();
 
         // Rotate the output if requested.
         MatrixExt.preRotate(snapshotTransform, rotationDegrees, 0.5f, 0.5f);
 
-        // Apply the texture transform.
-        Matrix.multiplyMM(snapshotTransform, 0, snapshotTransform, 0, textureTransform, 0);
+        // Flip the snapshot. This is for reverting the GL transform added in SurfaceOutputImpl.
+        MatrixExt.preVerticalFlip(snapshotTransform, 0.5f);
 
         // Update the size based on the rotation degrees.
         size = rotateSize(size, rotationDegrees);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
index f614de1..287eed3 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
@@ -42,6 +42,7 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.CameraEffect;
 import androidx.camera.core.ImageCapture;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.impl.CameraInfoInternal;
@@ -80,7 +81,7 @@
     private final StreamSharingConfig mDefaultConfig;
 
     @NonNull
-    private final VirtualCamera mVirtualCamera;
+    private final VirtualCameraAdapter mVirtualCameraAdapter;
     // Node that applies effect to the input.
     @Nullable
     private SurfaceProcessorNode mEffectNode;
@@ -114,7 +115,6 @@
         return new StreamSharingConfig(OptionsBundle.from(mutableConfig));
     }
 
-
     /**
      * Constructs a {@link StreamSharing} with a parent {@link CameraInternal}, children
      * {@link UseCase}s, and a {@link UseCaseConfigFactory} for getting default {@link UseCase}
@@ -125,17 +125,17 @@
             @NonNull UseCaseConfigFactory useCaseConfigFactory) {
         super(getDefaultConfig(children));
         mDefaultConfig = getDefaultConfig(children);
-        mVirtualCamera = new VirtualCamera(parentCamera, children, useCaseConfigFactory,
-                (jpegQuality, rotationDegrees) -> {
-                    SurfaceProcessorNode sharingNode = mSharingNode;
-                    if (sharingNode != null) {
-                        return sharingNode.getSurfaceProcessor().snapshot(
-                                jpegQuality, rotationDegrees);
-                    } else {
-                        return Futures.immediateFailedFuture(new Exception(
-                                "Failed to take picture: pipeline is not ready."));
-                    }
-                });
+        mVirtualCameraAdapter = new VirtualCameraAdapter(
+                parentCamera, children, useCaseConfigFactory, (jpegQuality, rotationDegrees) -> {
+            SurfaceProcessorNode sharingNode = mSharingNode;
+            if (sharingNode != null) {
+                return sharingNode.getSurfaceProcessor().snapshot(
+                        jpegQuality, rotationDegrees);
+            } else {
+                return Futures.immediateFailedFuture(new Exception(
+                        "Failed to take picture: pipeline is not ready."));
+            }
+        });
     }
 
     @Nullable
@@ -164,7 +164,7 @@
     @Override
     protected UseCaseConfig<?> onMergeConfig(@NonNull CameraInfoInternal cameraInfo,
             @NonNull UseCaseConfig.Builder<?, ?, ?> builder) {
-        mVirtualCamera.mergeChildrenConfigs(builder.getMutableConfig());
+        mVirtualCameraAdapter.mergeChildrenConfigs(builder.getMutableConfig());
         return builder.getUseCaseConfig();
     }
 
@@ -192,31 +192,31 @@
     @Override
     public void onBind() {
         super.onBind();
-        mVirtualCamera.bindChildren();
+        mVirtualCameraAdapter.bindChildren();
     }
 
     @Override
     public void onUnbind() {
         super.onUnbind();
         clearPipeline();
-        mVirtualCamera.unbindChildren();
+        mVirtualCameraAdapter.unbindChildren();
     }
 
     @Override
     public void onStateAttached() {
         super.onStateAttached();
-        mVirtualCamera.notifyStateAttached();
+        mVirtualCameraAdapter.notifyStateAttached();
     }
 
     @Override
     public void onStateDetached() {
         super.onStateDetached();
-        mVirtualCamera.notifyStateDetached();
+        mVirtualCameraAdapter.notifyStateDetached();
     }
 
     @NonNull
     public Set<UseCase> getChildren() {
-        return mVirtualCamera.getChildren();
+        return mVirtualCameraAdapter.getChildren();
     }
 
     /**
@@ -257,7 +257,8 @@
 
         // Transform the input based on virtual camera configuration.
         Map<UseCase, SurfaceProcessorNode.OutConfig> outConfigMap =
-                mVirtualCamera.getChildrenOutConfigs(mSharingInputEdge);
+                mVirtualCameraAdapter.getChildrenOutConfigs(mSharingInputEdge,
+                        getTargetRotationInternal());
         SurfaceProcessorNode.Out out = mSharingNode.transform(
                 SurfaceProcessorNode.In.of(mSharingInputEdge,
                         new ArrayList<>(outConfigMap.values())));
@@ -267,7 +268,7 @@
         for (Map.Entry<UseCase, SurfaceProcessorNode.OutConfig> entry : outConfigMap.entrySet()) {
             outputEdges.put(entry.getKey(), out.get(entry.getValue()));
         }
-        mVirtualCamera.setChildrenEdges(outputEdges);
+        mVirtualCameraAdapter.setChildrenEdges(outputEdges);
 
         // Send the camera edge Surface to the camera2.
         SessionConfig.Builder builder = SessionConfig.Builder.createFrom(config,
@@ -276,7 +277,8 @@
         propagateChildrenCamera2Interop(streamSpec.getResolution(), builder);
 
         builder.addSurface(mCameraEdge.getDeferrableSurface());
-        builder.addRepeatingCameraCaptureCallback(mVirtualCamera.getParentMetadataCallback());
+        builder.addRepeatingCameraCaptureCallback(
+                mVirtualCameraAdapter.getParentMetadataCallback());
         if (streamSpec.getImplementationOptions() != null) {
             builder.addImplementationOptions(streamSpec.getImplementationOptions());
         }
@@ -318,7 +320,7 @@
         mEffectNode = new SurfaceProcessorNode(camera,
                 getEffect().createSurfaceProcessorInternal());
         // Effect does not apply rotation.
-        int rotationAppliedByEffect = 0;
+        int rotationAppliedByEffect = getRotationAppliedByEffect();
         SurfaceProcessorNode.OutConfig outConfig = SurfaceProcessorNode.OutConfig.of(
                 cameraEdge.getTargets(),
                 cameraEdge.getFormat(),
@@ -332,6 +334,18 @@
         return requireNonNull(out.get(outConfig));
     }
 
+    private int getRotationAppliedByEffect() {
+        CameraEffect effect = checkNotNull(getEffect());
+        if (effect.getTransformation() == CameraEffect.TRANSFORMATION_CAMERA_AND_SURFACE_ROTATION) {
+            // Apply the rotation degrees if the effect is configured to do so.
+            // TODO: handle this option in VideoCapture.
+            return getRelativeRotation(checkNotNull(getCamera()));
+        } else {
+            // By default, the effect node does not apply any rotation.
+            return 0;
+        }
+    }
+
     private void addCameraErrorListener(
             @NonNull SessionConfig.Builder sessionConfigBuilder,
             @NonNull String cameraId,
@@ -349,7 +363,7 @@
                 // children UseCase does not have additional logic in SessionConfig error listener
                 // so this is OK. If they do, we need to invoke the children's SessionConfig
                 // error listeners instead.
-                mVirtualCamera.resetChildren();
+                mVirtualCameraAdapter.resetChildren();
             }
         });
     }
@@ -409,8 +423,8 @@
 
     @VisibleForTesting
     @NonNull
-    VirtualCamera getVirtualCamera() {
-        return mVirtualCamera;
+    VirtualCameraAdapter getVirtualCameraAdapter() {
+        return mVirtualCameraAdapter;
     }
 
     /**
@@ -437,4 +451,10 @@
     public static boolean isStreamSharing(@Nullable UseCase useCase) {
         return useCase instanceof StreamSharing;
     }
+
+    @VisibleForTesting
+    @Nullable
+    public SurfaceEdge getSharingInputEdge() {
+        return mSharingInputEdge;
+    }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java
index 2d939b7..4d3ad88 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java
@@ -15,63 +15,22 @@
  */
 package androidx.camera.core.streamsharing;
 
-import static androidx.camera.core.CameraEffect.IMAGE_CAPTURE;
-import static androidx.camera.core.CameraEffect.PREVIEW;
-import static androidx.camera.core.CameraEffect.VIDEO_CAPTURE;
-import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
-import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_DYNAMIC_RANGE;
-import static androidx.camera.core.impl.ImageOutputConfig.OPTION_CUSTOM_ORDERED_RESOLUTIONS;
-import static androidx.camera.core.impl.UseCaseConfig.OPTION_PREVIEW_STABILIZATION_MODE;
-import static androidx.camera.core.impl.UseCaseConfig.OPTION_SURFACE_OCCUPANCY_PRIORITY;
-import static androidx.camera.core.impl.UseCaseConfig.OPTION_VIDEO_STABILIZATION_MODE;
 import static androidx.camera.core.impl.utils.Threads.checkMainThread;
-import static androidx.camera.core.impl.utils.TransformUtils.getRotatedSize;
-import static androidx.camera.core.impl.utils.TransformUtils.rectToSize;
-import static androidx.camera.core.streamsharing.DynamicRangeUtils.resolveDynamicRange;
-import static androidx.camera.core.streamsharing.ResolutionUtils.getMergedResolutions;
-import static androidx.core.util.Preconditions.checkState;
 
-import static java.util.Objects.requireNonNull;
-
-import android.graphics.ImageFormat;
 import android.os.Build;
-import android.util.Size;
 
-import androidx.annotation.IntRange;
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
-import androidx.annotation.VisibleForTesting;
-import androidx.camera.core.CameraEffect;
-import androidx.camera.core.DynamicRange;
-import androidx.camera.core.ImageCapture;
-import androidx.camera.core.Preview;
 import androidx.camera.core.UseCase;
-import androidx.camera.core.impl.CameraCaptureCallback;
-import androidx.camera.core.impl.CameraCaptureResult;
 import androidx.camera.core.impl.CameraControlInternal;
 import androidx.camera.core.impl.CameraInfoInternal;
 import androidx.camera.core.impl.CameraInternal;
-import androidx.camera.core.impl.DeferrableSurface;
-import androidx.camera.core.impl.MutableConfig;
 import androidx.camera.core.impl.Observable;
-import androidx.camera.core.impl.SessionConfig;
-import androidx.camera.core.impl.UseCaseConfig;
-import androidx.camera.core.impl.UseCaseConfigFactory;
-import androidx.camera.core.impl.stabilization.StabilizationMode;
-import androidx.camera.core.processing.SurfaceEdge;
-import androidx.camera.core.processing.SurfaceProcessorNode.OutConfig;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * A virtual implementation of {@link CameraInternal}.
@@ -82,249 +41,65 @@
 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 class VirtualCamera implements CameraInternal {
     private static final String UNSUPPORTED_MESSAGE = "Operation not supported by VirtualCamera.";
-    // Children UseCases associated with this virtual camera.
-    @NonNull
-    final Set<UseCase> mChildren;
-    // Specs for children UseCase, calculated and set by StreamSharing.
-    @NonNull
-    final Map<UseCase, SurfaceEdge> mChildrenEdges = new HashMap<>();
-    // Whether a children is in the active state. See: UseCase.State.ACTIVE
-    @NonNull
-    final Map<UseCase, Boolean> mChildrenActiveState = new HashMap<>();
-    // Config factory for getting children's config.
-    @NonNull
-    private final UseCaseConfigFactory mUseCaseConfigFactory;
     // The parent camera instance.
     @NonNull
     private final CameraInternal mParentCamera;
-    // The callback that receives the parent camera's metadata.
-    @NonNull
-    private final CameraCaptureCallback mParentMetadataCallback = createCameraCaptureCallback();
     @NonNull
     private final VirtualCameraControl mVirtualCameraControl;
     @NonNull
     private final VirtualCameraInfo mVirtualCameraInfo;
 
+    private final UseCase.StateChangeCallback mStateChangeCallback;
+
     /**
-     * @param parentCamera         the parent {@link CameraInternal} instance. For example, the
-     *                             real camera.
-     * @param children             the children {@link UseCase}.
-     * @param useCaseConfigFactory the factory for configuring children {@link UseCase}.
+     * @param parentCamera the parent {@link CameraInternal} instance. For example, the
+     *                     real camera.
      */
     VirtualCamera(@NonNull CameraInternal parentCamera,
-            @NonNull Set<UseCase> children,
-            @NonNull UseCaseConfigFactory useCaseConfigFactory,
+            @NonNull UseCase.StateChangeCallback useCaseStateCallback,
             @NonNull StreamSharing.Control streamSharingControl) {
         mParentCamera = parentCamera;
-        mUseCaseConfigFactory = useCaseConfigFactory;
-        mChildren = children;
+        mStateChangeCallback = useCaseStateCallback;
         mVirtualCameraControl = new VirtualCameraControl(parentCamera.getCameraControlInternal(),
                 streamSharingControl);
         mVirtualCameraInfo = new VirtualCameraInfo(parentCamera.getCameraInfoInternal());
-        // Set children state to inactive by default.
-        for (UseCase child : children) {
-            mChildrenActiveState.put(child, false);
-        }
-    }
-
-    // --- API for StreamSharing ---
-    void mergeChildrenConfigs(@NonNull MutableConfig mutableConfig) {
-        Set<UseCaseConfig<?>> childrenConfigs = new HashSet<>();
-        for (UseCase useCase : mChildren) {
-            childrenConfigs.add(useCase.mergeConfigs(mParentCamera.getCameraInfoInternal(),
-                    null,
-                    useCase.getDefaultConfig(true, mUseCaseConfigFactory)));
-        }
-
-        // Merge resolution configs.
-        List<Size> cameraSupportedResolutions =
-                new ArrayList<>(mParentCamera.getCameraInfoInternal().getSupportedResolutions(
-                        INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE));
-        Size sensorSize = rectToSize(mParentCamera.getCameraControlInternal().getSensorRect());
-        List<Size> mergedResolutions = getMergedResolutions(cameraSupportedResolutions, sensorSize,
-                mutableConfig, childrenConfigs);
-        mutableConfig.insertOption(OPTION_CUSTOM_ORDERED_RESOLUTIONS, mergedResolutions);
-
-        // Merge Surface occupancy priority.
-        mutableConfig.insertOption(OPTION_SURFACE_OCCUPANCY_PRIORITY,
-                getHighestSurfacePriority(childrenConfigs));
-
-        // Merge dynamic range configs. Try to find a dynamic range that can match all child
-        // requirements, or throw an exception if no matching dynamic range.
-        //  TODO: This approach works for the current code base, where only VideoCapture can be
-        //   configured (Preview follows the settings, ImageCapture is fixed as SDR). When
-        //   dynamic range APIs opened on other use cases, we might want a more advanced approach
-        //   that allows conflicts, e.g. converting HDR stream to SDR stream.
-        DynamicRange dynamicRange = resolveDynamicRange(childrenConfigs);
-        if (dynamicRange == null) {
-            throw new IllegalArgumentException("Failed to merge child dynamic ranges, can not find"
-                    + " a dynamic range that satisfies all children.");
-        }
-        mutableConfig.insertOption(OPTION_INPUT_DYNAMIC_RANGE, dynamicRange);
-
-        // Merge Preview stabilization and video stabilization configs.
-        for (UseCase useCase : mChildren) {
-            if (useCase.getCurrentConfig().getVideoStabilizationMode()
-                    != StabilizationMode.UNSPECIFIED) {
-                mutableConfig.insertOption(OPTION_VIDEO_STABILIZATION_MODE,
-                        useCase.getCurrentConfig().getVideoStabilizationMode());
-            }
-
-            if (useCase.getCurrentConfig().getPreviewStabilizationMode()
-                    != StabilizationMode.UNSPECIFIED) {
-                mutableConfig.insertOption(OPTION_PREVIEW_STABILIZATION_MODE,
-                        useCase.getCurrentConfig().getPreviewStabilizationMode());
-            }
-        }
-    }
-
-    void bindChildren() {
-        for (UseCase useCase : mChildren) {
-            useCase.bindToCamera(this, null,
-                    useCase.getDefaultConfig(true, mUseCaseConfigFactory));
-        }
-    }
-
-    void unbindChildren() {
-        for (UseCase useCase : mChildren) {
-            useCase.unbindFromCamera(this);
-        }
-    }
-
-    void notifyStateAttached() {
-        for (UseCase useCase : mChildren) {
-            useCase.onStateAttached();
-        }
-    }
-
-    void notifyStateDetached() {
-        for (UseCase useCase : mChildren) {
-            useCase.onStateDetached();
-        }
-    }
-
-    @NonNull
-    Set<UseCase> getChildren() {
-        return mChildren;
     }
 
     /**
-     * Gets {@link OutConfig} for children {@link UseCase} based on the input edge.
+     * Sets the rotation applied by this virtual camera.
      */
-    @NonNull
-    Map<UseCase, OutConfig> getChildrenOutConfigs(@NonNull SurfaceEdge cameraEdge) {
-        Map<UseCase, OutConfig> outConfigs = new HashMap<>();
-        for (UseCase useCase : mChildren) {
-            // TODO(b/264936115): This is a temporary solution where children use the parent
-            //  stream without changing it. Later we will update it to allow
-            //  cropping/down-sampling to better match children UseCase config.
-            int rotationDegrees = getChildRotationDegrees(useCase);
-            outConfigs.put(useCase, OutConfig.of(
-                    getChildTargetType(useCase),
-                    getChildFormat(useCase),
-                    cameraEdge.getCropRect(),
-                    getRotatedSize(cameraEdge.getCropRect(), rotationDegrees),
-                    rotationDegrees,
-                    useCase.isMirroringRequired(this)));
-        }
-        return outConfigs;
+    void setRotationDegrees(int sensorRotationDegrees) {
+        mVirtualCameraInfo.setVirtualCameraRotationDegrees(sensorRotationDegrees);
     }
 
-    /**
-     * Update children {@link SurfaceEdge} calculated by {@link StreamSharing}.
-     */
-    void setChildrenEdges(@NonNull Map<UseCase, SurfaceEdge> childrenEdges) {
-        mChildrenEdges.clear();
-        mChildrenEdges.putAll(childrenEdges);
-        for (Map.Entry<UseCase, SurfaceEdge> entry : mChildrenEdges.entrySet()) {
-            UseCase useCase = entry.getKey();
-            SurfaceEdge surfaceEdge = entry.getValue();
-            useCase.setViewPortCropRect(surfaceEdge.getCropRect());
-            useCase.setSensorToBufferTransformMatrix(surfaceEdge.getSensorToBufferTransform());
-            useCase.updateSuggestedStreamSpec(surfaceEdge.getStreamSpec());
-            useCase.notifyState();
-        }
-    }
+    // --- Forward UseCase state change to VirtualCameraAdapter ---
 
-    /**
-     * Invokes {@link UseCase.StateChangeCallback#onUseCaseReset} for all children.
-     */
-    void resetChildren() {
-        checkMainThread();
-        for (UseCase useCase : mChildren) {
-            onUseCaseReset(useCase);
-        }
-    }
-
-    /**
-     * Gets the callback for receiving parent camera's metadata.
-     */
-    @NonNull
-    CameraCaptureCallback getParentMetadataCallback() {
-        return mParentMetadataCallback;
-    }
-
-    // --- Handle children state change ---
     @MainThread
     @Override
     public void onUseCaseActive(@NonNull UseCase useCase) {
         checkMainThread();
-        if (isUseCaseActive(useCase)) {
-            return;
-        }
-        mChildrenActiveState.put(useCase, true);
-        DeferrableSurface childSurface = getChildSurface(useCase);
-        if (childSurface != null) {
-            forceSetProvider(getUseCaseEdge(useCase), childSurface, useCase.getSessionConfig());
-        }
+        mStateChangeCallback.onUseCaseActive(useCase);
     }
 
     @MainThread
     @Override
     public void onUseCaseInactive(@NonNull UseCase useCase) {
         checkMainThread();
-        if (!isUseCaseActive(useCase)) {
-            return;
-        }
-        mChildrenActiveState.put(useCase, false);
-        getUseCaseEdge(useCase).disconnect();
+        mStateChangeCallback.onUseCaseInactive(useCase);
     }
 
     @MainThread
     @Override
     public void onUseCaseUpdated(@NonNull UseCase useCase) {
         checkMainThread();
-        if (!isUseCaseActive(useCase)) {
-            // No-op if the child is inactive. It will connect when it becomes active.
-            return;
-        }
-        SurfaceEdge edge = getUseCaseEdge(useCase);
-        DeferrableSurface childSurface = getChildSurface(useCase);
-        if (childSurface != null) {
-            // If the child has a Surface, connect. VideoCapture uses this mechanism to
-            // resume/start recording.
-            forceSetProvider(edge, childSurface, useCase.getSessionConfig());
-        } else {
-            // If the child has no Surface, disconnect. VideoCapture uses this mechanism to
-            // pause/stop recording.
-            edge.disconnect();
-        }
+        mStateChangeCallback.onUseCaseUpdated(useCase);
     }
 
     @MainThread
     @Override
     public void onUseCaseReset(@NonNull UseCase useCase) {
         checkMainThread();
-        SurfaceEdge edge = getUseCaseEdge(useCase);
-        edge.invalidate();
-        if (!isUseCaseActive(useCase)) {
-            // No-op if the child is inactive. It will connect when it becomes active.
-            return;
-        }
-        DeferrableSurface childSurface = getChildSurface(useCase);
-        if (childSurface != null) {
-            forceSetProvider(edge, childSurface, useCase.getSessionConfig());
-        }
+        mStateChangeCallback.onUseCaseReset(useCase);
     }
 
     // --- Forward parent camera properties and events ---
@@ -352,112 +127,8 @@
         return mParentCamera.getCameraState();
     }
 
-    // --- private methods ---
-
-    @IntRange(from = 0, to = 359)
-    private int getChildRotationDegrees(@NonNull UseCase child) {
-        if (child instanceof Preview) {
-            // Rotate the buffer for Preview because SurfaceView cannot handle rotation.
-            return mParentCamera.getCameraInfo().getSensorRotationDegrees(
-                    ((Preview) child).getTargetRotation());
-        }
-        // By default, sharing node does not rotate
-        return 0;
-    }
-
-    private static int getChildFormat(@NonNull UseCase useCase) {
-        return useCase instanceof ImageCapture ? ImageFormat.JPEG
-                : INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
-    }
-
-    @CameraEffect.Targets
-    private static int getChildTargetType(@NonNull UseCase useCase) {
-        if (useCase instanceof Preview) {
-            return PREVIEW;
-        } else if (useCase instanceof ImageCapture) {
-            return IMAGE_CAPTURE;
-        } else {
-            return VIDEO_CAPTURE;
-        }
-    }
-
-    private static int getHighestSurfacePriority(Set<UseCaseConfig<?>> childrenConfigs) {
-        int highestPriority = 0;
-        for (UseCaseConfig<?> childConfig : childrenConfigs) {
-            highestPriority = Math.max(highestPriority,
-                    childConfig.getSurfaceOccupancyPriority(0));
-        }
-        return highestPriority;
-    }
-
-    @NonNull
-    private SurfaceEdge getUseCaseEdge(@NonNull UseCase useCase) {
-        return requireNonNull(mChildrenEdges.get(useCase));
-    }
-
-    private boolean isUseCaseActive(@NonNull UseCase useCase) {
-        return requireNonNull(mChildrenActiveState.get(useCase));
-    }
-
-    private void forceSetProvider(@NonNull SurfaceEdge edge,
-            @NonNull DeferrableSurface childSurface,
-            @NonNull SessionConfig childSessionConfig) {
-        edge.invalidate();
-        try {
-            edge.setProvider(childSurface);
-        } catch (DeferrableSurface.SurfaceClosedException e) {
-            // The Surface is closed by the child. This will happen when e.g. the child is Preview
-            // with SurfaceView implementation.
-            // Invoke the error listener so it will recreate the pipeline.
-            for (SessionConfig.ErrorListener listener : childSessionConfig.getErrorListeners()) {
-                listener.onError(childSessionConfig,
-                        SessionConfig.SessionError.SESSION_ERROR_SURFACE_NEEDS_RESET);
-            }
-        }
-    }
-
-    /**
-     * Gets the {@link DeferrableSurface} associated with the child.
-     */
-    @VisibleForTesting
-    @Nullable
-    static DeferrableSurface getChildSurface(@NonNull UseCase child) {
-        // Get repeating Surface for preview & video, regular Surface for image capture.
-        List<DeferrableSurface> surfaces = child instanceof ImageCapture
-                ? child.getSessionConfig().getSurfaces() :
-                child.getSessionConfig().getRepeatingCaptureConfig().getSurfaces();
-        checkState(surfaces.size() <= 1);
-        if (surfaces.size() == 1) {
-            return surfaces.get(0);
-        }
-        return null;
-    }
-
-    CameraCaptureCallback createCameraCaptureCallback() {
-        return new CameraCaptureCallback() {
-            @Override
-            public void onCaptureCompleted(@NonNull CameraCaptureResult cameraCaptureResult) {
-                super.onCaptureCompleted(cameraCaptureResult);
-                for (UseCase child : mChildren) {
-                    sendCameraCaptureResultToChild(cameraCaptureResult,
-                            child.getSessionConfig());
-                }
-            }
-        };
-    }
-
-    static void sendCameraCaptureResultToChild(
-            @NonNull CameraCaptureResult cameraCaptureResult,
-            @NonNull SessionConfig sessionConfig) {
-        for (CameraCaptureCallback callback :
-                sessionConfig.getRepeatingCameraCaptureCallbacks()) {
-            callback.onCaptureCompleted(new VirtualCameraCaptureResult(
-                    sessionConfig.getRepeatingCaptureConfig().getTagBundle(),
-                    cameraCaptureResult));
-        }
-    }
-
     // --- Unused overrides ---
+
     @Override
     public void open() {
         throw new UnsupportedOperationException(UNSUPPORTED_MESSAGE);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraAdapter.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraAdapter.java
new file mode 100644
index 0000000..6323d6c
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraAdapter.java
@@ -0,0 +1,437 @@
+/*
+ * 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.camera.core.streamsharing;
+
+import static androidx.camera.core.CameraEffect.IMAGE_CAPTURE;
+import static androidx.camera.core.CameraEffect.PREVIEW;
+import static androidx.camera.core.CameraEffect.VIDEO_CAPTURE;
+import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
+import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_DYNAMIC_RANGE;
+import static androidx.camera.core.impl.ImageOutputConfig.OPTION_CUSTOM_ORDERED_RESOLUTIONS;
+import static androidx.camera.core.impl.UseCaseConfig.OPTION_PREVIEW_STABILIZATION_MODE;
+import static androidx.camera.core.impl.UseCaseConfig.OPTION_SURFACE_OCCUPANCY_PRIORITY;
+import static androidx.camera.core.impl.UseCaseConfig.OPTION_VIDEO_STABILIZATION_MODE;
+import static androidx.camera.core.impl.utils.Threads.checkMainThread;
+import static androidx.camera.core.impl.utils.TransformUtils.getRotatedSize;
+import static androidx.camera.core.impl.utils.TransformUtils.rectToSize;
+import static androidx.camera.core.impl.utils.TransformUtils.within360;
+import static androidx.camera.core.streamsharing.DynamicRangeUtils.resolveDynamicRange;
+import static androidx.camera.core.streamsharing.ResolutionUtils.getMergedResolutions;
+import static androidx.core.util.Preconditions.checkState;
+
+import static java.util.Objects.requireNonNull;
+
+import android.graphics.ImageFormat;
+import android.os.Build;
+import android.util.Size;
+import android.view.Surface;
+
+import androidx.annotation.IntRange;
+import androidx.annotation.MainThread;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.CameraEffect;
+import androidx.camera.core.DynamicRange;
+import androidx.camera.core.ImageCapture;
+import androidx.camera.core.Preview;
+import androidx.camera.core.UseCase;
+import androidx.camera.core.impl.CameraCaptureCallback;
+import androidx.camera.core.impl.CameraCaptureResult;
+import androidx.camera.core.impl.CameraInternal;
+import androidx.camera.core.impl.DeferrableSurface;
+import androidx.camera.core.impl.ImageOutputConfig;
+import androidx.camera.core.impl.MutableConfig;
+import androidx.camera.core.impl.SessionConfig;
+import androidx.camera.core.impl.UseCaseConfig;
+import androidx.camera.core.impl.UseCaseConfigFactory;
+import androidx.camera.core.impl.stabilization.StabilizationMode;
+import androidx.camera.core.processing.SurfaceEdge;
+import androidx.camera.core.processing.SurfaceProcessorNode.OutConfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A virtual implementation of {@link CameraInternal}.
+ *
+ * <p> This class manages children {@link UseCase} and connects/disconnects them to the
+ * parent {@link StreamSharing}. It also forwards parent camera properties/events to the children.
+ */
+@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+class VirtualCameraAdapter implements UseCase.StateChangeCallback {
+
+    // Children UseCases associated with this virtual camera.
+    @NonNull
+    final Set<UseCase> mChildren;
+    // Specs for children UseCase, calculated and set by StreamSharing.
+    @NonNull
+    final Map<UseCase, SurfaceEdge> mChildrenEdges = new HashMap<>();
+    @NonNull
+    private final Map<UseCase, VirtualCamera> mChildrenVirtualCameras = new HashMap<>();
+    // Whether a children is in the active state. See: UseCase.State.ACTIVE
+    @NonNull
+    final Map<UseCase, Boolean> mChildrenActiveState = new HashMap<>();
+    // Config factory for getting children's config.
+    @NonNull
+    private final UseCaseConfigFactory mUseCaseConfigFactory;
+    // The parent camera instance.
+    @NonNull
+    private final CameraInternal mParentCamera;
+    // The callback that receives the parent camera's metadata.
+    @NonNull
+    private final CameraCaptureCallback mParentMetadataCallback = createCameraCaptureCallback();
+
+
+    /**
+     * @param parentCamera         the parent {@link CameraInternal} instance. For example, the
+     *                             real camera.
+     * @param children             the children {@link UseCase}.
+     * @param useCaseConfigFactory the factory for configuring children {@link UseCase}.
+     */
+    VirtualCameraAdapter(@NonNull CameraInternal parentCamera,
+            @NonNull Set<UseCase> children,
+            @NonNull UseCaseConfigFactory useCaseConfigFactory,
+            @NonNull StreamSharing.Control streamSharingControl) {
+        mParentCamera = parentCamera;
+        mUseCaseConfigFactory = useCaseConfigFactory;
+        mChildren = children;
+        // Set children state to inactive by default.
+        for (UseCase child : children) {
+            mChildrenActiveState.put(child, false);
+            mChildrenVirtualCameras.put(child, new VirtualCamera(
+                    parentCamera,
+                    this,
+                    streamSharingControl));
+        }
+    }
+
+    // --- API for StreamSharing ---
+    void mergeChildrenConfigs(@NonNull MutableConfig mutableConfig) {
+        Set<UseCaseConfig<?>> childrenConfigs = new HashSet<>();
+        for (UseCase useCase : mChildren) {
+            childrenConfigs.add(useCase.mergeConfigs(mParentCamera.getCameraInfoInternal(),
+                    null,
+                    useCase.getDefaultConfig(true, mUseCaseConfigFactory)));
+        }
+
+        // Merge resolution configs.
+        List<Size> cameraSupportedResolutions =
+                new ArrayList<>(mParentCamera.getCameraInfoInternal().getSupportedResolutions(
+                        INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE));
+        Size sensorSize = rectToSize(mParentCamera.getCameraControlInternal().getSensorRect());
+        List<Size> mergedResolutions = getMergedResolutions(cameraSupportedResolutions, sensorSize,
+                mutableConfig, childrenConfigs);
+        mutableConfig.insertOption(OPTION_CUSTOM_ORDERED_RESOLUTIONS, mergedResolutions);
+
+        // Merge Surface occupancy priority.
+        mutableConfig.insertOption(OPTION_SURFACE_OCCUPANCY_PRIORITY,
+                getHighestSurfacePriority(childrenConfigs));
+
+        // Merge dynamic range configs. Try to find a dynamic range that can match all child
+        // requirements, or throw an exception if no matching dynamic range.
+        //  TODO: This approach works for the current code base, where only VideoCapture can be
+        //   configured (Preview follows the settings, ImageCapture is fixed as SDR). When
+        //   dynamic range APIs opened on other use cases, we might want a more advanced approach
+        //   that allows conflicts, e.g. converting HDR stream to SDR stream.
+        DynamicRange dynamicRange = resolveDynamicRange(childrenConfigs);
+        if (dynamicRange == null) {
+            throw new IllegalArgumentException("Failed to merge child dynamic ranges, can not find"
+                    + " a dynamic range that satisfies all children.");
+        }
+        mutableConfig.insertOption(OPTION_INPUT_DYNAMIC_RANGE, dynamicRange);
+
+        // Merge Preview stabilization and video stabilization configs.
+        for (UseCase useCase : mChildren) {
+            if (useCase.getCurrentConfig().getVideoStabilizationMode()
+                    != StabilizationMode.UNSPECIFIED) {
+                mutableConfig.insertOption(OPTION_VIDEO_STABILIZATION_MODE,
+                        useCase.getCurrentConfig().getVideoStabilizationMode());
+            }
+
+            if (useCase.getCurrentConfig().getPreviewStabilizationMode()
+                    != StabilizationMode.UNSPECIFIED) {
+                mutableConfig.insertOption(OPTION_PREVIEW_STABILIZATION_MODE,
+                        useCase.getCurrentConfig().getPreviewStabilizationMode());
+            }
+        }
+    }
+
+    void bindChildren() {
+        for (UseCase useCase : mChildren) {
+            useCase.bindToCamera(
+                    requireNonNull(mChildrenVirtualCameras.get(useCase)),
+                    null,
+                    useCase.getDefaultConfig(true, mUseCaseConfigFactory));
+        }
+    }
+
+    void unbindChildren() {
+        for (UseCase useCase : mChildren) {
+            useCase.unbindFromCamera(requireNonNull(mChildrenVirtualCameras.get(useCase)));
+        }
+    }
+
+    void notifyStateAttached() {
+        for (UseCase useCase : mChildren) {
+            useCase.onStateAttached();
+        }
+    }
+
+    void notifyStateDetached() {
+        for (UseCase useCase : mChildren) {
+            useCase.onStateDetached();
+        }
+    }
+
+    @NonNull
+    Set<UseCase> getChildren() {
+        return mChildren;
+    }
+
+    /**
+     * Gets {@link OutConfig} for children {@link UseCase} based on the input edge.
+     */
+    @NonNull
+    Map<UseCase, OutConfig> getChildrenOutConfigs(@NonNull SurfaceEdge cameraEdge,
+            @ImageOutputConfig.RotationValue int parentTargetRotation) {
+        Map<UseCase, OutConfig> outConfigs = new HashMap<>();
+        int parentRotationDegrees = mParentCamera.getCameraInfo().getSensorRotationDegrees(
+                parentTargetRotation);
+        for (UseCase useCase : mChildren) {
+            // TODO(b/264936115): This is a temporary solution where children use the parent
+            //  stream without changing it. Later we will update it to allow
+            //  cropping/down-sampling to better match children UseCase config.
+            int childRotationDegrees = getChildRotationDegrees(useCase);
+            requireNonNull(mChildrenVirtualCameras.get(useCase))
+                    .setRotationDegrees(childRotationDegrees);
+            int childParentDelta = within360(
+                    cameraEdge.getRotationDegrees() + childRotationDegrees - parentRotationDegrees);
+            outConfigs.put(useCase, OutConfig.of(
+                    getChildTargetType(useCase),
+                    getChildFormat(useCase),
+                    cameraEdge.getCropRect(),
+                    getRotatedSize(cameraEdge.getCropRect(), childParentDelta),
+                    childParentDelta,
+                    useCase.isMirroringRequired(mParentCamera)));
+        }
+        return outConfigs;
+    }
+
+    /**
+     * Update children {@link SurfaceEdge} calculated by {@link StreamSharing}.
+     */
+    void setChildrenEdges(@NonNull Map<UseCase, SurfaceEdge> childrenEdges) {
+        mChildrenEdges.clear();
+        mChildrenEdges.putAll(childrenEdges);
+        for (Map.Entry<UseCase, SurfaceEdge> entry : mChildrenEdges.entrySet()) {
+            UseCase useCase = entry.getKey();
+            SurfaceEdge surfaceEdge = entry.getValue();
+            useCase.setViewPortCropRect(surfaceEdge.getCropRect());
+            useCase.setSensorToBufferTransformMatrix(surfaceEdge.getSensorToBufferTransform());
+            useCase.updateSuggestedStreamSpec(surfaceEdge.getStreamSpec());
+            useCase.notifyState();
+        }
+    }
+
+    /**
+     * Invokes {@link UseCase.StateChangeCallback#onUseCaseReset} for all children.
+     */
+    void resetChildren() {
+        checkMainThread();
+        for (UseCase useCase : mChildren) {
+            onUseCaseReset(useCase);
+        }
+    }
+
+    /**
+     * Gets the callback for receiving parent camera's metadata.
+     */
+    @NonNull
+    CameraCaptureCallback getParentMetadataCallback() {
+        return mParentMetadataCallback;
+    }
+
+    // --- Handle children state change ---
+    @MainThread
+    @Override
+    public void onUseCaseActive(@NonNull UseCase useCase) {
+        checkMainThread();
+        if (isUseCaseActive(useCase)) {
+            return;
+        }
+        mChildrenActiveState.put(useCase, true);
+        DeferrableSurface childSurface = getChildSurface(useCase);
+        if (childSurface != null) {
+            forceSetProvider(getUseCaseEdge(useCase), childSurface, useCase.getSessionConfig());
+        }
+    }
+
+    @MainThread
+    @Override
+    public void onUseCaseInactive(@NonNull UseCase useCase) {
+        checkMainThread();
+        if (!isUseCaseActive(useCase)) {
+            return;
+        }
+        mChildrenActiveState.put(useCase, false);
+        getUseCaseEdge(useCase).disconnect();
+    }
+
+    @MainThread
+    @Override
+    public void onUseCaseUpdated(@NonNull UseCase useCase) {
+        checkMainThread();
+        if (!isUseCaseActive(useCase)) {
+            // No-op if the child is inactive. It will connect when it becomes active.
+            return;
+        }
+        SurfaceEdge edge = getUseCaseEdge(useCase);
+        DeferrableSurface childSurface = getChildSurface(useCase);
+        if (childSurface != null) {
+            // If the child has a Surface, connect. VideoCapture uses this mechanism to
+            // resume/start recording.
+            forceSetProvider(edge, childSurface, useCase.getSessionConfig());
+        } else {
+            // If the child has no Surface, disconnect. VideoCapture uses this mechanism to
+            // pause/stop recording.
+            edge.disconnect();
+        }
+    }
+
+    @MainThread
+    @Override
+    public void onUseCaseReset(@NonNull UseCase useCase) {
+        checkMainThread();
+        SurfaceEdge edge = getUseCaseEdge(useCase);
+        edge.invalidate();
+        if (!isUseCaseActive(useCase)) {
+            // No-op if the child is inactive. It will connect when it becomes active.
+            return;
+        }
+        DeferrableSurface childSurface = getChildSurface(useCase);
+        if (childSurface != null) {
+            forceSetProvider(edge, childSurface, useCase.getSessionConfig());
+        }
+    }
+
+    // --- private methods ---
+
+    @IntRange(from = 0, to = 359)
+    private int getChildRotationDegrees(@NonNull UseCase child) {
+        int childTargetRotation = ((ImageOutputConfig) child.getCurrentConfig())
+                .getTargetRotation(Surface.ROTATION_0);
+        return mParentCamera.getCameraInfo().getSensorRotationDegrees(
+                childTargetRotation);
+    }
+
+    private static int getChildFormat(@NonNull UseCase useCase) {
+        return useCase instanceof ImageCapture ? ImageFormat.JPEG
+                : INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
+    }
+
+    @CameraEffect.Targets
+    private static int getChildTargetType(@NonNull UseCase useCase) {
+        if (useCase instanceof Preview) {
+            return PREVIEW;
+        } else if (useCase instanceof ImageCapture) {
+            return IMAGE_CAPTURE;
+        } else {
+            return VIDEO_CAPTURE;
+        }
+    }
+
+    private static int getHighestSurfacePriority(Set<UseCaseConfig<?>> childrenConfigs) {
+        int highestPriority = 0;
+        for (UseCaseConfig<?> childConfig : childrenConfigs) {
+            highestPriority = Math.max(highestPriority,
+                    childConfig.getSurfaceOccupancyPriority(0));
+        }
+        return highestPriority;
+    }
+
+    @NonNull
+    private SurfaceEdge getUseCaseEdge(@NonNull UseCase useCase) {
+        return requireNonNull(mChildrenEdges.get(useCase));
+    }
+
+    private boolean isUseCaseActive(@NonNull UseCase useCase) {
+        return requireNonNull(mChildrenActiveState.get(useCase));
+    }
+
+    private static void forceSetProvider(@NonNull SurfaceEdge edge,
+            @NonNull DeferrableSurface childSurface,
+            @NonNull SessionConfig childSessionConfig) {
+        edge.invalidate();
+        try {
+            edge.setProvider(childSurface);
+        } catch (DeferrableSurface.SurfaceClosedException e) {
+            // The Surface is closed by the child. This will happen when e.g. the child is Preview
+            // with SurfaceView implementation.
+            // Invoke the error listener so it will recreate the pipeline.
+            for (SessionConfig.ErrorListener listener : childSessionConfig.getErrorListeners()) {
+                listener.onError(childSessionConfig,
+                        SessionConfig.SessionError.SESSION_ERROR_SURFACE_NEEDS_RESET);
+            }
+        }
+    }
+
+    /**
+     * Gets the {@link DeferrableSurface} associated with the child.
+     */
+    @VisibleForTesting
+    @Nullable
+    static DeferrableSurface getChildSurface(@NonNull UseCase child) {
+        // Get repeating Surface for preview & video, regular Surface for image capture.
+        List<DeferrableSurface> surfaces = child instanceof ImageCapture
+                ? child.getSessionConfig().getSurfaces() :
+                child.getSessionConfig().getRepeatingCaptureConfig().getSurfaces();
+        checkState(surfaces.size() <= 1);
+        if (surfaces.size() == 1) {
+            return surfaces.get(0);
+        }
+        return null;
+    }
+
+    CameraCaptureCallback createCameraCaptureCallback() {
+        return new CameraCaptureCallback() {
+            @Override
+            public void onCaptureCompleted(@NonNull CameraCaptureResult cameraCaptureResult) {
+                super.onCaptureCompleted(cameraCaptureResult);
+                for (UseCase child : mChildren) {
+                    sendCameraCaptureResultToChild(cameraCaptureResult,
+                            child.getSessionConfig());
+                }
+            }
+        };
+    }
+
+    static void sendCameraCaptureResultToChild(
+            @NonNull CameraCaptureResult cameraCaptureResult,
+            @NonNull SessionConfig sessionConfig) {
+        for (CameraCaptureCallback callback :
+                sessionConfig.getRepeatingCameraCaptureCallbacks()) {
+            callback.onCaptureCompleted(new VirtualCameraCaptureResult(
+                    sessionConfig.getRepeatingCaptureConfig().getTagBundle(),
+                    cameraCaptureResult));
+        }
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraInfo.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraInfo.java
index cdd2e3e..635428a 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraInfo.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraInfo.java
@@ -16,12 +16,16 @@
 
 package androidx.camera.core.streamsharing;
 
+import static androidx.camera.core.impl.utils.TransformUtils.within360;
+
 import android.os.Build;
+import android.view.Surface;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.impl.CameraInfoInternal;
 import androidx.camera.core.impl.ForwardingCameraInfo;
+import androidx.camera.core.impl.ImageOutputConfig;
 
 import java.util.UUID;
 
@@ -32,6 +36,7 @@
 public class VirtualCameraInfo extends ForwardingCameraInfo {
 
     private final String mVirtualCameraId;
+    private int mVirtualCameraRotationDegrees;
 
     VirtualCameraInfo(@NonNull CameraInfoInternal cameraInfoInternal) {
         super(cameraInfoInternal);
@@ -48,4 +53,24 @@
     public String getCameraId() {
         return mVirtualCameraId;
     }
+
+    /**
+     * Sets the rotation applied by this virtual camera.
+     */
+    void setVirtualCameraRotationDegrees(int virtualCameraRotationDegrees) {
+        mVirtualCameraRotationDegrees = virtualCameraRotationDegrees;
+    }
+
+    @Override
+    public int getSensorRotationDegrees() {
+        return getSensorRotationDegrees(Surface.ROTATION_0);
+    }
+
+    @Override
+    public int getSensorRotationDegrees(@ImageOutputConfig.RotationValue int relativeRotation) {
+        // The child UseCase calls this method to get the remaining rotation degrees, which is the
+        // original rotation minus the rotation applied by the virtual camera.
+        return within360(
+                super.getSensorRotationDegrees(relativeRotation) - mVirtualCameraRotationDegrees);
+    }
 }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
index 4d2bc37..ab1c29f 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
@@ -505,19 +505,6 @@
     }
 
     @Test
-    fun noCameraTransform_rotationDegreesIsZero() {
-        // Act: create preview with hasCameraTransform == false
-        frontCamera.hasTransform = false
-        val preview = createPreview(
-            effect,
-            frontCamera,
-            targetRotation = ROTATION_90
-        )
-        // Assert: rotationDegrees is 0.
-        assertThat(preview.cameraEdge.rotationDegrees).isEqualTo(0)
-    }
-
-    @Test
     fun setNoCameraTransform_propagatesToCameraEdge() {
         // Act: create preview with hasCameraTransform == false
         frontCamera.hasTransform = false
@@ -787,6 +774,21 @@
         assertThat(preview.isPreviewStabilizationEnabled).isTrue()
     }
 
+    @Test
+    fun canSetDynamicRange() {
+        // Use an unspecified dynamic range that isn't the default, UNSPECIFIED.
+        val preview = Preview.Builder().setDynamicRange(DynamicRange.HDR_UNSPECIFIED_10_BIT).build()
+
+        assertThat(preview.dynamicRange).isEqualTo(DynamicRange.HDR_UNSPECIFIED_10_BIT)
+    }
+
+    @Test
+    fun defaultDynamicRange_isUnspecified() {
+        val preview = Preview.Builder().build()
+
+        assertThat(preview.dynamicRange).isEqualTo(DynamicRange.UNSPECIFIED)
+    }
+
     private fun bindToLifecycleAndGetSurfaceRequest(): SurfaceRequest {
         return bindToLifecycleAndGetResult(null).first
     }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/CaptureNodeTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/CaptureNodeTest.kt
index 6c2969f..c25d59a 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/CaptureNodeTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/CaptureNodeTest.kt
@@ -16,8 +16,8 @@
 
 package androidx.camera.core.imagecapture
 
-import android.graphics.ImageFormat
 import android.graphics.ImageFormat.JPEG
+import android.graphics.ImageFormat.YUV_420_888
 import android.os.Build
 import android.os.Looper.getMainLooper
 import android.util.Size
@@ -55,7 +55,7 @@
 
     @Before
     fun setUp() {
-        captureNodeIn = CaptureNode.In.of(Size(10, 10), JPEG, JPEG, false, null, null)
+        captureNodeIn = CaptureNode.In.of(Size(10, 10), JPEG, JPEG, false, null)
         captureNodeOut = captureNode.transform(captureNodeIn)
         captureNodeOut.imageEdge.setListener {
             imagePropagated.add(it)
@@ -77,7 +77,7 @@
         val imageReaderProvider = ImageReaderProxyProvider { _, _, _, _, _ ->
             imageReader
         }
-        val input = CaptureNode.In.of(Size(10, 10), JPEG, JPEG, false, imageReaderProvider, null)
+        val input = CaptureNode.In.of(Size(10, 10), JPEG, JPEG, false, imageReaderProvider)
         // Act: transform.
         val node = CaptureNode()
         node.transform(input)
@@ -171,12 +171,13 @@
     }
 
     @Test
-    fun transformWithPostviewSize() {
+    fun transformWithPostviewSizeAndYuv() {
         // Arrange: set the postviewSize to the CaptureNode.In
         val postviewSize = Size(640, 480)
 
         val input = CaptureNode.In.of(Size(10, 10), JPEG, JPEG, false, null,
-            postviewSize)
+            postviewSize, YUV_420_888
+        )
 
         // Act: transform.
         val node = CaptureNode()
@@ -185,7 +186,26 @@
         // Assert: postview surface is created
         assertThat(input.postviewSurface).isNotNull()
         assertThat(input.postviewSurface!!.prescribedSize).isEqualTo(postviewSize)
-        assertThat(input.postviewSurface!!.prescribedStreamFormat).isEqualTo(ImageFormat.JPEG)
+        assertThat(input.postviewSurface!!.prescribedStreamFormat).isEqualTo(YUV_420_888)
+        node.release()
+    }
+
+    @Test
+    fun transformWithPostviewSizeAndJpeg() {
+        // Arrange: set the postviewSize to the CaptureNode.In
+        val postviewSize = Size(640, 480)
+
+        val input = CaptureNode.In.of(Size(10, 10), JPEG, JPEG, false, null,
+            postviewSize, JPEG)
+
+        // Act: transform.
+        val node = CaptureNode()
+        node.transform(input)
+
+        // Assert: postview surface is created
+        assertThat(input.postviewSurface).isNotNull()
+        assertThat(input.postviewSurface!!.prescribedSize).isEqualTo(postviewSize)
+        assertThat(input.postviewSurface!!.prescribedStreamFormat).isEqualTo(JPEG)
         node.release()
     }
 }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt
index 018c083..866772e 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/FakeTakePictureCallback.kt
@@ -16,6 +16,7 @@
 
 package androidx.camera.core.imagecapture
 
+import android.graphics.Bitmap
 import androidx.camera.core.ImageCapture.OutputFileResults
 import androidx.camera.core.ImageCaptureException
 import androidx.camera.core.ImageProxy
@@ -32,7 +33,7 @@
     var processFailure: ImageCaptureException? = null
     var onDiskResult: OutputFileResults? = null
     var captureProcessProgress = -1
-    var onPostviewImageAvailable: ImageProxy? = null
+    var onPostviewBitmapAvailable: Bitmap? = null
 
     var aborted = false
 
@@ -68,7 +69,7 @@
         captureProcessProgress = progress
     }
 
-    override fun onPostviewImageAvailable(imageProxy: ImageProxy) {
-        onPostviewImageAvailable = imageProxy
+    override fun onPostviewBitmapAvailable(bitmap: Bitmap) {
+        onPostviewBitmapAvailable = bitmap
     }
 }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ImagePipelineTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ImagePipelineTest.kt
index 0c108e2..47151d6 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ImagePipelineTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ImagePipelineTest.kt
@@ -137,7 +137,7 @@
         imagePipeline.close()
         imagePipeline =
             ImagePipeline(imageCaptureConfig, SIZE,
-                /*cameraEffect=*/null, /*isVirtualCamera=*/true, /*postviewSize*/ null)
+                /*cameraEffect=*/null, /*isVirtualCamera=*/true)
 
         // Act & assert: send and receive ImageProxy.
         sendInMemoryRequest_receivesImageProxy()
@@ -155,8 +155,7 @@
                 imageCaptureConfig,
                 SIZE,
                 GrayscaleImageEffect(),
-                false,
-                /*postviewSize*/ null
+                false
             ).processingNode.mImageProcessor
         ).isNotNull()
     }
@@ -260,10 +259,29 @@
     }
 
     @Test
-    fun createSessionConfigBuilderWithPostviewEnabled() {
+    fun createSessionConfigBuilderWithYuvPostviewEnabled() {
         // Arrange.
         val postviewSize = Size(640, 480)
-        imagePipeline = ImagePipeline(imageCaptureConfig, SIZE, null, false, postviewSize)
+        imagePipeline = ImagePipeline(imageCaptureConfig, SIZE, null, false,
+            postviewSize, ImageFormat.YUV_420_888)
+
+        // Act: create SessionConfig
+        val sessionConfig = imagePipeline.createSessionConfigBuilder(SIZE).build()
+
+        // Assert: SessionConfig contains the postview output config.
+        assertThat(sessionConfig.postviewOutputConfig).isNotNull()
+        assertThat(sessionConfig.postviewOutputConfig!!.surface.prescribedSize)
+            .isEqualTo(postviewSize)
+        assertThat(sessionConfig.postviewOutputConfig!!.surface.prescribedStreamFormat)
+            .isEqualTo(ImageFormat.YUV_420_888)
+    }
+
+    @Test
+    fun createSessionConfigBuilderWithJpegPostviewEnabled() {
+        // Arrange.
+        val postviewSize = Size(640, 480)
+        imagePipeline = ImagePipeline(imageCaptureConfig, SIZE, null, false,
+            postviewSize, ImageFormat.JPEG)
 
         // Act: create SessionConfig
         val sessionConfig = imagePipeline.createSessionConfigBuilder(SIZE).build()
@@ -280,7 +298,8 @@
     fun createCameraRequestWithPostviewEnabled() {
         // Arrange.
         val postviewSize = Size(640, 480)
-        imagePipeline = ImagePipeline(imageCaptureConfig, SIZE, null, false, postviewSize)
+        imagePipeline = ImagePipeline(imageCaptureConfig, SIZE, null, false,
+            postviewSize, ImageFormat.YUV_420_888)
 
         // Act: create requests
         val result =
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ProcessingNodeTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ProcessingNodeTest.kt
index 31ed105..0e0be4b 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ProcessingNodeTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/ProcessingNodeTest.kt
@@ -135,7 +135,7 @@
         shadowOf(getMainLooper()).idle()
 
         // Assert: postview image is received.
-        assertThat(callback.onPostviewImageAvailable).isNotNull()
+        assertThat(callback.onPostviewBitmapAvailable).isNotNull()
     }
 
     @Test
@@ -161,7 +161,7 @@
         shadowOf(getMainLooper()).idle()
 
         // Assert: the postview image is not received.
-        assertThat(callback.onPostviewImageAvailable).isNull()
+        assertThat(callback.onPostviewBitmapAvailable).isNull()
     }
 
     @Test
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
index e36141d..00cadd4 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
@@ -136,10 +136,42 @@
             streamSharing.unbindFromCamera(streamSharing.camera!!)
         }
         effectProcessor.release()
+        sharingProcessor.cleanUp()
+        effectProcessor.cleanUp()
         shadowOf(getMainLooper()).idle()
     }
 
     @Test
+    fun effectHandleRotation_remainingRotationIs0() {
+        // Arrange: create an effect that handles rotation.
+        effect = FakeSurfaceEffect(
+            PREVIEW or VIDEO_CAPTURE,
+            CameraEffect.TRANSFORMATION_CAMERA_AND_SURFACE_ROTATION,
+            effectProcessor
+        )
+        streamSharing = StreamSharing(camera, setOf(child1), useCaseConfigFactory)
+        streamSharing.effect = effect
+        // Act: Bind effect and get sharing input edge.
+        streamSharing.bindToCamera(frontCamera, null, defaultConfig)
+        streamSharing.onSuggestedStreamSpecUpdated(StreamSpec.builder(size).build())
+        // Assert: no remaining rotation because it's handled by the effect.
+        assertThat(streamSharing.sharingInputEdge!!.rotationDegrees).isEqualTo(0)
+    }
+
+    @Test
+    fun effectDoNotHandleRotation_remainingRotationIsNot0() {
+        // Arrange: create an effect that does not handle rotation.
+        streamSharing = StreamSharing(camera, setOf(child1), useCaseConfigFactory)
+        streamSharing.effect = effect
+        // Act: bind effect.
+        streamSharing.bindToCamera(frontCamera, null, defaultConfig)
+        streamSharing.onSuggestedStreamSpecUpdated(StreamSpec.builder(size).build())
+        // Assert: the remaining rotation still exists because the effect doesn't handle it. It will
+        // be handled by downstream pipeline.
+        assertThat(streamSharing.sharingInputEdge!!.rotationDegrees).isEqualTo(SENSOR_ROTATION)
+    }
+
+    @Test
     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     fun invokeParentSessionCaptureCallbacks_receivedByChildren() {
         // Arrange.
@@ -220,12 +252,12 @@
     fun childTakingPicture_getJpegQuality() {
         // Arrange: set up StreamSharing with min latency ImageCapture as child
         val imageCapture = ImageCapture.Builder()
-            .setTargetRotation(Surface.ROTATION_90)
             .setCaptureMode(CAPTURE_MODE_MINIMIZE_LATENCY)
             .build()
         streamSharing = StreamSharing(camera, setOf(child1, imageCapture), useCaseConfigFactory)
         streamSharing.bindToCamera(camera, null, defaultConfig)
         streamSharing.onSuggestedStreamSpecUpdated(StreamSpec.builder(size).build())
+        imageCapture.targetRotation = Surface.ROTATION_90
 
         // Act: the child takes a picture.
         imageCapture.takePicture(directExecutor(), object : ImageCapture.OnImageCapturedCallback() {
@@ -500,12 +532,12 @@
         assertThat(child2.pipelineCreationCount).isEqualTo(2)
         shadowOf(getMainLooper()).idle()
         // Assert: child Surface are propagated to StreamSharing.
-        val child1Surface =
-            streamSharing.virtualCamera.mChildrenEdges[child1]!!.deferrableSurfaceForTesting.surface
+        val child1Surface = streamSharing.virtualCameraAdapter.mChildrenEdges[child1]!!
+            .deferrableSurfaceForTesting.surface
         assertThat(child1Surface.isDone).isTrue()
         assertThat(child1Surface.get()).isEqualTo(surface1)
-        val child2Surface =
-            streamSharing.virtualCamera.mChildrenEdges[child2]!!.deferrableSurfaceForTesting.surface
+        val child2Surface = streamSharing.virtualCameraAdapter.mChildrenEdges[child2]!!
+            .deferrableSurfaceForTesting.surface
         assertThat(child2Surface.isDone).isTrue()
         assertThat(child2Surface.get()).isEqualTo(surface2)
 
@@ -526,6 +558,17 @@
     }
 
     @Test
+    fun bindChildToCamera_virtualCameraHasNoRotationDegrees() {
+        // Act.
+        streamSharing.bindToCamera(frontCamera, null, null)
+        // Assert.
+        assertThat(child1.camera!!.cameraInfoInternal.getSensorRotationDegrees(Surface.ROTATION_0))
+            .isEqualTo(0)
+        assertThat(child2.camera!!.cameraInfoInternal.getSensorRotationDegrees(Surface.ROTATION_0))
+            .isEqualTo(0)
+    }
+
+    @Test
     fun bindAndUnbindParent_propagatesToChildren() {
         // Assert: children not bound to camera by default.
         assertThat(child1.camera).isNull()
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraAdapterTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraAdapterTest.kt
new file mode 100644
index 0000000..9c85fe8
--- /dev/null
+++ b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraAdapterTest.kt
@@ -0,0 +1,334 @@
+/*
+ * 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.camera.core.streamsharing
+
+import android.graphics.ImageFormat
+import android.graphics.Matrix
+import android.graphics.Rect
+import android.graphics.SurfaceTexture
+import android.os.Build
+import android.os.Looper.getMainLooper
+import android.util.Size
+import android.view.Surface
+import androidx.camera.core.CameraEffect.IMAGE_CAPTURE
+import androidx.camera.core.CameraEffect.PREVIEW
+import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
+import androidx.camera.core.ImageCapture
+import androidx.camera.core.ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY
+import androidx.camera.core.ImageCapture.FLASH_MODE_AUTO
+import androidx.camera.core.MirrorMode.MIRROR_MODE_ON
+import androidx.camera.core.Preview
+import androidx.camera.core.UseCase
+import androidx.camera.core.impl.CameraControlInternal
+import androidx.camera.core.impl.CaptureConfig
+import androidx.camera.core.impl.DeferrableSurface
+import androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE
+import androidx.camera.core.impl.ImageOutputConfig.ROTATION_NOT_SPECIFIED
+import androidx.camera.core.impl.SessionConfig
+import androidx.camera.core.impl.SessionConfig.defaultEmptySessionConfig
+import androidx.camera.core.impl.StreamSpec
+import androidx.camera.core.impl.utils.executor.CameraXExecutors.directExecutor
+import androidx.camera.core.impl.utils.futures.Futures
+import androidx.camera.core.processing.SurfaceEdge
+import androidx.camera.testing.fakes.FakeCamera
+import androidx.camera.testing.impl.fakes.FakeDeferrableSurface
+import androidx.camera.testing.impl.fakes.FakeUseCaseConfig
+import androidx.camera.testing.impl.fakes.FakeUseCaseConfigFactory
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.Shadows.shadowOf
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+
+/**
+ * Unit tests for [VirtualCameraAdapter].
+ */
+@RunWith(RobolectricTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+class VirtualCameraAdapterTest {
+
+    companion object {
+        private const val CLOSED = true
+        private const val OPEN = false
+        private const val HAS_PROVIDER = true
+        private const val NO_PROVIDER = false
+        private val INPUT_SIZE = Size(800, 600)
+        private val CROP_RECT = Rect(0, 0, 800, 600)
+
+        // Arbitrary transform to test that the transform is propagated.
+        private val SENSOR_TO_BUFFER = Matrix().apply { setScale(1f, -1f) }
+        private var receivedSessionConfigError: SessionConfig.SessionError? = null
+        private val SESSION_CONFIG_WITH_SURFACE = SessionConfig.Builder()
+            .addSurface(FakeDeferrableSurface(INPUT_SIZE, ImageFormat.PRIVATE))
+            .addErrorListener { _, error ->
+                receivedSessionConfigError = error
+            }.build()
+    }
+
+    private val surfaceEdgesToClose = mutableListOf<SurfaceEdge>()
+    private val parentCamera = FakeCamera()
+    private val child1 = FakeUseCaseConfig.Builder().setTargetRotation(Surface.ROTATION_0).build()
+    private val child2 = FakeUseCaseConfig.Builder()
+        .setMirrorMode(MIRROR_MODE_ON)
+        .build()
+    private val childrenEdges = mapOf(
+        Pair(child1 as UseCase, createSurfaceEdge()),
+        Pair(child2 as UseCase, createSurfaceEdge())
+    )
+    private val useCaseConfigFactory = FakeUseCaseConfigFactory()
+    private lateinit var adapter: VirtualCameraAdapter
+    private var snapshotTriggered = false
+
+    @Before
+    fun setUp() {
+        adapter = VirtualCameraAdapter(
+            parentCamera, setOf(child1, child2), useCaseConfigFactory
+        ) { _, _ ->
+            snapshotTriggered = true
+            Futures.immediateFuture(null)
+        }
+    }
+
+    @After
+    fun tearDown() {
+        for (surfaceEdge in surfaceEdgesToClose) {
+            surfaceEdge.close()
+        }
+    }
+
+    @Test
+    fun submitStillCaptureRequests_triggersSnapshot() {
+        // Arrange.
+        adapter.bindChildren()
+
+        // Act: submit a still capture request from a child.
+        val cameraControl = child1.camera!!.cameraControl as CameraControlInternal
+        cameraControl.submitStillCaptureRequests(
+            listOf(CaptureConfig.Builder().build()),
+            CAPTURE_MODE_MINIMIZE_LATENCY,
+            FLASH_MODE_AUTO
+        )
+        shadowOf(getMainLooper()).idle()
+
+        // The StreamSharing.Control is called to take a snapshot.
+        assertThat(snapshotTriggered).isTrue()
+    }
+
+    @Test
+    fun getImageCaptureSurface_returnsNonRepeatingSurface() {
+        assertThat(getUseCaseSurface(ImageCapture.Builder().build())).isNotNull()
+    }
+
+    @Test
+    fun getChildSurface_returnsRepeatingSurface() {
+        // Arrange.
+        val surfaceTexture = SurfaceTexture(0)
+        val surface = Surface(surfaceTexture)
+        val preview = Preview.Builder().build().apply {
+            this.setSurfaceProvider {
+                it.provideSurface(surface, directExecutor()) {
+                    surfaceTexture.release()
+                    surface.release()
+                }
+            }
+        }
+        // Act & Assert.
+        assertThat(getUseCaseSurface(preview)).isNotNull()
+        // Cleanup.
+        preview.unbindFromCamera(parentCamera)
+        surfaceTexture.release()
+        surface.release()
+    }
+
+    private fun getUseCaseSurface(useCase: UseCase): DeferrableSurface? {
+        useCase.bindToCamera(
+            parentCamera,
+            null,
+            useCase.getDefaultConfig(true, useCaseConfigFactory)
+        )
+        useCase.updateSuggestedStreamSpec(StreamSpec.builder(INPUT_SIZE).build())
+        return VirtualCameraAdapter.getChildSurface(useCase)
+    }
+
+    @Test
+    fun setUseCaseActiveAndInactive_surfaceConnectsAndDisconnects() {
+        // Arrange.
+        adapter.bindChildren()
+        adapter.setChildrenEdges(childrenEdges)
+        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
+        // Assert: edge open by default.
+        verifyEdge(child1, OPEN, NO_PROVIDER)
+        // Set UseCase to active, verify it has provider.
+        child1.notifyActiveForTesting()
+        verifyEdge(child1, OPEN, HAS_PROVIDER)
+        // Set UseCase to inactive, verify it's closed.
+        child1.notifyInactiveForTesting()
+        verifyEdge(child1, CLOSED, HAS_PROVIDER)
+        // Set UseCase to active, verify it becomes open again.
+        child1.notifyActiveForTesting()
+        verifyEdge(child1, OPEN, HAS_PROVIDER)
+    }
+
+    @Test
+    fun resetWithClosedChildSurface_invokesErrorListener() {
+        // Arrange.
+        adapter.bindChildren()
+        adapter.setChildrenEdges(childrenEdges)
+        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
+        child1.notifyActiveForTesting()
+
+        // Act: close the child surface.
+        SESSION_CONFIG_WITH_SURFACE.surfaces[0].close()
+        adapter.onUseCaseReset(child1)
+        shadowOf(getMainLooper()).idle()
+
+        // Assert: error listener is invoked.
+        assertThat(receivedSessionConfigError)
+            .isEqualTo(SessionConfig.SessionError.SESSION_ERROR_SURFACE_NEEDS_RESET)
+    }
+
+    @Test
+    fun resetUseCase_edgeInvalidated() {
+        // Arrange: setup and get the old DeferrableSurface.
+        adapter.bindChildren()
+        adapter.setChildrenEdges(childrenEdges)
+        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
+        child1.notifyActiveForTesting()
+        val oldSurface = childrenEdges[child1]!!.deferrableSurfaceForTesting
+        // Act: notify reset.
+        child1.notifyResetForTesting()
+        // Assert: DeferrableSurface is recreated. The old one is closed.
+        assertThat(oldSurface.isClosed).isTrue()
+        assertThat(childrenEdges[child1]!!.deferrableSurfaceForTesting)
+            .isNotSameInstanceAs(oldSurface)
+        verifyEdge(child1, OPEN, HAS_PROVIDER)
+    }
+
+    @Test
+    fun updateUseCaseWithAndWithoutSurface_surfaceConnectsAndDisconnects() {
+        // Arrange
+        adapter.bindChildren()
+        adapter.setChildrenEdges(childrenEdges)
+        child1.notifyActiveForTesting()
+        verifyEdge(child1, OPEN, NO_PROVIDER)
+
+        // Act: set Surface and update
+        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
+        child1.notifyUpdatedForTesting()
+        // Assert: edge is connected.
+        verifyEdge(child1, OPEN, HAS_PROVIDER)
+        // Act: remove Surface and update.
+        child1.updateSessionConfigForTesting(defaultEmptySessionConfig())
+        child1.notifyUpdatedForTesting()
+        // Assert: edge is disconnected.
+        verifyEdge(child1, CLOSED, HAS_PROVIDER)
+        // Act: set Surface and update.
+        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
+        child1.notifyUpdatedForTesting()
+        // Assert: edge is connected again.
+        verifyEdge(child1, OPEN, HAS_PROVIDER)
+    }
+
+    @Test
+    fun getChildrenOutConfigs() {
+        // Arrange.
+        val cropRect = Rect(10, 10, 410, 310)
+        val preview = Preview.Builder().setTargetRotation(Surface.ROTATION_90).build()
+        val imageCapture = ImageCapture.Builder().setTargetRotation(Surface.ROTATION_0).build()
+        adapter = VirtualCameraAdapter(
+            parentCamera, setOf(preview, child2, imageCapture), useCaseConfigFactory
+        ) { _, _ ->
+            Futures.immediateFuture(null)
+        }
+
+        // Act.
+        val outConfigs = adapter.getChildrenOutConfigs(
+            createSurfaceEdge(cropRect = cropRect, rotationDegrees = 90),
+            Surface.ROTATION_90
+        )
+
+        // Assert: preview config
+        val previewOutConfig = outConfigs[preview]!!
+        assertThat(previewOutConfig.format).isEqualTo(INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE)
+        assertThat(previewOutConfig.targets).isEqualTo(PREVIEW)
+        assertThat(previewOutConfig.cropRect).isEqualTo(cropRect)
+        // Preview's target rotation matches the parent's, so it only applies the 90° rotation.
+        assertThat(previewOutConfig.size).isEqualTo(Size(300, 400))
+        assertThat(previewOutConfig.rotationDegrees).isEqualTo(90)
+        assertThat(previewOutConfig.mirroring).isFalse()
+        // Assert: ImageCapture config
+        val imageOutConfig = outConfigs[imageCapture]!!
+        assertThat(imageOutConfig.format).isEqualTo(ImageFormat.JPEG)
+        assertThat(imageOutConfig.targets).isEqualTo(IMAGE_CAPTURE)
+        // ImageCapture's target rotation does not match the parent's, so it applies the delta on
+        // top of the 90° rotation.
+        assertThat(imageOutConfig.size).isEqualTo(Size(400, 300))
+        assertThat(imageOutConfig.rotationDegrees).isEqualTo(180)
+        // Assert: child2
+        val outConfig2 = outConfigs[child2]!!
+        assertThat(outConfig2.format).isEqualTo(INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE)
+        assertThat(outConfig2.targets).isEqualTo(VIDEO_CAPTURE)
+        assertThat(outConfig2.cropRect).isEqualTo(cropRect)
+        assertThat(outConfig2.mirroring).isTrue()
+    }
+
+    @Test
+    fun updateChildrenSpec_updateAndNotifyChildren() {
+        // Act: update children with the map.
+        adapter.setChildrenEdges(childrenEdges)
+        // Assert: surface size, crop rect and transformation propagated to children
+        assertThat(child1.attachedStreamSpec!!.resolution).isEqualTo(INPUT_SIZE)
+        assertThat(child2.attachedStreamSpec!!.resolution).isEqualTo(INPUT_SIZE)
+        assertThat(child1.viewPortCropRect).isEqualTo(CROP_RECT)
+        assertThat(child2.viewPortCropRect).isEqualTo(CROP_RECT)
+        assertThat(child1.sensorToBufferTransformMatrix).isEqualTo(SENSOR_TO_BUFFER)
+        assertThat(child2.sensorToBufferTransformMatrix).isEqualTo(SENSOR_TO_BUFFER)
+    }
+
+    private fun createSurfaceEdge(
+        target: Int = PREVIEW,
+        format: Int = INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE,
+        streamSpec: StreamSpec = StreamSpec.builder(INPUT_SIZE).build(),
+        matrix: Matrix = SENSOR_TO_BUFFER,
+        hasCameraTransform: Boolean = true,
+        cropRect: Rect = CROP_RECT,
+        rotationDegrees: Int = 0,
+        mirroring: Boolean = false
+    ): SurfaceEdge {
+        return SurfaceEdge(
+            target,
+            format,
+            streamSpec,
+            matrix,
+            hasCameraTransform,
+            cropRect,
+            rotationDegrees,
+            ROTATION_NOT_SPECIFIED,
+            mirroring
+        ).also { surfaceEdgesToClose.add(it) }
+    }
+
+    private fun verifyEdge(child: UseCase, isClosed: Boolean, hasProvider: Boolean) {
+        assertThat(childrenEdges[child]!!.deferrableSurfaceForTesting.isClosed).isEqualTo(isClosed)
+        assertThat(childrenEdges[child]!!.hasProvider()).isEqualTo(hasProvider)
+    }
+}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraTest.kt
index 4681fbb..1b2a88e 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/VirtualCameraTest.kt
@@ -16,45 +16,17 @@
 
 package androidx.camera.core.streamsharing
 
-import android.graphics.ImageFormat
-import android.graphics.Matrix
-import android.graphics.Rect
-import android.graphics.SurfaceTexture
 import android.os.Build
-import android.os.Looper.getMainLooper
-import android.util.Size
 import android.view.Surface
-import androidx.camera.core.CameraEffect.IMAGE_CAPTURE
-import androidx.camera.core.CameraEffect.PREVIEW
-import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
-import androidx.camera.core.ImageCapture
-import androidx.camera.core.ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY
-import androidx.camera.core.ImageCapture.FLASH_MODE_AUTO
-import androidx.camera.core.MirrorMode.MIRROR_MODE_ON
-import androidx.camera.core.Preview
+import androidx.camera.core.CameraSelector
 import androidx.camera.core.UseCase
-import androidx.camera.core.impl.CameraControlInternal
-import androidx.camera.core.impl.CaptureConfig
-import androidx.camera.core.impl.DeferrableSurface
-import androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE
-import androidx.camera.core.impl.ImageOutputConfig.ROTATION_NOT_SPECIFIED
-import androidx.camera.core.impl.SessionConfig
-import androidx.camera.core.impl.SessionConfig.defaultEmptySessionConfig
-import androidx.camera.core.impl.StreamSpec
-import androidx.camera.core.impl.utils.executor.CameraXExecutors.directExecutor
 import androidx.camera.core.impl.utils.futures.Futures
-import androidx.camera.core.processing.SurfaceEdge
 import androidx.camera.testing.fakes.FakeCamera
-import androidx.camera.testing.impl.fakes.FakeDeferrableSurface
-import androidx.camera.testing.impl.fakes.FakeUseCaseConfig
-import androidx.camera.testing.impl.fakes.FakeUseCaseConfigFactory
+import androidx.camera.testing.fakes.FakeCameraInfoInternal
 import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.robolectric.RobolectricTestRunner
-import org.robolectric.Shadows.shadowOf
 import org.robolectric.annotation.Config
 import org.robolectric.annotation.internal.DoNotInstrument
 
@@ -66,55 +38,32 @@
 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
 class VirtualCameraTest {
 
-    companion object {
-        private const val CLOSED = true
-        private const val OPEN = false
-        private const val HAS_PROVIDER = true
-        private const val NO_PROVIDER = false
-        private val INPUT_SIZE = Size(800, 600)
-        private val CROP_RECT = Rect(0, 0, 800, 600)
+    private val cameraInfo = FakeCameraInfoInternal(90, CameraSelector.LENS_FACING_BACK)
 
-        // Arbitrary transform to test that the transform is propagated.
-        private val SENSOR_TO_BUFFER = Matrix().apply { setScale(1f, -1f) }
-        private var receivedSessionConfigError: SessionConfig.SessionError? = null
-        private val SESSION_CONFIG_WITH_SURFACE = SessionConfig.Builder()
-            .addSurface(FakeDeferrableSurface(INPUT_SIZE, ImageFormat.PRIVATE))
-            .addErrorListener { _, error ->
-                receivedSessionConfigError = error
-            }.build()
-    }
+    private val parentCamera = FakeCamera(null, cameraInfo)
 
-    private val surfaceEdgesToClose = mutableListOf<SurfaceEdge>()
-    private val parentCamera = FakeCamera()
-    private val child1 = FakeUseCaseConfig.Builder().setTargetRotation(Surface.ROTATION_0).build()
-    private val child2 = FakeUseCaseConfig.Builder()
-        .setMirrorMode(MIRROR_MODE_ON)
-        .build()
-    private val childrenEdges = mapOf(
-        Pair(child1 as UseCase, createSurfaceEdge()),
-        Pair(child2 as UseCase, createSurfaceEdge())
-    )
-    private val useCaseConfigFactory = FakeUseCaseConfigFactory()
-    private lateinit var virtualCamera: VirtualCamera
-    private var snapshotTriggered = false
+    private val useCaseStateCallback = object : UseCase.StateChangeCallback {
 
-    @Before
-    fun setUp() {
-        virtualCamera = VirtualCamera(
-            parentCamera, setOf(child1, child2), useCaseConfigFactory
-        ) { _, _ ->
-            snapshotTriggered = true
-            Futures.immediateFuture(null)
+        override fun onUseCaseActive(useCase: UseCase) {
+        }
+
+        override fun onUseCaseInactive(useCase: UseCase) {
+        }
+
+        override fun onUseCaseUpdated(useCase: UseCase) {
+        }
+
+        override fun onUseCaseReset(useCase: UseCase) {
         }
     }
 
-    @After
-    fun tearDown() {
-        for (surfaceEdge in surfaceEdgesToClose) {
-            surfaceEdge.close()
-        }
+    private val streamSharingControl = StreamSharing.Control { _, _ ->
+        Futures.immediateFuture(null)
     }
 
+    private val virtualCamera =
+        VirtualCamera(parentCamera, useCaseStateCallback, streamSharingControl)
+
     @Test
     fun getCameraId_returnsVirtualCameraId() {
         assertThat(virtualCamera.cameraInfoInternal.cameraId)
@@ -122,219 +71,18 @@
     }
 
     @Test
-    fun submitStillCaptureRequests_triggersSnapshot() {
-        // Arrange.
-        virtualCamera.bindChildren()
-
-        // Act: submit a still capture request from a child.
-        val cameraControl = child1.camera!!.cameraControl as CameraControlInternal
-        cameraControl.submitStillCaptureRequests(
-            listOf(CaptureConfig.Builder().build()),
-            CAPTURE_MODE_MINIMIZE_LATENCY,
-            FLASH_MODE_AUTO
-        )
-        shadowOf(getMainLooper()).idle()
-
-        // The StreamSharing.Control is called to take a snapshot.
-        assertThat(snapshotTriggered).isTrue()
-    }
-
-    @Test
-    fun getImageCaptureSurface_returnsNonRepeatingSurface() {
-        assertThat(getUseCaseSurface(ImageCapture.Builder().build())).isNotNull()
-    }
-
-    @Test
-    fun getChildSurface_returnsRepeatingSurface() {
-        // Arrange.
-        val surfaceTexture = SurfaceTexture(0)
-        val surface = Surface(surfaceTexture)
-        val preview = Preview.Builder().build().apply {
-            this.setSurfaceProvider {
-                it.provideSurface(surface, directExecutor()) {
-                    surfaceTexture.release()
-                    surface.release()
-                }
-            }
-        }
-        // Act & Assert.
-        assertThat(getUseCaseSurface(preview)).isNotNull()
-        // Cleanup.
-        preview.unbindFromCamera(parentCamera)
-    }
-
-    private fun getUseCaseSurface(useCase: UseCase): DeferrableSurface? {
-        useCase.bindToCamera(
-            parentCamera,
-            null,
-            useCase.getDefaultConfig(true, useCaseConfigFactory)
-        )
-        useCase.updateSuggestedStreamSpec(StreamSpec.builder(INPUT_SIZE).build())
-        return VirtualCamera.getChildSurface(useCase)
-    }
-
-    @Test
-    fun setUseCaseActiveAndInactive_surfaceConnectsAndDisconnects() {
-        // Arrange.
-        virtualCamera.bindChildren()
-        virtualCamera.setChildrenEdges(childrenEdges)
-        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
-        // Assert: edge open by default.
-        verifyEdge(child1, OPEN, NO_PROVIDER)
-        // Set UseCase to active, verify it has provider.
-        child1.notifyActiveForTesting()
-        verifyEdge(child1, OPEN, HAS_PROVIDER)
-        // Set UseCase to inactive, verify it's closed.
-        child1.notifyInactiveForTesting()
-        verifyEdge(child1, CLOSED, HAS_PROVIDER)
-        // Set UseCase to active, verify it becomes open again.
-        child1.notifyActiveForTesting()
-        verifyEdge(child1, OPEN, HAS_PROVIDER)
-    }
-
-    @Test
-    fun resetWithClosedChildSurface_invokesErrorListener() {
-        // Arrange.
-        virtualCamera.bindChildren()
-        virtualCamera.setChildrenEdges(childrenEdges)
-        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
-        child1.notifyActiveForTesting()
-
-        // Act: close the child surface.
-        SESSION_CONFIG_WITH_SURFACE.surfaces[0].close()
-        virtualCamera.onUseCaseReset(child1)
-        shadowOf(getMainLooper()).idle()
-
-        // Assert: error listener is invoked.
-        assertThat(receivedSessionConfigError)
-            .isEqualTo(SessionConfig.SessionError.SESSION_ERROR_SURFACE_NEEDS_RESET)
-    }
-
-    @Test
-    fun resetUseCase_edgeInvalidated() {
-        // Arrange: setup and get the old DeferrableSurface.
-        virtualCamera.bindChildren()
-        virtualCamera.setChildrenEdges(childrenEdges)
-        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
-        child1.notifyActiveForTesting()
-        val oldSurface = childrenEdges[child1]!!.deferrableSurfaceForTesting
-        // Act: notify reset.
-        child1.notifyResetForTesting()
-        // Assert: DeferrableSurface is recreated. The old one is closed.
-        assertThat(oldSurface.isClosed).isTrue()
-        assertThat(childrenEdges[child1]!!.deferrableSurfaceForTesting)
-            .isNotSameInstanceAs(oldSurface)
-        verifyEdge(child1, OPEN, HAS_PROVIDER)
-    }
-
-    @Test
-    fun updateUseCaseWithAndWithoutSurface_surfaceConnectsAndDisconnects() {
-        // Arrange
-        virtualCamera.bindChildren()
-        virtualCamera.setChildrenEdges(childrenEdges)
-        child1.notifyActiveForTesting()
-        verifyEdge(child1, OPEN, NO_PROVIDER)
-
-        // Act: set Surface and update
-        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
-        child1.notifyUpdatedForTesting()
-        // Assert: edge is connected.
-        verifyEdge(child1, OPEN, HAS_PROVIDER)
-        // Act: remove Surface and update.
-        child1.updateSessionConfigForTesting(defaultEmptySessionConfig())
-        child1.notifyUpdatedForTesting()
-        // Assert: edge is disconnected.
-        verifyEdge(child1, CLOSED, HAS_PROVIDER)
-        // Act: set Surface and update.
-        child1.updateSessionConfigForTesting(SESSION_CONFIG_WITH_SURFACE)
-        child1.notifyUpdatedForTesting()
-        // Assert: edge is connected again.
-        verifyEdge(child1, OPEN, HAS_PROVIDER)
-    }
-
-    @Test
-    fun virtualCameraInheritsParentProperties() {
+    fun getCameraState_returnsParentState() {
         assertThat(virtualCamera.cameraState).isEqualTo(parentCamera.cameraState)
-        assertThat(virtualCamera.cameraInfoInternal.implementation)
-            .isEqualTo(virtualCamera.cameraInfoInternal.implementation)
     }
 
     @Test
-    fun getChildrenOutConfigs() {
-        // Arrange.
-        val cropRect = Rect(10, 10, 410, 310)
-        val preview = Preview.Builder().setTargetRotation(Surface.ROTATION_90).build()
-        val imageCapture = ImageCapture.Builder().build()
-        virtualCamera = VirtualCamera(
-            parentCamera, setOf(preview, child2, imageCapture), useCaseConfigFactory
-        ) { _, _ ->
-            Futures.immediateFuture(null)
-        }
-
-        // Act.
-        val outConfigs = virtualCamera.getChildrenOutConfigs(
-            createSurfaceEdge(cropRect = cropRect)
-        )
-
-        // Assert: preview config
-        val previewOutConfig = outConfigs[preview]!!
-        assertThat(previewOutConfig.format).isEqualTo(INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE)
-        assertThat(previewOutConfig.targets).isEqualTo(PREVIEW)
-        assertThat(previewOutConfig.cropRect).isEqualTo(cropRect)
-        assertThat(previewOutConfig.size).isEqualTo(Size(300, 400))
-        assertThat(previewOutConfig.rotationDegrees).isEqualTo(270)
-        assertThat(previewOutConfig.mirroring).isFalse()
-        // Assert: ImageCapture config
-        val imageOutConfig = outConfigs[imageCapture]!!
-        assertThat(imageOutConfig.format).isEqualTo(ImageFormat.JPEG)
-        assertThat(imageOutConfig.targets).isEqualTo(IMAGE_CAPTURE)
-        // Assert: child2
-        val outConfig2 = outConfigs[child2]!!
-        assertThat(outConfig2.format).isEqualTo(INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE)
-        assertThat(outConfig2.targets).isEqualTo(VIDEO_CAPTURE)
-        assertThat(outConfig2.cropRect).isEqualTo(cropRect)
-        assertThat(outConfig2.size).isEqualTo(Size(400, 300))
-        assertThat(outConfig2.mirroring).isTrue()
-    }
-
-    @Test
-    fun updateChildrenSpec_updateAndNotifyChildren() {
-        // Act: update children with the map.
-        virtualCamera.setChildrenEdges(childrenEdges)
-        // Assert: surface size, crop rect and transformation propagated to children
-        assertThat(child1.attachedStreamSpec!!.resolution).isEqualTo(INPUT_SIZE)
-        assertThat(child2.attachedStreamSpec!!.resolution).isEqualTo(INPUT_SIZE)
-        assertThat(child1.viewPortCropRect).isEqualTo(CROP_RECT)
-        assertThat(child2.viewPortCropRect).isEqualTo(CROP_RECT)
-        assertThat(child1.sensorToBufferTransformMatrix).isEqualTo(SENSOR_TO_BUFFER)
-        assertThat(child2.sensorToBufferTransformMatrix).isEqualTo(SENSOR_TO_BUFFER)
-    }
-
-    private fun createSurfaceEdge(
-        target: Int = PREVIEW,
-        format: Int = INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE,
-        streamSpec: StreamSpec = StreamSpec.builder(INPUT_SIZE).build(),
-        matrix: Matrix = SENSOR_TO_BUFFER,
-        hasCameraTransform: Boolean = true,
-        cropRect: Rect = CROP_RECT,
-        rotationDegrees: Int = 0,
-        mirroring: Boolean = false
-    ): SurfaceEdge {
-        return SurfaceEdge(
-            target,
-            format,
-            streamSpec,
-            matrix,
-            hasCameraTransform,
-            cropRect,
-            rotationDegrees,
-            ROTATION_NOT_SPECIFIED,
-            mirroring
-        ).also { surfaceEdgesToClose.add(it) }
-    }
-
-    private fun verifyEdge(child: UseCase, isClosed: Boolean, hasProvider: Boolean) {
-        assertThat(childrenEdges[child]!!.deferrableSurfaceForTesting.isClosed).isEqualTo(isClosed)
-        assertThat(childrenEdges[child]!!.hasProvider()).isEqualTo(hasProvider)
+    fun setRotationDegrees_offsetsParentRotationDegrees() {
+        assertThat(parentCamera.cameraInfoInternal.getSensorRotationDegrees(Surface.ROTATION_0))
+            .isEqualTo(90)
+        virtualCamera.setRotationDegrees(180)
+        assertThat(virtualCamera.cameraInfoInternal.getSensorRotationDegrees())
+            .isEqualTo(270)
+        assertThat(virtualCamera.cameraInfoInternal.getSensorRotationDegrees(Surface.ROTATION_0))
+            .isEqualTo(270)
     }
 }
diff --git a/camera/camera-effects/api/current.txt b/camera/camera-effects/api/current.txt
index e6f50d0..0fa6f1a 100644
--- a/camera/camera-effects/api/current.txt
+++ b/camera/camera-effects/api/current.txt
@@ -1 +1,30 @@
 // Signature format: 4.0
+package androidx.camera.effects {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class Frame {
+    ctor public Frame();
+    method public abstract android.graphics.Rect getCropRect();
+    method public abstract boolean getMirroring();
+    method public android.graphics.Canvas getOverlayCanvas();
+    method public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract android.util.Size getSize();
+    method public abstract long getTimestampNanos();
+  }
+
+  @RequiresApi(21) public class OverlayEffect extends androidx.camera.core.CameraEffect implements java.lang.AutoCloseable {
+    ctor public OverlayEffect(int, int, android.os.Handler, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public void clearOnDrawListener();
+    method public void close();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> drawFrameAsync(long);
+    method public android.os.Handler getHandler();
+    method public int getQueueDepth();
+    method public void setOnDrawListener(androidx.arch.core.util.Function<androidx.camera.effects.Frame!,java.lang.Boolean!>);
+    field public static final int RESULT_CANCELLED_BY_CALLER = 4; // 0x4
+    field public static final int RESULT_FRAME_NOT_FOUND = 2; // 0x2
+    field public static final int RESULT_INVALID_SURFACE = 3; // 0x3
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+}
+
diff --git a/camera/camera-effects/api/restricted_current.txt b/camera/camera-effects/api/restricted_current.txt
index e6f50d0..0fa6f1a 100644
--- a/camera/camera-effects/api/restricted_current.txt
+++ b/camera/camera-effects/api/restricted_current.txt
@@ -1 +1,30 @@
 // Signature format: 4.0
+package androidx.camera.effects {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class Frame {
+    ctor public Frame();
+    method public abstract android.graphics.Rect getCropRect();
+    method public abstract boolean getMirroring();
+    method public android.graphics.Canvas getOverlayCanvas();
+    method public abstract int getRotationDegrees();
+    method public abstract android.graphics.Matrix getSensorToBufferTransform();
+    method public abstract android.util.Size getSize();
+    method public abstract long getTimestampNanos();
+  }
+
+  @RequiresApi(21) public class OverlayEffect extends androidx.camera.core.CameraEffect implements java.lang.AutoCloseable {
+    ctor public OverlayEffect(int, int, android.os.Handler, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public void clearOnDrawListener();
+    method public void close();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> drawFrameAsync(long);
+    method public android.os.Handler getHandler();
+    method public int getQueueDepth();
+    method public void setOnDrawListener(androidx.arch.core.util.Function<androidx.camera.effects.Frame!,java.lang.Boolean!>);
+    field public static final int RESULT_CANCELLED_BY_CALLER = 4; // 0x4
+    field public static final int RESULT_FRAME_NOT_FOUND = 2; // 0x2
+    field public static final int RESULT_INVALID_SURFACE = 3; // 0x3
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+}
+
diff --git a/camera/camera-effects/build.gradle b/camera/camera-effects/build.gradle
index cedb467..a806e1a 100644
--- a/camera/camera-effects/build.gradle
+++ b/camera/camera-effects/build.gradle
@@ -58,11 +58,10 @@
 }
 androidx {
     name = "Camera Effects"
-    publish = Publish.NONE
-    inceptionYear = "2022"
+    publish = Publish.SNAPSHOT_AND_RELEASE
+    inceptionYear = "2023"
     runApiTasks = new RunApiTasks.Yes()
     description = "Camera effects components for the Jetpack Camera Library, a library providing " +
-            "camera post-processing features such as portrait mode that can be used with the " +
-            "CameraX library."
+            "camera post-processing features such as drawing overlay with the CameraX library."
     metalavaK2UastEnabled = true
 }
diff --git a/camera/camera-effects/src/androidTest/java/androidx/camera/effects/internal/SurfaceProcessorImplDeviceTest.kt b/camera/camera-effects/src/androidTest/java/androidx/camera/effects/internal/SurfaceProcessorImplDeviceTest.kt
index 8378175..2eca7e1 100644
--- a/camera/camera-effects/src/androidTest/java/androidx/camera/effects/internal/SurfaceProcessorImplDeviceTest.kt
+++ b/camera/camera-effects/src/androidTest/java/androidx/camera/effects/internal/SurfaceProcessorImplDeviceTest.kt
@@ -242,7 +242,7 @@
         val cachedFrame = processor.buffer.frames.single()
 
         // Act: draw the cached frame.
-        val drawFuture = processor.drawFrame(cachedFrame.timestampNs)
+        val drawFuture = processor.drawFrameAsync(cachedFrame.timestampNanos)
 
         // Assert: the future completes with RESULT_SUCCESS and the output receives the frame.
         assertThat(drawFuture.get()).isEqualTo(OverlayEffect.RESULT_SUCCESS)
@@ -256,7 +256,7 @@
         val frame = processor.buffer.frames.single()
 
         // Act: draw the frame with a wrong timestamp.
-        val drawFuture = processor.drawFrame(frame.timestampNs - 1)
+        val drawFuture = processor.drawFrameAsync(frame.timestampNanos - 1)
 
         // Assert: the future completes with RESULT_FRAME_NOT_FOUND and the output does not receive
         // the frame.
@@ -275,7 +275,7 @@
         val frame = processor.buffer.frames.single()
 
         // Act: draw the frame.
-        val drawFuture = processor.drawFrame(frame.timestampNs)
+        val drawFuture = processor.drawFrameAsync(frame.timestampNanos)
 
         // Assert: the future completes with RESULT_CANCELLED_BY_CALLER and the output does not
         // receive the frame.
@@ -303,7 +303,7 @@
         }
 
         // Act: draw the buffered frame.
-        val drawFuture = processor.drawFrame(frame.timestampNs)
+        val drawFuture = processor.drawFrameAsync(frame.timestampNanos)
 
         // Assert: the future completes with RESULT_INVALID_SURFACE and the output does not
         // receive the frame.
@@ -318,7 +318,7 @@
         processor.release()
 
         // Act: release the processor and draw a frame.
-        val drawFuture = processor.drawFrame(0)
+        val drawFuture = processor.drawFrameAsync(0)
 
         // Assert: the future completes with an exception.
         try {
diff --git a/camera/camera-effects/src/main/java/androidx/camera/effects/Frame.java b/camera/camera-effects/src/main/java/androidx/camera/effects/Frame.java
index 47c353b..102a961 100644
--- a/camera/camera-effects/src/main/java/androidx/camera/effects/Frame.java
+++ b/camera/camera-effects/src/main/java/androidx/camera/effects/Frame.java
@@ -22,7 +22,6 @@
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraCharacteristics;
 import android.util.Size;
 import android.view.Surface;
 
@@ -30,21 +29,20 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.camera.core.ImageAnalysis;
 import androidx.camera.core.ImageInfo;
+import androidx.camera.core.Preview;
 import androidx.camera.core.SurfaceRequest;
 
 import com.google.auto.value.AutoValue;
 
 /**
- * Represents a frame that will be rendered next.
+ * Represents a frame that is about to be rendered.
  *
- * <p>This class can be used to overlay graphics or data on camera output. It contains
- * information for drawing an overlay, including sensor-to-buffer transform, size, crop rect,
- * rotation, mirroring, and timestamp. It also provides a {@link Canvas} for the drawing.
- *
- * TODO(b/297509601): Make it public API in 1.4.
+ * <p>Use this class to draw overlay on camera output. It contains a {@link Canvas} for the
+ * drawing. It also provides metadata for positioning the overlay correctly, including
+ * sensor-to-buffer transform, size, crop rect, rotation, mirroring, and timestamp.
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(21)
 @AutoValue
 public abstract class Frame {
@@ -61,12 +59,12 @@
     @NonNull
     public static Frame of(
             @NonNull Surface overlaySurface,
-            long timestampNs,
+            long timestampNanos,
             @NonNull Size size,
             @NonNull SurfaceRequest.TransformationInfo transformationInfo) {
         Frame frame = new AutoValue_Frame(transformationInfo.getSensorToBufferTransform(), size,
                 transformationInfo.getCropRect(), transformationInfo.getRotationDegrees(),
-                transformationInfo.getMirroring(), timestampNs);
+                transformationInfo.getMirroring(), timestampNanos);
         frame.mOverlaySurface = overlaySurface;
         return frame;
     }
@@ -75,8 +73,8 @@
      * Returns the sensor to image buffer transform matrix.
      *
      * <p>The value is a mapping from sensor coordinates to buffer coordinates, which is,
-     * from the rect of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE} to the
-     * rect defined by {@code (0, 0, #getSize()#getWidth(), #getSize()#getHeight())}.
+     * from the rect of the camera sensor to the rect defined by {@code (0, 0, #getSize()
+     * #getWidth(), #getSize()#getHeight())}.
      *
      * <p>The value can be set on the {@link Canvas} using {@link Canvas#setMatrix} API. This
      * transforms the {@link Canvas} to the sensor coordinate system.
@@ -89,18 +87,20 @@
     /**
      * Returns the resolution of the frame.
      *
+     * <p>This is the size of the input {@link SurfaceTexture} created by the effect.
+     *
      * @see SurfaceRequest#getResolution()
      */
     @NonNull
     public abstract Size getSize();
 
     /**
-     * Returns the crop rect rectangle.
+     * Returns the crop rect.
      *
-     * <p>The value represents how the frame will be cropped by the CameraX pipeline. The crop
-     * rectangle specifies the region of valid pixels in the frame, using coordinates from (0, 0)
-     * to the (width, height) of {@link #getSize()}. Only the overlay drawn within the bound of
-     * the crop rect will be visible to the end users.
+     * <p>The value represents how CameraX intends to crop the input frame. The crop rect specifies
+     * the region of valid pixels in the frame, using coordinates from (0, 0) to the (width,
+     * height) of {@link #getSize()}. Only the overlay drawn within the bound of the crop rect
+     * will be visible to the end users.
      *
      * <p>The crop rect is applied before the rotating and mirroring. The order of the operations
      * is as follows: 1) cropping, 2) rotating and 3) mirroring.
@@ -114,9 +114,10 @@
      * Returns the rotation degrees of the frame.
      *
      * <p>This is a clockwise rotation in degrees that needs to be applied to the frame. The
-     * rotation will be determined by {@link CameraCharacteristics} and UseCase configuration.
-     * The app must draw the overlay according to the rotation degrees to ensure it is
-     * displayed correctly to the end users.
+     * rotation will be determined by camera sensor orientation and UseCase configuration
+     * such as {@link Preview#setTargetRotation}. The app must draw the overlay according to the
+     * rotation degrees to ensure it is displayed correctly to the end users. For example, to
+     * overlay a text, make sure the text's orientation is aligned with the rotation degrees.
      *
      * <p>The rotation is applied after the cropping but before the mirroring. The order of the
      * operations is as follows: 1) cropping, 2) rotating and 3) mirroring.
@@ -128,7 +129,7 @@
     /**
      * Returns whether the buffer will be mirrored.
      *
-     * <p>This flag indicates whether the buffer will be mirrored by the pipeline vertically. For
+     * <p>This flag indicates whether the buffer will be mirrored vertically by the pipeline. For
      * example, for front camera preview, the buffer is usually mirrored before displayed to end
      * users.
      *
@@ -142,21 +143,26 @@
     /**
      * Returns the timestamp of the frame in nanoseconds.
      *
+     * <p>This value will match the frames from other streams. For example, for a
+     * {@link ImageAnalysis} output that is originated from the same frame, this value will match
+     * the value of {@link ImageInfo#getTimestamp()}.
+     *
      * @see SurfaceTexture#getTimestamp()
      * @see ImageInfo#getTimestamp()
      */
-    public abstract long getTimestampNs();
+    public abstract long getTimestampNanos();
 
     /**
      * Get the canvas for drawing the overlay.
      *
      * <p>Call this method to get the {@link Canvas} for drawing an overlay on top of the frame.
-     * The {@link Canvas} is backed by a {@link SurfaceTexture} with the sizes equals
+     * The {@link Canvas} is backed by a {@link SurfaceTexture} with a size equal to
      * {@link #getSize()}. To draw object in camera sensor coordinates, apply
      * {@link #getSensorToBufferTransform()} via {@link Canvas#setMatrix(Matrix)} before drawing.
      *
-     * <p>The caller should only invoke this method when there's a requirement to overlay on the
-     * frame. Using this method introduce wait times to synchronize frame updates.
+     * <p>Using this method introduces wait times to synchronize frame updates. The caller should
+     * only invoke this method when it needs to draw overlay. For example, when an object is
+     * detected in the frame.
      */
     @NonNull
     public Canvas getOverlayCanvas() {
@@ -166,7 +172,6 @@
         return mOverlayCanvas;
     }
 
-
     /**
      * Internal API to check whether the overlay canvas has been drawn into.
      */
diff --git a/camera/camera-effects/src/main/java/androidx/camera/effects/OverlayEffect.java b/camera/camera-effects/src/main/java/androidx/camera/effects/OverlayEffect.java
index 642f8e6..f274630 100644
--- a/camera/camera-effects/src/main/java/androidx/camera/effects/OverlayEffect.java
+++ b/camera/camera-effects/src/main/java/androidx/camera/effects/OverlayEffect.java
@@ -16,29 +16,65 @@
 
 package androidx.camera.effects;
 
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.SurfaceTexture;
+import android.os.Handler;
+
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.arch.core.util.Function;
 import androidx.camera.core.CameraEffect;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.ImageInfo;
+import androidx.camera.core.ProcessingException;
+import androidx.camera.core.SurfaceProcessor;
 import androidx.camera.core.UseCase;
+import androidx.camera.effects.internal.SurfaceProcessorImpl;
+import androidx.core.util.Consumer;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /**
  * A {@link CameraEffect} for drawing overlay on top of the camera frames.
- * TODO(b/297509601): Make it public API in 1.4.
+ *
+ * <p>This class manages and processes camera frames with OpenGL. Upon arrival, frames are
+ * enqueued into an array of GL textures for deferred rendering. Calling
+ * {@link #drawFrameAsync(long)} dequeues frames and renders them to the output. Additionally, when
+ * the texture queue reaches its capacity, the oldest frame is automatically dequeued and
+ * rendered. The size of the texture queue can be defined in the constructor.
+ *
+ * <p>The queuing mechanism provides the flexibility to postpone frame rendering until analysis
+ * results are available. For instance, to highlight on a QR code in a preview, one can apply a
+ * QR code detection algorithm using {@link ImageAnalysis}. Once the frame's analysis result
+ * is ready, invoke {@link #drawFrameAsync(long)} and pass in the
+ * {@link ImageInfo#getTimestamp()} to release the frame and draw overlay. If the app
+ * doesn't render real-time analysis results, set the queue depth to 0 to avoid unnecessary
+ * buffer copies. For example, when laying over a static watermark.
+ *
+ * <p>Prior to rendering a frame, the {@link OverlayEffect} invokes the listener set in
+ * {@link #setOnDrawListener(Function)}. This listener provides a {@link Frame} object, which
+ * contains both a {@link Canvas} object for drawing the overlay and the metadata like crop rect,
+ * rotation degrees, etc to calculate how the overlay should be positioned. Once the listener
+ * returns, {@link OverlayEffect} updates the {@link SurfaceTexture} behind the {@link Canvas}
+ * and blends it with the camera frame before rendering to the output.
+ *
+ * <p>This class is thread-safe. The methods can be invoked on any thread. The app provides a
+ * {@link Handler} object in the constructor which is used for listening for Surface updates,
+ * performing OpenGL operations and invoking app provided listeners.
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(21)
-public class OverlayEffect {
+public class OverlayEffect extends CameraEffect implements AutoCloseable {
 
     /**
-     * {@link #drawFrame(long)} result code
+     * {@link #drawFrameAsync(long)} result code.
      */
     @Retention(RetentionPolicy.SOURCE)
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -51,21 +87,20 @@
     }
 
     /**
-     * The {@link #drawFrame(long)} call was successful. The frame with the exact timestamp was
+     * The {@link #drawFrameAsync(long)} call was successful. The frame with the exact timestamp was
      * drawn to the output surface.
      */
     public static final int RESULT_SUCCESS = 1;
 
     /**
-     * The {@link #drawFrame(long)} call failed because the frame with the exact timestamp was
+     * The {@link #drawFrameAsync(long)} call failed because the frame with the exact timestamp was
      * not found in the queue. It could be one of the following reasons:
      *
      * <ul>
-     * <li>the timestamp was incorrect, or
-     * <li>the frame was not yet available, or
-     * <li>the frame was removed because {@link #drawFrame} had been called with a newer
+     * <li>the timestamp provided was incorrect, or
+     * <li>the frame was removed because {@link #drawFrameAsync} had been called with a newer
      * timestamp, or
-     * <li>the frame was removed due to the queue is full.
+     * <li>the frame was removed due to the queue being full.
      * </ul>
      *
      * If it's the last case, the caller may avoid this issue by increasing the queue depth.
@@ -73,30 +108,137 @@
     public static final int RESULT_FRAME_NOT_FOUND = 2;
 
     /**
-     * The {@link #drawFrame(long)} call failed because the output surface is missing, or the
-     * output surface no longer matches the frame. It could be because the {@link UseCase}
-     * was unbound, causing the original surface to be replaced or disabled.
+     * The {@link #drawFrameAsync(long)} call failed because the output surface is missing, or the
+     * output surface no longer matches the frame. It can happen when the output Surface is
+     * replaced or disabled. For example, when the {@link UseCase} was unbound.
      */
     public static final int RESULT_INVALID_SURFACE = 3;
 
     /**
-     * The {@link #drawFrame(long)} call failed because the caller cancelled the drawing. This
-     * happens when the listener provided via {@link #setOnDrawListener(Function)} returned false.
+     * The {@link #drawFrameAsync(long)} call failed because the caller cancelled the drawing. This
+     * happens when the listener in {@link #setOnDrawListener(Function)} returned false.
      */
     public static final int RESULT_CANCELLED_BY_CALLER = 4;
 
     /**
-     * TODO(b/297509601): add JavaDoc
+     * Creates an {@link OverlayEffect}.
+     *
+     * @param targets       The targets the effect applies to. For example,
+     *                      {@link CameraEffect#PREVIEW} | {@link CameraEffect#VIDEO_CAPTURE}. See
+     *                      {@link UseCaseGroup.Builder#addEffect} for supported targets
+     *                      combinations.
+     * @param queueDepth    The depth of the queue. This value indicates how many frames can be
+     *                      queued before the oldest frame being automatically released.
+     *                      {@link OverlayEffect} allocates an array of OpenGL 2D textures that
+     *                      matches this size. The maximum value of the queueDepth depends on the
+     *                      size of the image and the device capabilities. Set a larger value if
+     *                      an ImageAnalysis processing takes a long time to produce a result to
+     *                      be used for overlay, so the frame is not auto-released before the
+     *                      result is ready. If the queue depth is 0, the input frames are
+     *                      rendered immediately without queuing.
+     * @param handler       The Handler for listening for the input Surface updates and for
+     *                      performing OpenGL operations.
+     * @param errorListener invoked if the effect runs into unrecoverable errors. The
+     *                      {@link Throwable} will be the error thrown by this
+     *                      {@link CameraEffect}. For example, {@link ProcessingException}.
+     *                      This is invoked on the provided {@param Handler}.
      */
-    @NonNull
-    public ListenableFuture<Integer> drawFrame(long timestampNs) {
-        throw new UnsupportedOperationException("Not implemented yet");
+    public OverlayEffect(int targets, int queueDepth, @NonNull Handler handler,
+            @NonNull Consumer<Throwable> errorListener) {
+        this(targets, new SurfaceProcessorImpl(queueDepth, handler), errorListener);
+    }
+
+    private OverlayEffect(int targets, @NonNull SurfaceProcessorImpl surfaceProcessor,
+            @NonNull Consumer<Throwable> errorListener) {
+        this(targets, surfaceProcessor.getGlExecutor(), surfaceProcessor,
+                errorListener);
+    }
+
+    private OverlayEffect(int targets, @NonNull Executor executor,
+            @NonNull SurfaceProcessor surfaceProcessor,
+            @NonNull Consumer<Throwable> errorListener) {
+        super(targets, executor, surfaceProcessor, errorListener);
     }
 
     /**
-     * TODO(b/297509601): add JavaDoc
+     * Draws the queued frame with the given timestamp.
+     *
+     * <p>Once invoked, {@link OverlayEffect} retrieves the queued frame with the given timestamp
+     * and draws it to the output Surface. If the frame is successfully drawn,
+     * {@link ListenableFuture} completes with {@link #RESULT_SUCCESS}. Otherwise, it completes
+     * with one of the following results: {@link #RESULT_FRAME_NOT_FOUND},
+     * {@link #RESULT_INVALID_SURFACE} or {@link #RESULT_CANCELLED_BY_CALLER}. If this method is
+     * called after the {@link OverlayEffect} is released, the {@link ListenableFuture} completes
+     * with an {@link IllegalStateException}.
+     *
+     * <p>This method is thread safe. When calling from the {@link #getHandler()} thread, it's
+     * executed right away; otherwise, it posts the execution on the {@link #getHandler()}. It's
+     * recommended to call this method from the {@link #getHandler()} thread to avoid thread
+     * hopping.
+     */
+    @NonNull
+    public ListenableFuture<Integer> drawFrameAsync(long timestampNs) {
+        return getSurfaceProcessorImpl().drawFrameAsync(timestampNs);
+    }
+
+    /**
+     * Sets the listener for drawing overlay.
+     *
+     * <p>Each time before {@link OverlayEffect} draws a frame to the output, the listener
+     * receives a {@link Frame} object, which contains the necessary APIs for drawing overlay.
+     *
+     * <p>To draw an overlay, first call {@link Frame#getOverlayCanvas()} ()} to get a
+     * {@link Canvas} object. The {@link Canvas} object is backed by a {@link SurfaceTexture}
+     * with the size of {@link Frame#getSize()}. {@link Frame#getSensorToBufferTransform()}
+     * represents the mapping from camera sensor coordinates to the frame's coordinates. To draw
+     * objects in the sensor coordinates, call {@link Canvas#setMatrix(Matrix)} with the value of
+     * {@link Frame#getSensorToBufferTransform()}.
+     *
+     * <p>Once the drawing is done, the listener should return true for the {@link OverlayEffect}
+     * to draw it to the output Surface. If it returns false, the frame will be dropped.
+     *
+     * <p>{@link OverlayEffect} invokes the listener on the {@link #getHandler()} thread.
+     *
+     * @see Frame
      */
     public void setOnDrawListener(@NonNull Function<Frame, Boolean> onDrawListener) {
-        throw new UnsupportedOperationException("Not implemented yet");
+        getSurfaceProcessorImpl().setOnDrawListener(onDrawListener);
+    }
+
+    /**
+     * Clears the listener set in {@link #setOnDrawListener(Function)}.
+     */
+    public void clearOnDrawListener() {
+        getSurfaceProcessorImpl().setOnDrawListener(null);
+    }
+
+    /**
+     * Closes the {@link OverlayEffect}.
+     *
+     * <p>Once closed, the {@link OverlayEffect} can no longer be used.
+     */
+    @Override
+    public void close() {
+        getSurfaceProcessorImpl().release();
+    }
+
+    /**
+     * Gets the depth of the queue set in the constructor.
+     */
+    public int getQueueDepth() {
+        return getSurfaceProcessorImpl().getQueueDepth();
+    }
+
+    /**
+     * Gets the {@link Handler} set in the constructor.
+     */
+    @NonNull
+    public Handler getHandler() {
+        return getSurfaceProcessorImpl().getGlHandler();
+    }
+
+    @NonNull
+    private SurfaceProcessorImpl getSurfaceProcessorImpl() {
+        return (SurfaceProcessorImpl) Objects.requireNonNull(getSurfaceProcessor());
     }
 }
diff --git a/camera/camera-effects/src/main/java/androidx/camera/effects/internal/SurfaceProcessorImpl.java b/camera/camera-effects/src/main/java/androidx/camera/effects/internal/SurfaceProcessorImpl.java
index b85c79f..6422c8f 100644
--- a/camera/camera-effects/src/main/java/androidx/camera/effects/internal/SurfaceProcessorImpl.java
+++ b/camera/camera-effects/src/main/java/androidx/camera/effects/internal/SurfaceProcessorImpl.java
@@ -96,11 +96,14 @@
 
     private boolean mIsReleased = false;
 
+    private final int mQueueDepth;
+
     // Thread and handler for receiving overlay texture updates.
     private final HandlerThread mOverlayHandlerThread;
     private final Handler mOverlayHandler;
 
     public SurfaceProcessorImpl(int queueDepth, @NonNull Handler glHandler) {
+        mQueueDepth = queueDepth;
         mGlHandler = glHandler;
         mGlExecutor = CameraXExecutors.newHandlerExecutor(mGlHandler);
         mGlRenderer = new GlRenderer(queueDepth);
@@ -267,7 +270,7 @@
      * exception.
      */
     @NonNull
-    public ListenableFuture<Integer> drawFrame(long timestampNs) {
+    public ListenableFuture<Integer> drawFrameAsync(long timestampNs) {
         return CallbackToFutureAdapter.getFuture(completer -> {
             runOnGlThread(() -> {
                 if (mIsReleased) {
@@ -286,6 +289,21 @@
         });
     }
 
+    /**
+     * Gets the depth of the buffer.
+     */
+    public int getQueueDepth() {
+        return mQueueDepth;
+    }
+
+    /**
+     * Gets the GL handler.
+     */
+    @NonNull
+    public Handler getGlHandler() {
+        return mGlHandler;
+    }
+
     // *** Private methods ***
 
     private void runOnGlThread(@NonNull Runnable runnable) {
@@ -331,10 +349,10 @@
                 return OverlayEffect.RESULT_INVALID_SURFACE;
             }
             // Only draw if frame is associated with the current output surface.
-            if (drawOverlay(frame.getTimestampNs())) {
+            if (drawOverlay(frame.getTimestampNanos())) {
                 mGlRenderer.renderQueueTextureToSurface(
                         frame.getTextureId(),
-                        frame.getTimestampNs(),
+                        frame.getTimestampNanos(),
                         frame.getTransform(),
                         frame.getSurface());
                 return OverlayEffect.RESULT_SUCCESS;
diff --git a/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrame.java b/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrame.java
index d284439..6a1a542 100644
--- a/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrame.java
+++ b/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrame.java
@@ -40,7 +40,7 @@
 
     private final int mTextureId;
 
-    private long mTimestampNs = NO_VALUE;
+    private long mTimestampNanos = NO_VALUE;
     @Nullable
     private Surface mSurface;
 
@@ -61,7 +61,7 @@
      * with new content.
      */
     boolean isEmpty() {
-        return mTimestampNs == NO_VALUE;
+        return mTimestampNanos == NO_VALUE;
     }
 
     /**
@@ -71,7 +71,7 @@
      */
     void markEmpty() {
         checkState(!isEmpty(), "Frame is already empty");
-        mTimestampNs = NO_VALUE;
+        mTimestampNanos = NO_VALUE;
         mSurface = null;
     }
 
@@ -88,7 +88,7 @@
      */
     void markFilled(long timestampNs, @NonNull float[] transform, @NonNull Surface surface) {
         checkState(isEmpty(), "Frame is already filled");
-        mTimestampNs = timestampNs;
+        mTimestampNanos = timestampNs;
         System.arraycopy(transform, 0, mTransform, 0, transform.length);
         mSurface = surface;
     }
@@ -98,8 +98,8 @@
      *
      * <p>This value is used in {@link GlRenderer#renderQueueTextureToSurface}.
      */
-    long getTimestampNs() {
-        return mTimestampNs;
+    long getTimestampNanos() {
+        return mTimestampNanos;
     }
 
     /**
diff --git a/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrameBuffer.java b/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrameBuffer.java
index e75b292..8c5b854 100644
--- a/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrameBuffer.java
+++ b/camera/camera-effects/src/main/java/androidx/camera/effects/internal/TextureFrameBuffer.java
@@ -73,9 +73,9 @@
             if (frame.isEmpty()) {
                 continue;
             }
-            if (frame.getTimestampNs() == timestampNs) {
+            if (frame.getTimestampNanos() == timestampNs) {
                 frameToReturn = frame;
-            } else if (frame.getTimestampNs() < timestampNs) {
+            } else if (frame.getTimestampNanos() < timestampNs) {
                 frame.markEmpty();
             }
         }
@@ -95,8 +95,8 @@
         for (TextureFrame frame : mFrames) {
             if (frame.isEmpty()) {
                 return frame;
-            } else if (frame.getTimestampNs() < minTimestampNs) {
-                minTimestampNs = frame.getTimestampNs();
+            } else if (frame.getTimestampNanos() < minTimestampNs) {
+                minTimestampNs = frame.getTimestampNanos();
                 oldestFrame = frame;
             }
         }
diff --git a/camera/camera-effects/src/main/java/androidx/camera/effects/opengl/GlRenderer.java b/camera/camera-effects/src/main/java/androidx/camera/effects/opengl/GlRenderer.java
index 9158e9a..c2aeac5 100644
--- a/camera/camera-effects/src/main/java/androidx/camera/effects/opengl/GlRenderer.java
+++ b/camera/camera-effects/src/main/java/androidx/camera/effects/opengl/GlRenderer.java
@@ -43,7 +43,7 @@
  * <li>Rendering a texture in the queue to the output Surface.
  * </ul>
  *
- * <p>It also allows the caller to upload a bitmap and overlay it when rendering to Surface.
+ * <p>It also allows the caller to overlay a texture when rendering to Surface.
  */
 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 @RestrictTo(RestrictTo.Scope.LIBRARY)
diff --git a/camera/camera-effects/src/test/java/androidx/camera/effects/internal/TextureFrameBufferTest.kt b/camera/camera-effects/src/test/java/androidx/camera/effects/internal/TextureFrameBufferTest.kt
index 757373c..5f7edda 100644
--- a/camera/camera-effects/src/test/java/androidx/camera/effects/internal/TextureFrameBufferTest.kt
+++ b/camera/camera-effects/src/test/java/androidx/camera/effects/internal/TextureFrameBufferTest.kt
@@ -92,7 +92,7 @@
 
         // Assert: the frame has the correct values.
         assertThat(frame.textureId).isEqualTo(1)
-        assertThat(frame.timestampNs).isEqualTo(TIMESTAMP_1)
+        assertThat(frame.timestampNanos).isEqualTo(TIMESTAMP_1)
         assertThat(frame.transform.contentEquals(transform1)).isTrue()
         assertThat(frame.transform).isNotSameInstanceAs(transform1)
         assertThat(frame.surface).isSameInstanceAs(surface1)
diff --git a/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java b/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
index dbcd1ef..98cf915 100644
--- a/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
+++ b/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
@@ -91,7 +91,7 @@
 
     /**
      * Returns supported output format/size map for postview image. OEM is required to support
-     * both JPEG and YUV_420_888 format output.
+     * YUV_420_888 format output.
      *
      * <p>Pair list composed with {@link ImageFormat} and {@link Size} array will be returned.
      * The sizes must be smaller than or equal to the provided capture size and have the same
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
index 926cad2..5dc613d 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
@@ -27,6 +27,7 @@
 import androidx.camera.core.SurfaceRequest
 import androidx.camera.core.impl.CameraInfoInternal
 import androidx.camera.core.impl.MutableStateObservable
+import androidx.camera.extensions.impl.ExtensionsTestlibControl
 import androidx.camera.extensions.internal.ClientVersion
 import androidx.camera.extensions.internal.ExtensionVersion
 import androidx.camera.extensions.internal.VendorExtender
@@ -60,6 +61,7 @@
 @RunWith(Parameterized::class)
 @SdkSuppress(minSdkVersion = 21)
 class ExtensionsManagerTest(
+    private val implType: ExtensionsTestlibControl.ImplementationType,
     @field:ExtensionMode.Mode @param:ExtensionMode.Mode private val extensionMode: Int,
     @field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
 ) {
@@ -92,6 +94,7 @@
         )
 
         baseCameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
+        ExtensionsTestlibControl.getInstance().setImplementationType(implType)
     }
 
     @After
@@ -107,9 +110,9 @@
 
     companion object {
         @JvmStatic
-        @get:Parameterized.Parameters(name = "extension = {0}, facing = {1}")
+        @get:Parameterized.Parameters(name = "implType = {0}, mode = {1}, facing = {2}")
         val parameters: Collection<Array<Any>>
-            get() = ExtensionsTestUtil.getAllExtensionsLensFacingCombinations()
+            get() = ExtensionsTestUtil.getAllImplExtensionsLensFacingCombinations()
     }
 
     @Test
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageAnalysisTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageAnalysisTest.kt
index 2fb9866..935c0e1 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageAnalysisTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageAnalysisTest.kt
@@ -30,6 +30,7 @@
 import androidx.camera.core.Preview
 import androidx.camera.core.impl.ImageFormatConstants
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
+import androidx.camera.extensions.impl.ExtensionsTestlibControl
 import androidx.camera.extensions.internal.VendorExtender
 import androidx.camera.extensions.util.ExtensionsTestUtil
 import androidx.camera.lifecycle.ProcessCameraProvider
@@ -58,14 +59,15 @@
 @RunWith(Parameterized::class)
 @SdkSuppress(minSdkVersion = 21)
 class ImageAnalysisTest(
+    private val implType: ExtensionsTestlibControl.ImplementationType,
     @ExtensionMode.Mode private val extensionMode: Int,
     @CameraSelector.LensFacing private val lensFacing: Int
 ) {
     companion object {
         @JvmStatic
-        @get:Parameterized.Parameters(name = "extension = {0}, facing = {1}")
+        @get:Parameterized.Parameters(name = "implType = {0}, mode = {1}, facing = {2}")
         val parameters: Collection<Array<Any>>
-            get() = ExtensionsTestUtil.getAllExtensionsLensFacingCombinations()
+            get() = ExtensionsTestUtil.getAllImplExtensionsLensFacingCombinations()
     }
 
     @get:Rule
@@ -91,6 +93,7 @@
         )
 
         cameraProvider = ProcessCameraProvider.getInstance(context)[10000, TimeUnit.MILLISECONDS]
+        ExtensionsTestlibControl.getInstance().setImplementationType(implType)
         baseCameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
         extensionsManager = ExtensionsManager.getInstanceAsync(
             context,
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureTest.kt
index 3a8d018..96616ad 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureTest.kt
@@ -17,10 +17,13 @@
 package androidx.camera.extensions
 
 import android.content.Context
+import android.graphics.Bitmap
 import android.graphics.ImageFormat
 import android.graphics.SurfaceTexture
 import android.util.Size
+import android.view.Surface
 import androidx.camera.camera2.Camera2Config
+import androidx.camera.core.Camera
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.ImageCapture
 import androidx.camera.core.ImageCaptureException
@@ -28,6 +31,7 @@
 import androidx.camera.core.Preview
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
 import androidx.camera.core.internal.compat.workaround.ExifRotationAvailability
+import androidx.camera.extensions.impl.ExtensionsTestlibControl
 import androidx.camera.extensions.util.ExtensionsTestUtil
 import androidx.camera.lifecycle.ProcessCameraProvider
 import androidx.camera.testing.impl.CameraUtil
@@ -47,6 +51,7 @@
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withTimeoutOrNull
 import org.junit.After
+import org.junit.Assert.assertTrue
 import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Rule
@@ -62,6 +67,7 @@
 @RunWith(Parameterized::class)
 @SdkSuppress(minSdkVersion = 21)
 class ImageCaptureTest(
+    private val implType: ExtensionsTestlibControl.ImplementationType,
     @field:ExtensionMode.Mode @param:ExtensionMode.Mode private val extensionMode: Int,
     @field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
 ) {
@@ -98,6 +104,7 @@
 
         cameraProvider = ProcessCameraProvider.getInstance(context)[10000, TimeUnit.MILLISECONDS]
         baseCameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
+        ExtensionsTestlibControl.getInstance().setImplementationType(implType)
         extensionsManager = ExtensionsManager.getInstanceAsync(
             context,
             cameraProvider
@@ -128,9 +135,9 @@
 
     companion object {
         @JvmStatic
-        @get:Parameterized.Parameters(name = "extension = {0}, facing = {1}")
+        @get:Parameterized.Parameters(name = "impl= {0}, mode = {1}, facing = {2}")
         val parameters: Collection<Array<Any>>
-            get() = ExtensionsTestUtil.getAllExtensionsLensFacingCombinations()
+            get() = ExtensionsTestUtil.getAllImplExtensionsLensFacingCombinations()
     }
 
     @Test
@@ -216,14 +223,16 @@
 
     private suspend fun bindAndTakePicture(
         onImageCaptureCallback: ImageCapture.OnImageCapturedCallback,
+        targetRotation: Int? = null,
         enablePostview: Boolean = false
-    ) {
+    ): Camera {
         // To test bind/unbind and take picture.
-        val imageCapture = ImageCapture.Builder()
-            .setPostviewEnabled(enablePostview)
-            .build()
+        val imageCapture = ImageCapture.Builder().apply {
+            targetRotation?.let { setTargetRotation(it) }
+            setPostviewEnabled(enablePostview)
+        }.build()
         val preview = Preview.Builder().build()
-        withContext(Dispatchers.Main) {
+        return withContext(Dispatchers.Main) {
             // To set the update listener and Preview will change to active state.
             preview.setSurfaceProvider(
                 SurfaceTextureProvider.createSurfaceTextureProvider(
@@ -243,7 +252,7 @@
                     })
             )
 
-            cameraProvider.bindToLifecycle(
+            val camera = cameraProvider.bindToLifecycle(
                 fakeLifecycleOwner,
                 extensionsCameraSelector,
                 preview,
@@ -254,19 +263,22 @@
                 CameraXExecutors.mainThreadExecutor(),
                 onImageCaptureCallback
             )
+            camera
         }
     }
 
     private suspend fun bindAndTakePicture(
         onImageSavedCallback: ImageCapture.OnImageSavedCallback,
+        targetRotation: Int? = null,
         enablePostview: Boolean = false
-    ) {
+    ): Camera {
         // To test bind/unbind and take picture.
-        val imageCapture = ImageCapture.Builder()
-            .setPostviewEnabled(enablePostview)
-            .build()
+        val imageCapture = ImageCapture.Builder().apply {
+            targetRotation?.let { setTargetRotation(it) }
+            setPostviewEnabled(enablePostview)
+        }.build()
         val preview = Preview.Builder().build()
-        withContext(Dispatchers.Main) {
+        return withContext(Dispatchers.Main) {
             // To set the update listener and Preview will change to active state.
             preview.setSurfaceProvider(
                 SurfaceTextureProvider.createSurfaceTextureProvider(
@@ -286,7 +298,7 @@
                     })
             )
 
-            cameraProvider.bindToLifecycle(
+            val camera = cameraProvider.bindToLifecycle(
                 fakeLifecycleOwner,
                 extensionsCameraSelector,
                 preview,
@@ -302,6 +314,7 @@
                 CameraXExecutors.mainThreadExecutor(),
                 onImageSavedCallback
             )
+            camera
         }
     }
 
@@ -385,10 +398,11 @@
 
         val captureStartedDeferred = CompletableDeferred<Boolean>()
         val captureSuccessDeferred = CompletableDeferred<ImageProxy>()
-        val PostviewDeferred = CompletableDeferred<ImageProxy>()
+        val PostviewDeferred = CompletableDeferred<Bitmap>()
         var hasError = false
+        val targetRotation = Surface.ROTATION_0
 
-        bindAndTakePicture(object : ImageCapture.OnImageCapturedCallback() {
+        val camera = bindAndTakePicture(object : ImageCapture.OnImageCapturedCallback() {
             override fun onError(exception: ImageCaptureException) {
                 hasError = true
             }
@@ -398,19 +412,21 @@
             override fun onCaptureSuccess(image: ImageProxy) {
                 captureSuccessDeferred.complete(image)
             }
-            override fun onPostviewImageAvailable(image: ImageProxy) {
-                PostviewDeferred.complete(image)
+            override fun onPostviewBitmapAvailable(bitmap: Bitmap) {
+                PostviewDeferred.complete(bitmap)
             }
-        }, enablePostview = true)
+        }, enablePostview = true, targetRotation = targetRotation)
+        val rotationDegree = camera.cameraInfo.getSensorRotationDegrees(targetRotation)
+        val isFlipped = (rotationDegree % 180) != 0
 
         assertThat(withTimeoutOrNull(5000) { captureStartedDeferred.await() }).isTrue()
 
-        withTimeoutOrNull(5000) { PostviewDeferred.await() }.use {
+        withTimeoutOrNull(5000) { PostviewDeferred.await() }.let {
             assertThat(it).isNotNull()
-            assertThat(it!!.format).isEqualTo(ImageFormat.JPEG)
-            if (isRotationOptionSupportedDevice()) {
-                val exif = ExifUtil.getExif(it)
-                assertThat(exif!!.rotation).isEqualTo(it.imageInfo.rotationDegrees)
+            if (isFlipped) {
+                assertTrue(it!!.width <= it.height)
+            } else {
+                assertTrue(it!!.height <= it.width)
             }
         }
 
@@ -432,10 +448,11 @@
 
         val captureStartedDeferred = CompletableDeferred<Boolean>()
         val imageSavedDeferred = CompletableDeferred<ImageCapture.OutputFileResults>()
-        val PostviewDeferred = CompletableDeferred<ImageProxy>()
+        val PostviewDeferred = CompletableDeferred<Bitmap>()
         var hasError = false
+        val targetRotation = Surface.ROTATION_0
 
-        bindAndTakePicture(object : ImageCapture.OnImageSavedCallback {
+        val camera = bindAndTakePicture(object : ImageCapture.OnImageSavedCallback {
             override fun onError(exception: ImageCaptureException) {
                 hasError = true
             }
@@ -446,19 +463,21 @@
             override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                 imageSavedDeferred.complete(outputFileResults)
             }
-            override fun onPostviewImageAvailable(image: ImageProxy) {
-                PostviewDeferred.complete(image)
+            override fun onPostviewBitmapAvailable(bitmap: Bitmap) {
+                PostviewDeferred.complete(bitmap)
             }
         }, enablePostview = true)
+        val rotationDegree = camera.cameraInfo.getSensorRotationDegrees(targetRotation)
+        val isFlipped = (rotationDegree % 180) != 0
 
         assertThat(withTimeoutOrNull(5000) { captureStartedDeferred.await() }).isTrue()
 
-        withTimeoutOrNull(5000) { PostviewDeferred.await() }.use {
+        withTimeoutOrNull(5000) { PostviewDeferred.await() }.let {
             assertThat(it).isNotNull()
-            assertThat(it!!.format).isEqualTo(ImageFormat.JPEG)
-            if (isRotationOptionSupportedDevice()) {
-                val exif = ExifUtil.getExif(it)
-                assertThat(exif!!.rotation).isEqualTo(it.imageInfo.rotationDegrees)
+            if (isFlipped) {
+                assertTrue(it!!.width <= it.height)
+            } else {
+                assertTrue(it!!.height <= it.width)
             }
         }
 
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewTest.kt
index 7ba9407..ef828d0 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewTest.kt
@@ -24,6 +24,7 @@
 import androidx.camera.camera2.Camera2Config
 import androidx.camera.core.CameraSelector
 import androidx.camera.core.Preview
+import androidx.camera.extensions.impl.ExtensionsTestlibControl
 import androidx.camera.extensions.util.ExtensionsTestUtil
 import androidx.camera.lifecycle.ProcessCameraProvider
 import androidx.camera.testing.impl.CameraUtil
@@ -53,6 +54,7 @@
 @RunWith(Parameterized::class)
 @SdkSuppress(minSdkVersion = 21)
 class PreviewTest(
+    private val implType: ExtensionsTestlibControl.ImplementationType,
     @field:ExtensionMode.Mode @param:ExtensionMode.Mode private val extensionMode: Int,
     @field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
 ) {
@@ -119,6 +121,7 @@
         )
 
         cameraProvider = ProcessCameraProvider.getInstance(context)[10000, TimeUnit.MILLISECONDS]
+        ExtensionsTestlibControl.getInstance().setImplementationType(implType)
         baseCameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
         extensionsManager = ExtensionsManager.getInstanceAsync(
             context,
@@ -150,9 +153,9 @@
 
     companion object {
         @JvmStatic
-        @get:Parameterized.Parameters(name = "extension = {0}, facing = {1}")
+        @get:Parameterized.Parameters(name = "implType = {0}, mode = {1}, facing = {2}")
         val parameters: Collection<Array<Any>>
-            get() = ExtensionsTestUtil.getAllExtensionsLensFacingCombinations()
+            get() = ExtensionsTestUtil.getAllImplExtensionsLensFacingCombinations()
     }
 
     @UiThreadTest
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/VideoCaptureTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/VideoCaptureTest.kt
index 8348eeb..69bcb78 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/VideoCaptureTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/VideoCaptureTest.kt
@@ -29,6 +29,7 @@
 import androidx.camera.core.Preview
 import androidx.camera.core.Preview.SurfaceProvider
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
+import androidx.camera.extensions.impl.ExtensionsTestlibControl
 import androidx.camera.extensions.util.ExtensionsTestUtil
 import androidx.camera.lifecycle.ProcessCameraProvider
 import androidx.camera.testing.impl.AndroidUtil.skipVideoRecordingTestIfNotSupportedByEmulator
@@ -66,6 +67,7 @@
 @RunWith(Parameterized::class)
 @SdkSuppress(minSdkVersion = 21)
 class VideoCaptureTest(
+    private val implType: ExtensionsTestlibControl.ImplementationType,
     @field:ExtensionMode.Mode @param:ExtensionMode.Mode private val extensionMode: Int,
     @field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
 ) {
@@ -130,6 +132,7 @@
         skipVideoRecordingTestIfNotSupportedByEmulator()
 
         cameraProvider = ProcessCameraProvider.getInstance(context)[10000, TimeUnit.MILLISECONDS]
+        ExtensionsTestlibControl.getInstance().setImplementationType(implType)
         baseCameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
         extensionsManager = ExtensionsManager.getInstanceAsync(
             context,
@@ -280,8 +283,8 @@
         private const val TAG = "VideoCaptureTest"
 
         @JvmStatic
-        @get:Parameterized.Parameters(name = "extension = {0}, facing = {1}")
+        @get:Parameterized.Parameters(name = "implType = {0}, mode = {1}, facing = {2}")
         val parameters: Collection<Array<Any>>
-            get() = ExtensionsTestUtil.getAllExtensionsLensFacingCombinations()
+            get() = ExtensionsTestUtil.getAllImplExtensionsLensFacingCombinations()
     }
 }
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
index 22d42d2..a2757be 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
@@ -662,10 +662,8 @@
         fakeCaptureExtenderImpl.postviewSupportedSizes = postviewSizes
 
         // 2. Act and Assert
-        // BasiccVendorExtender is supposed to convert the YUV supported sizes into JPEG supported
-        // size.s
         assertThat(basicExtenderSessionProcessor.getSupportedPostviewSize(Size(1920, 1080))
-            .get(ImageFormat.JPEG)).containsExactly(Size(1920, 1080), Size(640, 480))
+            .get(ImageFormat.YUV_420_888)).containsExactly(Size(1920, 1080), Size(640, 480))
     }
 
     private suspend fun initBasicExtenderSessionProcessor(): AutoCloseable {
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessorTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessorTest.kt
index ceb3377..8519505 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessorTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessorTest.kt
@@ -263,7 +263,7 @@
     }
 
     @Test
-    fun canStartCaptureWithPostviewWithRotation(): Unit = runBlocking {
+    fun canStartCaptureWithPostview(): Unit = runBlocking {
         Assume.assumeTrue(
             ClientVersion.isMinimumCompatibleVersion(Version.VERSION_1_4) &&
                 ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)
@@ -281,20 +281,18 @@
         )
 
         val postviewImageReader = ImageReaderProxys.createIsolatedReader(
-            WIDTH, HEIGHT, ImageFormat.JPEG, 2)
+            WIDTH, HEIGHT, ImageFormat.YUV_420_888, 2)
         val postviewOutputSurface = OutputSurface.create(
             postviewImageReader.surface!!,
-            Size(WIDTH, HEIGHT), ImageFormat.JPEG
+            Size(WIDTH, HEIGHT), ImageFormat.YUV_420_888
         )
 
-        val rotationDegrees = 270
         stillCaptureProcessor = StillCaptureProcessor(
             fakeCaptureProcessorImpl,
             imageReaderJpeg.surface!!,
             Size(WIDTH, HEIGHT),
             postviewOutputSurface
         )
-        stillCaptureProcessor.setRotationDegrees(rotationDegrees)
 
         val captureSession = Camera2Util.openCaptureSession(
             cameraDevice!!.unwrap(), listOf(cameraYuvImageReader!!.surface), backgroundHandler
@@ -318,9 +316,7 @@
             }
 
             val postviewImage = postviewDeferred.await()
-            assertThat(postviewImage.format).isEqualTo(ImageFormat.JPEG)
-            val exif = Exif.createFromImageProxy(postviewImage)
-            assertThat(exif.rotation).isEqualTo(rotationDegrees)
+            assertThat(postviewImage.format).isEqualTo(ImageFormat.YUV_420_888)
         }
 
         postviewImageReader.close()
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
index a9f652d..8f92a27 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
@@ -21,6 +21,9 @@
 import static androidx.camera.extensions.ExtensionMode.FACE_RETOUCH;
 import static androidx.camera.extensions.ExtensionMode.HDR;
 import static androidx.camera.extensions.ExtensionMode.NIGHT;
+import static androidx.camera.extensions.impl.ExtensionsTestlibControl.ImplementationType.OEM_IMPL;
+import static androidx.camera.extensions.impl.ExtensionsTestlibControl.ImplementationType.TESTLIB_ADVANCED;
+import static androidx.camera.extensions.impl.ExtensionsTestlibControl.ImplementationType.TESTLIB_BASIC;
 
 import android.hardware.camera2.CameraCharacteristics;
 import android.os.Build;
@@ -29,6 +32,7 @@
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.extensions.ExtensionMode;
+import androidx.camera.extensions.impl.ExtensionsTestlibControl;
 import androidx.camera.extensions.internal.AdvancedVendorExtender;
 import androidx.camera.extensions.internal.BasicVendorExtender;
 import androidx.camera.extensions.internal.ExtensionVersion;
@@ -37,28 +41,65 @@
 import androidx.camera.extensions.internal.compat.workaround.ExtensionDisabledValidator;
 import androidx.camera.testing.impl.CameraUtil;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 
 /**
  * Extension test util functions.
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 public class ExtensionsTestUtil {
+
+    /**
+     * Returns the parameters which contains the combination of implementationType, extensions
+     * mode and lens facing.
+     */
     @NonNull
-    public static Collection<Object[]> getAllExtensionsLensFacingCombinations() {
-        return Arrays.asList(new Object[][]{
-                {BOKEH, CameraSelector.LENS_FACING_FRONT},
-                {BOKEH, CameraSelector.LENS_FACING_BACK},
-                {HDR, CameraSelector.LENS_FACING_FRONT},
-                {HDR, CameraSelector.LENS_FACING_BACK},
-                {FACE_RETOUCH, CameraSelector.LENS_FACING_FRONT},
-                {FACE_RETOUCH, CameraSelector.LENS_FACING_BACK},
-                {NIGHT, CameraSelector.LENS_FACING_FRONT},
-                {NIGHT, CameraSelector.LENS_FACING_BACK},
-                {AUTO, CameraSelector.LENS_FACING_FRONT},
-                {AUTO, CameraSelector.LENS_FACING_BACK}
+    public static Collection<Object[]> getAllImplExtensionsLensFacingCombinations() {
+        ExtensionsTestlibControl.ImplementationType implType =
+                ExtensionsTestlibControl.getInstance().getImplementationType();
+
+        if (implType == TESTLIB_ADVANCED) {
+            ExtensionsTestlibControl.getInstance().setImplementationType(TESTLIB_BASIC);
+            implType = TESTLIB_BASIC;
+        }
+
+        List<Object[]> basicOrOemImplList = Arrays.asList(new Object[][]{
+                {implType, BOKEH, CameraSelector.LENS_FACING_FRONT},
+                {implType, BOKEH, CameraSelector.LENS_FACING_BACK},
+                {implType, HDR, CameraSelector.LENS_FACING_FRONT},
+                {implType, HDR, CameraSelector.LENS_FACING_BACK},
+                {implType, FACE_RETOUCH, CameraSelector.LENS_FACING_FRONT},
+                {implType, FACE_RETOUCH, CameraSelector.LENS_FACING_BACK},
+                {implType, NIGHT, CameraSelector.LENS_FACING_FRONT},
+                {implType, NIGHT, CameraSelector.LENS_FACING_BACK},
+                {implType, AUTO, CameraSelector.LENS_FACING_FRONT},
+                {implType, AUTO, CameraSelector.LENS_FACING_BACK}
         });
+
+        if (implType == OEM_IMPL) {
+            return basicOrOemImplList;
+        }
+
+        List<Object[]> advancedList = Arrays.asList(new Object[][]{
+                {TESTLIB_ADVANCED, BOKEH, CameraSelector.LENS_FACING_FRONT},
+                {TESTLIB_ADVANCED, BOKEH, CameraSelector.LENS_FACING_BACK},
+                {TESTLIB_ADVANCED, HDR, CameraSelector.LENS_FACING_FRONT},
+                {TESTLIB_ADVANCED, HDR, CameraSelector.LENS_FACING_BACK},
+                {TESTLIB_ADVANCED, FACE_RETOUCH, CameraSelector.LENS_FACING_FRONT},
+                {TESTLIB_ADVANCED, FACE_RETOUCH, CameraSelector.LENS_FACING_BACK},
+                {TESTLIB_ADVANCED, NIGHT, CameraSelector.LENS_FACING_FRONT},
+                {TESTLIB_ADVANCED, NIGHT, CameraSelector.LENS_FACING_BACK},
+                {TESTLIB_ADVANCED, AUTO, CameraSelector.LENS_FACING_FRONT},
+                {TESTLIB_ADVANCED, AUTO, CameraSelector.LENS_FACING_BACK}
+        });
+
+        List<Object[]> allList = new ArrayList<>();
+        allList.addAll(basicOrOemImplList);
+        allList.addAll(advancedList);
+        return allList;
     }
 
     /**
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java
index 14bf4a1..11975ad 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java
@@ -39,6 +39,7 @@
 import androidx.camera.extensions.impl.advanced.HdrAdvancedExtenderImpl;
 import androidx.camera.extensions.impl.advanced.NightAdvancedExtenderImpl;
 import androidx.camera.extensions.internal.compat.workaround.ExtensionDisabledValidator;
+import androidx.camera.extensions.internal.compat.workaround.ImageAnalysisAvailability;
 import androidx.camera.extensions.internal.sessionprocessor.AdvancedSessionProcessor;
 import androidx.core.util.Preconditions;
 
@@ -57,6 +58,7 @@
             new ExtensionDisabledValidator();
     private final AdvancedExtenderImpl mAdvancedExtenderImpl;
     private String mCameraId;
+    private final @ExtensionMode.Mode int mMode;
 
     public AdvancedVendorExtender(@ExtensionMode.Mode int mode) {
         try {
@@ -80,6 +82,7 @@
                 default:
                     throw new IllegalArgumentException("Should not active ExtensionMode.NONE");
             }
+            mMode = mode;
         } catch (NoClassDefFoundError e) {
             throw new IllegalArgumentException("AdvancedExtenderImpl does not exist");
         }
@@ -88,6 +91,7 @@
     @VisibleForTesting
     AdvancedVendorExtender(AdvancedExtenderImpl advancedExtenderImpl) {
         mAdvancedExtenderImpl = advancedExtenderImpl;
+        mMode = ExtensionMode.NONE;
     }
 
     @Override
@@ -152,6 +156,11 @@
     @Override
     public Size[] getSupportedYuvAnalysisResolutions() {
         Preconditions.checkNotNull(mCameraId, "VendorExtender#init() must be called first");
+        ImageAnalysisAvailability imageAnalysisAvailability = new ImageAnalysisAvailability();
+        if (!imageAnalysisAvailability.isAvailable(mCameraId, mMode)) {
+            return new Size[0];
+        }
+
         List<Size> yuvList = mAdvancedExtenderImpl.getSupportedYuvAnalysisResolutions(mCameraId);
         return yuvList == null ? new Size[0] : yuvList.toArray(new Size[0]);
     }
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java
index 657cfd5..e190a59 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java
@@ -49,6 +49,7 @@
 import androidx.camera.extensions.impl.NightPreviewExtenderImpl;
 import androidx.camera.extensions.impl.PreviewExtenderImpl;
 import androidx.camera.extensions.internal.compat.workaround.AvailableKeysRetriever;
+import androidx.camera.extensions.internal.compat.workaround.BasicExtenderSurfaceCombinationAvailability;
 import androidx.camera.extensions.internal.compat.workaround.ExtensionDisabledValidator;
 import androidx.camera.extensions.internal.compat.workaround.ImageAnalysisAvailability;
 import androidx.camera.extensions.internal.sessionprocessor.BasicExtenderSessionProcessor;
@@ -310,15 +311,25 @@
     @NonNull
     @Override
     public Size[] getSupportedYuvAnalysisResolutions() {
+        Preconditions.checkNotNull(mCameraInfo, "VendorExtender#init() must be called first");
+
+        // check if the ImageAnalysis is available.
         ImageAnalysisAvailability imageAnalysisAvailability = new ImageAnalysisAvailability();
+        if (!imageAnalysisAvailability.isAvailable(mCameraId, mMode)) {
+            return new Size[0];
+        }
+
+        // check if the surface combination supports the ImageAnalysis.
+        BasicExtenderSurfaceCombinationAvailability
+                surfaceCombinationAvailability = new BasicExtenderSurfaceCombinationAvailability();
         boolean hasPreviewProcessor = mPreviewExtenderImpl.getProcessorType()
                 == PreviewExtenderImpl.ProcessorType.PROCESSOR_TYPE_IMAGE_PROCESSOR;
         boolean hasImageCaptureProcessor = mImageCaptureExtenderImpl.getCaptureProcessor() != null;
-        if (!imageAnalysisAvailability.isAvailable(mCameraId, getHardwareLevel(), mMode,
-                hasPreviewProcessor, hasImageCaptureProcessor)) {
+        if (!surfaceCombinationAvailability.isImageAnalysisAvailable(
+                getHardwareLevel(), hasPreviewProcessor, hasImageCaptureProcessor)) {
             return new Size[0];
         }
-        Preconditions.checkNotNull(mCameraInfo, "VendorExtender#init() must be called first");
+
         return getOutputSizes(ImageFormat.YUV_420_888);
     }
 
@@ -379,18 +390,13 @@
     public Map<Integer, List<Size>> getSupportedPostviewResolutions(@NonNull Size captureSize) {
         if (ClientVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)
                 && ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)) {
-            // For OEMs implementing basic extender, the supported format of the postview
-            // can only be YUV.
             List<Pair<Integer, Size[]>> list =
                     mImageCaptureExtenderImpl.getSupportedPostviewResolutions(captureSize);
             Map<Integer, List<Size>> result = new HashMap<>();
             for (Pair<Integer, Size[]> pair : list) {
                 int format = pair.first;
                 Size[] sizes = pair.second;
-                if (format == ImageFormat.YUV_420_888) {
-                    // Basic Extender convert the YUV format into JPEG format.
-                    result.put(ImageFormat.JPEG, Arrays.asList(sizes));
-                }
+                result.put(format, Arrays.asList(sizes));
             }
             return Collections.unmodifiableMap(result);
         }
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtraSupportedSurfaceCombinationsQuirk.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtraSupportedSurfaceCombinationsQuirk.java
index 023d5b8..0d080d5 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtraSupportedSurfaceCombinationsQuirk.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/quirk/ExtraSupportedSurfaceCombinationsQuirk.java
@@ -20,7 +20,7 @@
 
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.impl.Quirk;
-import androidx.camera.extensions.internal.compat.workaround.ImageAnalysisAvailability;
+import androidx.camera.extensions.internal.compat.workaround.BasicExtenderSurfaceCombinationAvailability;
 
 import java.util.Arrays;
 import java.util.HashSet;
@@ -36,7 +36,7 @@
  *                  + PRIV/PREVIEW + YUV/MAXIMUM and YUV/640x480 + YUV/PREVIEW + YUV/MAXIMUM
  *                  configurations.
  *     Device(s): Some Samsung devices
- *     @see ImageAnalysisAvailability
+ *     @see BasicExtenderSurfaceCombinationAvailability
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 public class ExtraSupportedSurfaceCombinationsQuirk implements Quirk {
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/BasicExtenderSurfaceCombinationAvailability.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/BasicExtenderSurfaceCombinationAvailability.java
new file mode 100644
index 0000000..85a93fa
--- /dev/null
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/BasicExtenderSurfaceCombinationAvailability.java
@@ -0,0 +1,81 @@
+/*
+ * 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.camera.extensions.internal.compat.workaround;
+
+import static android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_3;
+import static android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
+import static android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.ImageCapture;
+import androidx.camera.core.Preview;
+import androidx.camera.extensions.internal.compat.quirk.DeviceQuirks;
+import androidx.camera.extensions.internal.compat.quirk.ExtraSupportedSurfaceCombinationsQuirk;
+
+/**
+ * Workaround to check whether {@link ImageAnalysis} can be bound together with {@link Preview} and
+ * {@link ImageCapture} when enabling extensions.
+ *
+ * <p>This is used by the BasicVendorExtender to check whether the device can support to bind the
+ * additional ImageAnalysis UseCase.
+ *
+ * @see ExtraSupportedSurfaceCombinationsQuirk
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+public class BasicExtenderSurfaceCombinationAvailability {
+    ExtraSupportedSurfaceCombinationsQuirk mExtraSupportedSurfaceCombinationsQuirk =
+            DeviceQuirks.get(ExtraSupportedSurfaceCombinationsQuirk.class);
+
+    /**
+     * Returns whether {@link ImageAnalysis} is available to be bound together with
+     * {@link Preview} and {@link ImageCapture} for the specified camera id and extensions mode.
+     *
+     * @param hardwareLevel the camera device hardware level
+     * @param hasPreviewProcessor whether PreviewExtenderImpl has processor
+     * @param hasImageCaptureProcessor whether ImageCaptureExtenderImpl has processor
+     * @return {@code true} if {@link ImageAnalysis} is available. Otherwise, returns {@code
+     * false}.
+     */
+    public boolean isImageAnalysisAvailable(int hardwareLevel,
+            boolean hasPreviewProcessor,
+            boolean hasImageCaptureProcessor) {
+        // No matter what the device hardware is and no matter the Preview and the ImageCapture
+        // have processor or not, once ExtraSupportedSurfaceCombinationsQuirk can be loaded, the
+        // device can support to bind ImageAnalysis when enabling the extensions mode.
+        if (mExtraSupportedSurfaceCombinationsQuirk != null) {
+            return true;
+        }
+
+        if (!hasPreviewProcessor && !hasImageCaptureProcessor) {
+            // Required configuration: PRIV + JPEG + YUV
+            // Required HW level: any
+            return true;
+        } else if (hasPreviewProcessor && !hasImageCaptureProcessor) {
+            // Required configuration: YUV + JPEG + YUV
+            // Required HW level: LIMITED level or above
+            return hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
+                    || hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+                    || hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_3;
+        } else {
+            // Required configuration: PRIV + YUV + YUV or YUV + YUV + YUV
+            // Required HW level: FULL level or above
+            return hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+                    || hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_3;
+        }
+    }
+}
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailability.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailability.java
index 9500758..246c8001 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailability.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailability.java
@@ -16,10 +16,6 @@
 
 package androidx.camera.extensions.internal.compat.workaround;
 
-import static android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_3;
-import static android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
-import static android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.camera.core.ImageAnalysis;
@@ -27,71 +23,33 @@
 import androidx.camera.core.Preview;
 import androidx.camera.extensions.ExtensionMode;
 import androidx.camera.extensions.internal.compat.quirk.DeviceQuirks;
-import androidx.camera.extensions.internal.compat.quirk.ExtraSupportedSurfaceCombinationsQuirk;
 import androidx.camera.extensions.internal.compat.quirk.ImageAnalysisUnavailableQuirk;
 
 /**
  * Workaround to check whether {@link ImageAnalysis} can be bound together with {@link Preview} and
  * {@link ImageCapture} when enabling extensions.
  *
- * <p>This is used by the BasicVendorExtender to check whether the device can support to bind the
- * additional ImageAnalysis UseCase.
- *
- * @see ImageAnalysisUnavailableQuirk, ExtraSupportedSurfaceCombinationsQuirk
+ * @see ImageAnalysisUnavailableQuirk
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 public class ImageAnalysisAvailability {
     ImageAnalysisUnavailableQuirk mImageAnalysisUnavailableQuirk =
             DeviceQuirks.get(ImageAnalysisUnavailableQuirk.class);
 
-    ExtraSupportedSurfaceCombinationsQuirk mExtraSupportedSurfaceCombinationsQuirk =
-            DeviceQuirks.get(ExtraSupportedSurfaceCombinationsQuirk.class);
-
     /**
      * Returns whether {@link ImageAnalysis} is available to be bound together with
      * {@link Preview} and {@link ImageCapture} for the specified camera id and extensions mode.
      *
      * @param cameraId the camera id to query
-     * @param hardwareLevel the camera device hardware level
      * @param mode the extensions mode to query
-     * @param hasPreviewProcessor whether PreviewExtenderImpl has processor
-     * @param hasImageCaptureProcessor whether ImageCaptureExtenderImpl has processor
      * @return {@code true} if {@link ImageAnalysis} is available. Otherwise, returns {@code
      * false}.
      */
-    public boolean isAvailable(@NonNull String cameraId, int hardwareLevel,
-            @ExtensionMode.Mode int mode, boolean hasPreviewProcessor,
-            boolean hasImageCaptureProcessor) {
-        // When ImageAnalysisUnavailableQuirk is loaded and its isUnavailable() function returns
-        // true, directly return false that means the device can't support to bind ImageAnalysis
-        // when enabling the extensions mode.
+    public boolean isAvailable(@NonNull String cameraId, @ExtensionMode.Mode int mode) {
         if (mImageAnalysisUnavailableQuirk != null
                 && mImageAnalysisUnavailableQuirk.isUnavailable(cameraId, mode)) {
             return false;
         }
-
-        // No matter what the device hardware is and no matter the Preview and the ImageCapture
-        // have processor or not, once ExtraSupportedSurfaceCombinationsQuirk can be loaded, the
-        // device can support to bind ImageAnalysis when enabling the extensions mode.
-        if (mExtraSupportedSurfaceCombinationsQuirk != null) {
-            return true;
-        }
-
-        if (!hasPreviewProcessor && !hasImageCaptureProcessor) {
-            // Required configuration: PRIV + JPEG + YUV
-            // Required HW level: any
-            return true;
-        } else if (hasPreviewProcessor && !hasImageCaptureProcessor) {
-            // Required configuration: YUV + JPEG + YUV
-            // Required HW level: LIMITED level or above
-            return hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
-                    || hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_FULL
-                    || hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_3;
-        } else {
-            // Required configuration: PRIV + YUV + YUV or YUV + YUV + YUV
-            // Required HW level: FULL level or above
-            return hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_FULL
-                    || hardwareLevel == INFO_SUPPORTED_HARDWARE_LEVEL_3;
-        }
+        return true;
     }
 }
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessor.java
index 5646194..639b172 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/StillCaptureProcessor.java
@@ -44,6 +44,7 @@
 import androidx.camera.extensions.internal.ClientVersion;
 import androidx.camera.extensions.internal.ExtensionVersion;
 import androidx.camera.extensions.internal.Version;
+import androidx.core.util.Preconditions;
 
 import org.jetbrains.annotations.TestOnly;
 
@@ -78,14 +79,9 @@
     final CaptureResultImageMatcher mCaptureResultImageMatcher = new CaptureResultImageMatcher();
     @NonNull
     final ImageReaderProxy mProcessedYuvImageReader;
-    @Nullable
-    private ImageReaderProxy mPostviewYuvImageReader;
     private boolean mIsPostviewConfigured;
     @NonNull
     YuvToJpegConverter mYuvToJpegConverter;
-    @Nullable
-    YuvToJpegConverter mYuvToJpegConverterPostview;
-
     final Object mLock = new Object();
     @GuardedBy("mLock")
     @NonNull
@@ -166,33 +162,10 @@
         if (postviewOutputSurface != null
                 && ClientVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)
                 && ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)) {
-            mPostviewYuvImageReader = ImageReaderProxys.createIsolatedReader(
-                    postviewOutputSurface.getSize().getWidth(),
-                    postviewOutputSurface.getSize().getHeight(),
-                    ImageFormat.YUV_420_888, MAX_IMAGES);
-            mPostviewYuvImageReader.setOnImageAvailableListener(
-                    imageReader -> {
-                        synchronized (mLock) {
-                            if (mIsClosed) {
-                                Logger.d(TAG, "Ignore JPEG processing in closed state");
-                                return;
-                            }
-                            ImageProxy imageProxy = imageReader.acquireNextImage();
-                            if (imageProxy != null) {
-                                try {
-                                    mYuvToJpegConverterPostview.writeYuvImage(imageProxy);
-                                } catch (YuvToJpegConverter.ConversionFailedException e) {
-                                }
-                            }
-                        }
-                    }, CameraXExecutors.ioExecutor());
-
-
+            Preconditions.checkArgument(
+                    postviewOutputSurface.getImageFormat() == ImageFormat.YUV_420_888);
             mCaptureProcessorImpl.onResolutionUpdate(surfaceSize, postviewOutputSurface.getSize());
-            mCaptureProcessorImpl.onPostviewOutputSurface(mPostviewYuvImageReader.getSurface());
-
-            mYuvToJpegConverterPostview =
-                    new YuvToJpegConverter(90, postviewOutputSurface.getSurface());
+            mCaptureProcessorImpl.onPostviewOutputSurface(postviewOutputSurface.getSurface());
 
         } else {
             mCaptureProcessorImpl.onResolutionUpdate(surfaceSize);
@@ -289,7 +262,7 @@
                                                                     progress);
                                                 }
 
-                                            }, CameraXExecutors.ioExecutor());
+                                            }, CameraXExecutors.directExecutor());
                                 } else if (ExtensionVersion.isMinimumCompatibleVersion(
                                         Version.VERSION_1_3)
                                         && ClientVersion.isMinimumCompatibleVersion(
@@ -311,7 +284,7 @@
                                                     onCaptureResultCallback
                                                             .onCaptureProcessProgressed(progress);
                                                 }
-                                            }, CameraXExecutors.ioExecutor());
+                                            }, CameraXExecutors.directExecutor());
                                 } else {
                                     mCaptureProcessorImpl.process(convertedResult);
                                 }
@@ -348,17 +321,11 @@
 
     void setJpegQuality(@IntRange(from = 0, to = 100) int quality) {
         mYuvToJpegConverter.setJpegQuality(quality);
-        if (mYuvToJpegConverterPostview != null) {
-            mYuvToJpegConverterPostview.setJpegQuality(quality);
-        }
     }
 
     void setRotationDegrees(
             @ImageOutputConfig.RotationDegreesValue int rotationDegrees) {
         mYuvToJpegConverter.setRotationDegrees(rotationDegrees);
-        if (mYuvToJpegConverterPostview != null) {
-            mYuvToJpegConverterPostview.setRotationDegrees(rotationDegrees);
-        }
     }
 
     /**
@@ -374,10 +341,6 @@
             mCaptureResultImageMatcher.clearImageReferenceListener();
             mCaptureResultImageMatcher.clear();
             mProcessedYuvImageReader.close();
-            if (mPostviewYuvImageReader != null) {
-                mPostviewYuvImageReader.clearOnImageAvailableListener();
-                mPostviewYuvImageReader.close();
-            }
         }
     }
 }
diff --git a/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/BasicExtenderSurfaceCombinationAvailabilityTest.kt b/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/BasicExtenderSurfaceCombinationAvailabilityTest.kt
new file mode 100644
index 0000000..40f43cb
--- /dev/null
+++ b/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/BasicExtenderSurfaceCombinationAvailabilityTest.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.camera.extensions.internal.compat.workaround
+
+import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_3
+import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
+import android.os.Build
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.ParameterizedRobolectricTestRunner
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+import org.robolectric.util.ReflectionHelpers
+
+@RunWith(ParameterizedRobolectricTestRunner::class)
+@DoNotInstrument
+@Config(
+    minSdk = Build.VERSION_CODES.Q
+)
+class BasicExtenderSurfaceCombinationAvailabilityTest(private val config: Config) {
+
+    @Test
+    fun checkImageAnalysisAvailability() {
+        // Set up device properties
+        ReflectionHelpers.setStaticField(Build::class.java, "BRAND", config.brand)
+        ReflectionHelpers.setStaticField(Build::class.java, "DEVICE", config.device)
+        ReflectionHelpers.setStaticField(Build::class.java, "MODEL", config.model)
+        val basicExtenderImageAnalysisAvailability =
+                BasicExtenderSurfaceCombinationAvailability()
+        val isAvailable = basicExtenderImageAnalysisAvailability.isImageAnalysisAvailable(
+            config.hardwareLevel,
+            config.hasPreviewProcessor,
+            config.hasImageCaptureProcessor
+        )
+        assertThat(isAvailable).isEqualTo(config.isAvailable)
+    }
+
+    class Config(
+        val brand: String,
+        val device: String,
+        val model: String,
+        val hardwareLevel: Int,
+        val hasPreviewProcessor: Boolean,
+        val hasImageCaptureProcessor: Boolean,
+        val isAvailable: Boolean
+    )
+
+    companion object {
+        @JvmStatic
+        @ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
+        fun createTestSet(): List<Config> {
+            val levelLimited = INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
+            val levelFull = INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+            val level3 = INFO_SUPPORTED_HARDWARE_LEVEL_3
+            return listOf(
+                // Samsung Galaxy A51 (support extra full level surface combinations)
+                Config("Samsung", "", "SM-A515F", levelLimited, true, true, true),
+                Config("Samsung", "", "SM-A515F", levelLimited, true, false, true),
+                Config("Samsung", "", "SM-A515U", levelLimited, true, true, true),
+                Config("Samsung", "", "SM-A515U", levelLimited, true, false, true),
+                Config("Samsung", "", "SM-A515W", levelLimited, true, true, true),
+                Config("Samsung", "", "SM-A516U1", levelLimited, true, true, true),
+                Config("Samsung", "", "SM-A8050", levelLimited, true, true, true),
+                Config("Samsung", "", "SM-F907B", levelLimited, true, true, true),
+
+                // Other cases should be determined by hardware level and processors.
+                Config("", "", "", level3, true, true, true),
+                Config("", "", "", levelFull, true, true, true),
+                Config("", "", "", levelFull, false, true, true),
+                Config("", "", "", levelLimited, true, true, false),
+                Config("", "", "", levelLimited, true, false, true),
+                Config("", "", "", levelLimited, false, true, false),
+            )
+        }
+    }
+}
diff --git a/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailabilityTest.kt b/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailabilityTest.kt
index 3f79e33..42c95b7 100644
--- a/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailabilityTest.kt
+++ b/camera/camera-extensions/src/test/java/androidx/camera/extensions/internal/compat/workaround/ImageAnalysisAvailabilityTest.kt
@@ -16,14 +16,11 @@
 
 package androidx.camera.extensions.internal.compat.workaround
 
-import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_3
-import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL
-import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
 import android.os.Build
 import androidx.camera.extensions.ExtensionMode.BOKEH
 import androidx.camera.extensions.ExtensionMode.FACE_RETOUCH
 import androidx.camera.extensions.ExtensionMode.NIGHT
-import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.robolectric.ParameterizedRobolectricTestRunner
@@ -36,8 +33,7 @@
 @Config(
     minSdk = Build.VERSION_CODES.Q
 )
-class ImageAnalysisAvailabilityTest(private val config: TestConfig) {
-
+class ImageAnalysisAvailabilityTest(private val config: Config) {
     @Test
     fun checkImageAnalysisAvailability() {
         // Set up device properties
@@ -45,75 +41,60 @@
         ReflectionHelpers.setStaticField(Build::class.java, "DEVICE", config.device)
         ReflectionHelpers.setStaticField(Build::class.java, "MODEL", config.model)
         val imageAnalysisAvailability = ImageAnalysisAvailability()
-        assertThat(imageAnalysisAvailability.isAvailable(
-            config.cameraId,
-            config.hardwareLevel,
-            config.mode,
-            config.hasPreviewProcessor,
-            config.hasImageCaptureProcessor)).isEqualTo(
-            config.isAvailable
-        )
+        var isAvailable = imageAnalysisAvailability.isAvailable(config.cameraId, config.mode)
+        Truth.assertThat(isAvailable).isEqualTo(config.isAvailable)
     }
 
-    class TestConfig(
+    class Config(
         val brand: String,
         val device: String,
         val model: String,
         val cameraId: String,
-        val hardwareLevel: Int,
         val mode: Int,
-        val hasPreviewProcessor: Boolean,
-        val hasImageCaptureProcessor: Boolean,
         val isAvailable: Boolean
     )
 
     companion object {
         @JvmStatic
         @ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
-        fun createTestSet(): List<TestConfig> {
-            val levelLimited = INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
-            val levelFull = INFO_SUPPORTED_HARDWARE_LEVEL_FULL
-            val level3 = INFO_SUPPORTED_HARDWARE_LEVEL_3
+        fun createTestSet(): List<Config> {
             return listOf(
                 // Samsung Galaxy S23 Ultra 5G tests
-                TestConfig("Samsung", "dm3q", "", "0", level3, BOKEH, true, true, false),
-                TestConfig("Samsung", "dm3q", "", "0", levelFull, FACE_RETOUCH, true, true, false),
-                TestConfig("Samsung", "dm3q", "", "1", levelFull, FACE_RETOUCH, true, true, false),
-                TestConfig("Samsung", "dm3q", "", "2", levelLimited, BOKEH, true, true, false),
+                Config("Samsung", "dm3q", "", "0", BOKEH, false),
+                Config("Samsung", "dm3q", "", "0", FACE_RETOUCH, false),
+                Config("Samsung", "dm3q", "", "1", BOKEH, false),
+                Config("Samsung", "dm3q", "", "1", FACE_RETOUCH, false),
+                Config("Samsung", "dm3q", "", "3", BOKEH, false),
+                Config("Samsung", "dm3q", "", "3", FACE_RETOUCH, false),
+                Config("Samsung", "dm3q", "", "2", BOKEH, true),
+                Config("Samsung", "dm3q", "", "0", NIGHT, true),
 
                 // Samsung Galaxy Z Fold3 5G
-                TestConfig("Samsung", "q2q", "", "0", level3, BOKEH, true, true, false),
-                TestConfig("Samsung", "q2q", "", "0", level3, FACE_RETOUCH, true, true, false),
-                TestConfig("Samsung", "q2q", "", "1", levelLimited, BOKEH, true, true, false),
+                Config("Samsung", "q2q", "", "0", BOKEH, false),
+                Config("Samsung", "q2q", "", "0", FACE_RETOUCH, false),
+                Config("Samsung", "q2q", "", "1", BOKEH, true),
+                Config("Samsung", "q2q", "", "0", NIGHT, true),
 
                 // Samsung Galaxy A52s 5G
-                TestConfig("Samsung", "a52sxq", "", "0", level3, BOKEH, true, true, false),
-                TestConfig("Samsung", "a52sxq", "", "0", level3, BOKEH, true, true, false),
-                TestConfig("Samsung", "a52sxq", "", "1", levelLimited, BOKEH, true, true, false),
+                Config("Samsung", "a52sxq", "", "0", BOKEH, false),
+                Config("Samsung", "a52sxq", "", "0", FACE_RETOUCH, false),
+                Config("Samsung", "a52sxq", "", "1", BOKEH, true),
+                Config("Samsung", "a52sxq", "", "1", FACE_RETOUCH, true),
 
                 // Samsung Galaxy S22 Ultra tests
-                TestConfig("Samsung", "b0q", "", "0", level3, BOKEH, true, true, true),
-                TestConfig("Samsung", "b0q", "", "3", levelFull, BOKEH, true, true, false),
-                TestConfig("Samsung", "b0q", "", "3", levelFull, FACE_RETOUCH, true, true, false),
-
-                // Samsung Galaxy A51 (support extra full level surface combinations)
-                TestConfig("Samsung", "", "SM-A515F", "1", levelLimited, BOKEH, true, true, true),
-
-                // Other cases should be determined by hardware level and processors.
-                TestConfig("", "", "", "0", level3, BOKEH, true, true, true),
-                TestConfig("", "", "", "0", levelFull, BOKEH, true, true, true),
-                TestConfig("", "", "", "0", levelFull, BOKEH, false, true, true),
-                TestConfig("", "", "", "0", levelLimited, BOKEH, true, true, false),
-                TestConfig("", "", "", "0", levelLimited, BOKEH, true, false, true),
-                TestConfig("", "", "", "0", levelLimited, BOKEH, false, true, false),
+                Config("Samsung", "b0q", "", "3", BOKEH, false),
+                Config("Samsung", "b0q", "", "3", FACE_RETOUCH, false),
+                Config("Samsung", "b0q", "", "0", BOKEH, true),
+                Config("Samsung", "b0q", "", "0", FACE_RETOUCH, true),
 
                 // Google Pixel doesn't support ImageAnalysis.
-                TestConfig("google", "", "redfin", "0", levelLimited, BOKEH, true, true, false),
-                TestConfig("google", "", "oriole", "0", levelLimited, BOKEH, false, false, false),
+                Config("google", "", "redfin", "0", BOKEH, false),
+                Config("google", "", "oriole", "1", NIGHT, false),
+                Config("google", "", "pixel unknown", "0", BOKEH, false),
 
                 // Xiaomi 13T Pro doesn't support ImageAnalysis.
-                TestConfig("xiaomi", "corot", "", "0", level3, NIGHT, false, true, false),
-                TestConfig("xiaomi", "corot", "", "1", level3, NIGHT, false, true, false),
+                Config("xiaomi", "corot", "", "0", NIGHT, false),
+                Config("xiaomi", "corot", "", "1", NIGHT, false),
             )
         }
     }
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
index 68a27ed..5048cbb 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraInfoInternal.java
@@ -26,6 +26,7 @@
 import androidx.annotation.FloatRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.CameraState;
 import androidx.camera.core.DynamicRange;
@@ -35,6 +36,7 @@
 import androidx.camera.core.ZoomState;
 import androidx.camera.core.impl.CameraCaptureCallback;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.core.impl.DynamicRanges;
 import androidx.camera.core.impl.EncoderProfilesProvider;
 import androidx.camera.core.impl.ImageOutputConfig.RotationValue;
 import androidx.camera.core.impl.Quirk;
@@ -260,6 +262,30 @@
         return mSupportedDynamicRanges;
     }
 
+    /**
+     * Returns the supported dynamic ranges of this camera from a set of candidate dynamic ranges.
+     *
+     * <p>The dynamic ranges which represent what the camera supports will come from the dynamic
+     * ranges set on {@link #setSupportedDynamicRanges(Set)}, or will consist of {@code {SDR}} if
+     * {@code setSupportedDynamicRanges(Set)} has not been called. In order to stay compliant
+     * with the API contract of
+     * {@link androidx.camera.core.CameraInfo#querySupportedDynamicRanges(Set)}, it is
+     * required that the {@link Set} provided to {@code setSupportedDynamicRanges(Set)} should
+     * always contain {@link DynamicRange#SDR} and should never contain under-specified dynamic
+     * ranges, such as {@link DynamicRange#UNSPECIFIED} and
+     * {@link DynamicRange#HDR_UNSPECIFIED_10_BIT}.
+     *
+     * @see androidx.camera.core.CameraInfo#querySupportedDynamicRanges(Set)
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @NonNull
+    @Override
+    public Set<DynamicRange> querySupportedDynamicRanges(
+            @NonNull Set<DynamicRange> candidateDynamicRanges) {
+        return DynamicRanges.findAllPossibleMatches(
+                candidateDynamicRanges, getSupportedDynamicRanges());
+    }
+
     @Override
     public void addSessionCaptureCallback(@NonNull Executor executor,
             @NonNull CameraCaptureCallback callback) {
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceEffect.java b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceEffect.java
index 5166d0c..26925b4 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceEffect.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceEffect.java
@@ -58,6 +58,21 @@
      * <p> This is helpful when we want to make sure the {@link SurfaceProcessorInternal} is
      * released properly.
      */
+    public FakeSurfaceEffect(@Targets int targets, @Transformations int transformation,
+            @NonNull SurfaceProcessorInternal surfaceProcessorInternal) {
+        super(targets, transformation, mainThreadExecutor(), surfaceProcessorInternal,
+                throwable -> {
+                });
+        mSurfaceProcessorInternal = surfaceProcessorInternal;
+    }
+
+    /**
+     * Create a fake {@link CameraEffect} the {@link #createSurfaceProcessorInternal} value
+     * overridden.
+     *
+     * <p> This is helpful when we want to make sure the {@link SurfaceProcessorInternal} is
+     * released properly.
+     */
     public FakeSurfaceEffect(@Targets int targets,
             @NonNull SurfaceProcessorInternal surfaceProcessorInternal) {
         super(targets, mainThreadExecutor(), surfaceProcessorInternal, throwable -> {
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceProcessor.java b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceProcessor.java
index c0aed34..d97e4fe 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceProcessor.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/fakes/FakeSurfaceProcessor.java
@@ -43,7 +43,6 @@
     private final Executor mExecutor;
     private final boolean mAutoCloseSurfaceOutput;
 
-
     @Nullable
     private SurfaceRequest mSurfaceRequest;
     @NonNull
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
index 5235e59..7df0fe49 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
@@ -87,6 +87,15 @@
      * @since 1.2
      */
     public boolean isAdvancedExtenderImplemented() {
-        return false;
+        return ExtensionsTestlibControl.getInstance().getImplementationType()
+                == ExtensionsTestlibControl.ImplementationType.TESTLIB_ADVANCED;
+    }
+
+    /**
+     * This method is used to check if test lib is running. If OEM implementation exists, invoking
+     * this method will throw {@link NoSuchMethodError}. This can be used to determine if OEM
+     * implementation is used or not.
+     */
+    public void checkTestlibRunning() {
     }
 }
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionsTestlibControl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionsTestlibControl.java
index 6cf35b5..344d9ac 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionsTestlibControl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionsTestlibControl.java
@@ -21,19 +21,25 @@
 
 /**
  * An internal utility class that allows tests to specify whether to enable basic extender or
- * advanced extender of this testlib.
+ * advanced extender of this testlib. If OEM implementation exists on the device, the
+ * implementation type is always {@link ImplementationType#OEM_IMPL} and can't be changed to
+ * other types.
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 public class ExtensionsTestlibControl {
     public enum ImplementationType {
-        ADVANCED_EXTENDER,
-        BASIC_EXTENDER
+        OEM_IMPL,
+        TESTLIB_ADVANCED,
+        TESTLIB_BASIC
     }
 
     private static ExtensionsTestlibControl sInstance;
     private static Object sLock = new Object();
+    private volatile ImplementationType mImplementationType = ImplementationType.TESTLIB_BASIC;
 
     private ExtensionsTestlibControl() {
+        mImplementationType = doesOEMImplementationExist()
+                ? ImplementationType.OEM_IMPL : ImplementationType.TESTLIB_BASIC;
     }
 
     /**
@@ -49,15 +55,43 @@
         }
     }
 
-    private ImplementationType mImplementationType = ImplementationType.BASIC_EXTENDER;
-
     /**
      * Set the implementation type.
+     *
+     * <p>When OEM implementation exists on the device, the only possible type is
+     * {@link ImplementationType#OEM_IMPL}. Setting the implementation type to
+     * {@link ImplementationType#TESTLIB_BASIC} or {@link ImplementationType#TESTLIB_ADVANCED}
+     *  when OEM implementation exist will throw an {@link IllegalArgumentException}.
+     *
+     * <p>When OEM implementation doesn't exist on the device, it is allowed to set it to
+     * {@link ImplementationType#TESTLIB_BASIC} or {@link ImplementationType#TESTLIB_ADVANCED}.
+     * Setting it to {@link ImplementationType#OEM_IMPL} in this case will throw an
+     * {@link IllegalArgumentException}.
      */
     public void setImplementationType(@NonNull ImplementationType type) {
+        if (mImplementationType != ImplementationType.OEM_IMPL) { // OEM impl doesn't exist
+            if (type == ImplementationType.OEM_IMPL) {
+                throw new IllegalArgumentException("OEM_IMPL is not supported on this device.");
+            }
+        } else { // OEM impl exists
+            if (type != ImplementationType.OEM_IMPL) {
+                throw new IllegalArgumentException("Can't change the implementation type because "
+                        + "OEM implementation exists on the device");
+            }
+        }
+
         mImplementationType = type;
     }
 
+    private boolean doesOEMImplementationExist() {
+        try {
+            new ExtensionVersionImpl().checkTestlibRunning();
+            return false;
+        } catch (NoSuchMethodError e) { // checkTestlibRunning doesn't exist in OEM implementation.
+            return true;
+        }
+    }
+
     /**
      * Gets the implementation type;
      */
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
index ac5fdce..0c0cf09 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
@@ -19,7 +19,6 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
-import android.graphics.ImageFormat;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
@@ -40,7 +39,7 @@
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
@@ -385,8 +384,7 @@
     @Nullable
     @Override
     public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(@NonNull Size captureSize) {
-        Pair<Integer, Size[]> pair = new Pair<>(ImageFormat.JPEG, new Size[] {captureSize});
-        return Arrays.asList(pair);
+        return Collections.emptyList();
     }
 
     @Override
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
index 093d409..0de93ff 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
@@ -179,11 +179,11 @@
     @NonNull
     @Override
     public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() {
-        List<CaptureRequest.Key> keys = Arrays.asList(
+        List<CaptureRequest.Key> keys = new ArrayList<>(Arrays.asList(
                 CaptureRequest.CONTROL_AF_MODE,
                 CaptureRequest.CONTROL_AF_TRIGGER,
                 CaptureRequest.CONTROL_AF_REGIONS,
-                CaptureRequest.CONTROL_AE_REGIONS);
+                CaptureRequest.CONTROL_AE_REGIONS));
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
             keys.add(CaptureRequest.CONTROL_ZOOM_RATIO);
         } else {
@@ -195,12 +195,12 @@
     @NonNull
     @Override
     public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
-        List<CaptureResult.Key> keys = Arrays.asList(
+        List<CaptureResult.Key> keys = new ArrayList<>(Arrays.asList(
                 CaptureResult.CONTROL_AF_MODE,
                 CaptureResult.CONTROL_AE_REGIONS,
                 CaptureResult.CONTROL_AF_REGIONS,
                 CaptureResult.CONTROL_AE_STATE,
-                CaptureResult.CONTROL_AF_STATE);
+                CaptureResult.CONTROL_AF_STATE));
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
             keys.add(CaptureResult.CONTROL_ZOOM_RATIO);
         } else {
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
index 9f567ba..520ea90 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
@@ -42,13 +42,12 @@
     @Override
     public boolean isExtensionAvailable(@NonNull String cameraId,
             @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
+        return false;
     }
 
     @Override
     public void init(@NonNull String cameraId,
             @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
     }
 
     @Override
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java
index 40bbb93..d99e44c 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java
@@ -42,13 +42,12 @@
     @Override
     public boolean isExtensionAvailable(@NonNull String cameraId,
             @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
+        return false;
     }
 
     @Override
     public void init(@NonNull String cameraId,
             @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
     }
 
     @Override
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java
index 4093211..743b8d9 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java
@@ -42,13 +42,12 @@
     @Override
     public boolean isExtensionAvailable(@NonNull String cameraId,
             @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
+        return false;
     }
 
     @Override
     public void init(@NonNull String cameraId,
             @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
     }
 
     @Override
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/DefaultRequestProcessorImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/DefaultRequestProcessorImpl.java
new file mode 100644
index 0000000..c6c58a3
--- /dev/null
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/DefaultRequestProcessorImpl.java
@@ -0,0 +1,65 @@
+/*
+ * 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.camera.extensions.impl.advanced;
+
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+
+import androidx.annotation.NonNull;
+
+public class DefaultRequestProcessorImpl implements RequestProcessorImpl.Callback {
+    @Override
+    public void onCaptureStarted(@NonNull RequestProcessorImpl.Request request, long frameNumber,
+            long timestamp) {
+
+    }
+
+    @Override
+    public void onCaptureProgressed(@NonNull RequestProcessorImpl.Request request,
+            @NonNull CaptureResult partialResult) {
+
+    }
+
+    @Override
+    public void onCaptureCompleted(@NonNull RequestProcessorImpl.Request request,
+            @NonNull TotalCaptureResult totalCaptureResult) {
+
+    }
+
+    @Override
+    public void onCaptureFailed(@NonNull RequestProcessorImpl.Request request,
+            @NonNull CaptureFailure captureFailure) {
+
+    }
+
+    @Override
+    public void onCaptureBufferLost(@NonNull RequestProcessorImpl.Request request, long frameNumber,
+            int outputStreamId) {
+
+    }
+
+    @Override
+    public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) {
+
+    }
+
+    @Override
+    public void onCaptureSequenceAborted(int sequenceId) {
+
+    }
+}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
index 3d682ec..e4b038c 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
@@ -16,101 +16,19 @@
 
 package androidx.camera.extensions.impl.advanced;
 
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.util.Range;
-import android.util.Size;
+import android.graphics.ImageFormat;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.List;
-import java.util.Map;
+import androidx.annotation.RequiresApi;
 
 /**
- * Stub advanced extender implementation for hdr.
- *
- * <p>This class should be implemented by OEM and deployed to the target devices.
+ * A sample HDR implementation for testing long processing capture. It is capable of outputting
+ * the postview(JPEG format) and the process progress event. ImageAnalysis is not supported.
  *
  * @since 1.2
  */
-public class HdrAdvancedExtenderImpl implements AdvancedExtenderImpl {
+@RequiresApi(21)
+public class HdrAdvancedExtenderImpl extends LongCaptureAdvancedExtenderImpl {
     public HdrAdvancedExtenderImpl() {
-    }
-
-    @Override
-    public boolean isExtensionAvailable(@NonNull String cameraId,
-            @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    public void init(@NonNull String cameraId,
-            @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @Nullable
-    public Range<Long> getEstimatedCaptureLatencyRange(
-            @NonNull String cameraId, @Nullable Size size, int imageFormat) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public Map<Integer, List<Size>> getSupportedPreviewOutputResolutions(
-            @NonNull String cameraId) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-
-    @Override
-    @NonNull
-    public Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(
-            @NonNull String cameraId) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public Map<Integer, List<Size>> getSupportedPostviewResolutions(
-            @NonNull Size captureSize) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @Nullable
-    public List<Size> getSupportedYuvAnalysisResolutions(@NonNull String cameraId) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public SessionProcessorImpl createSessionProcessor() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    public boolean isCaptureProcessProgressAvailable() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    public boolean isPostviewAvailable() {
-        throw new RuntimeException("Stub, replace with implementation.");
+        super(/* postviewFormat */ ImageFormat.JPEG);
     }
 }
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/LongCaptureAdvancedExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/LongCaptureAdvancedExtenderImpl.java
new file mode 100644
index 0000000..d28067c
--- /dev/null
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/LongCaptureAdvancedExtenderImpl.java
@@ -0,0 +1,593 @@
+/*
+ * 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.camera.extensions.impl.advanced;
+
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Pair;
+import android.util.Range;
+import android.util.Size;
+import android.view.Surface;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.ImageProcessingUtil;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * An {@link AdvancedExtenderImpl} implementation that have long processing time for capture and
+ * is capable of outputting the postview and the process progress event.
+ */
+@RequiresApi(21)
+public class LongCaptureAdvancedExtenderImpl implements AdvancedExtenderImpl {
+    private static final int EV_INDEX = 10;
+
+    private CameraCharacteristics mCameraCharacteristics;
+    private final int mPostviewFormat;
+
+    public LongCaptureAdvancedExtenderImpl(int postviewFormat) {
+        mPostviewFormat = postviewFormat;
+    }
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
+        return true;
+    }
+
+    @Override
+    public void init(@NonNull String cameraId,
+            @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
+        mCameraCharacteristics = characteristicsMap.get(cameraId);
+    }
+
+    @Override
+    @Nullable
+    public Range<Long> getEstimatedCaptureLatencyRange(
+            @NonNull String cameraId, @Nullable Size size, int imageFormat) {
+        return new Range<>(1000L, 4000L);
+    }
+
+    @Override
+    @NonNull
+    public Map<Integer, List<Size>> getSupportedPreviewOutputResolutions(
+            @NonNull String cameraId) {
+        HashMap<Integer, List<Size>> map = new HashMap<>();
+        map.put(ImageFormat.PRIVATE, getOutputSizes(ImageFormat.PRIVATE));
+        return map;
+    }
+
+    private List<Size> getOutputSizes(int imageFormat) {
+        StreamConfigurationMap map = mCameraCharacteristics
+                .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+        return Arrays.asList(map.getOutputSizes(imageFormat));
+    }
+
+    @Override
+    @NonNull
+    public Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(
+            @NonNull String cameraId) {
+        HashMap<Integer, List<Size>> map = new HashMap<>();
+        map.put(ImageFormat.JPEG, getOutputSizes(ImageFormat.JPEG));
+        return map;
+    }
+
+    @Override
+    @NonNull
+    public Map<Integer, List<Size>> getSupportedPostviewResolutions(
+            @NonNull Size captureSize) {
+        HashMap<Integer, List<Size>> map = new HashMap<>();
+        // Here it intentionally contains JPEG or YUV instead of both so that we can test
+        // the different path.
+        if (mPostviewFormat == ImageFormat.YUV_420_888) {
+            map.put(ImageFormat.YUV_420_888, getCompatibleYuvSizes(captureSize));
+        } else if (mPostviewFormat == ImageFormat.JPEG) {
+            // it will configure YUV stream and convert it to JPEG.
+            map.put(ImageFormat.JPEG, getCompatibleYuvSizes(captureSize));
+        }
+        return map;
+    }
+
+    private List<Size> getCompatibleYuvSizes(Size captureSize) {
+        List<Size> yuvSizes = getOutputSizes(ImageFormat.YUV_420_888);
+        List<Size> results = new ArrayList<>();
+
+        for (Size yuvSize : yuvSizes) {
+            int area = yuvSize.getWidth() * yuvSize.getHeight();
+            if (area <= captureSize.getWidth() * captureSize.getHeight()
+                    && area <= 1920 * 1080 /* 1080P */) {
+                results.add(yuvSize);
+            }
+        }
+        return results;
+    }
+
+    @Override
+    @Nullable
+    public List<Size> getSupportedYuvAnalysisResolutions(
+            @NonNull String cameraId) {
+        return Collections.emptyList();
+    }
+
+    private LongCaptureSessionProcessor mNightSessionProcessor = new LongCaptureSessionProcessor();
+    @Override
+    @NonNull
+    public SessionProcessorImpl createSessionProcessor() {
+        return mNightSessionProcessor;
+    }
+
+    @Override
+    @NonNull
+    public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() {
+        List<CaptureRequest.Key> keys = new ArrayList<>(Arrays.asList(
+                CaptureRequest.CONTROL_AF_MODE,
+                CaptureRequest.CONTROL_AF_TRIGGER,
+                CaptureRequest.CONTROL_AF_REGIONS,
+                CaptureRequest.CONTROL_AE_REGIONS)
+        );
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            keys.add(CaptureRequest.CONTROL_ZOOM_RATIO);
+        } else {
+            keys.add(CaptureRequest.SCALER_CROP_REGION);
+        }
+        return Collections.unmodifiableList(keys);
+    }
+
+    @Override
+    @NonNull
+    public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
+        List<CaptureResult.Key> keys = new ArrayList<>(Arrays.asList(
+                CaptureResult.CONTROL_AF_MODE,
+                CaptureResult.CONTROL_AE_REGIONS,
+                CaptureResult.CONTROL_AF_REGIONS,
+                CaptureResult.CONTROL_AE_STATE,
+                CaptureResult.CONTROL_AF_STATE));
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            keys.add(CaptureResult.CONTROL_ZOOM_RATIO);
+        } else {
+            keys.add(CaptureResult.SCALER_CROP_REGION);
+        }
+        return Collections.unmodifiableList(keys);
+    }
+
+    @Override
+    public boolean isCaptureProcessProgressAvailable() {
+        return true;
+    }
+
+    @Override
+    public boolean isPostviewAvailable() {
+        return true;
+    }
+
+    private class LongCaptureSessionProcessor implements SessionProcessorImpl {
+        private HandlerThread mHandlerThread;
+        private Handler mBackgroundHandler;
+
+        private final Object mLock = new Object();
+        @GuardedBy("mLock")
+        private Map<CaptureRequest.Key<?>, Object> mParameters = new LinkedHashMap<>();
+
+        private Camera2OutputConfigImpl mPreviewOutputConfig;
+        private Camera2OutputConfigImpl mCaptureOutputConfig;
+        private Camera2OutputConfigImpl mPostviewOutputConfig;
+
+        private Surface mPostviewJpegOutputSurface;
+
+        private RequestProcessorImpl mRequestProcessor;
+        private AtomicInteger mNextCaptureSequenceId = new AtomicInteger(1);
+
+        @NonNull
+        @Override
+        public Camera2SessionConfigImpl initSession(@NonNull String cameraId,
+                @NonNull Map<String, CameraCharacteristics> cameraCharacteristicsMap,
+                @NonNull Context context, @NonNull OutputSurfaceConfigurationImpl surfaceConfigs) {
+            return initSessionInternal(
+                    surfaceConfigs.getPreviewOutputSurface(),
+                    surfaceConfigs.getImageCaptureOutputSurface(),
+                    surfaceConfigs.getPostviewOutputSurface());
+        }
+
+        @NonNull
+        @Override
+        public Camera2SessionConfigImpl initSession(@NonNull String cameraId,
+                @NonNull Map<String, CameraCharacteristics> cameraCharacteristicsMap,
+                @NonNull Context context, @NonNull OutputSurfaceImpl previewSurfaceConfig,
+                @NonNull OutputSurfaceImpl imageCaptureSurfaceConfig,
+                @Nullable OutputSurfaceImpl imageAnalysisSurfaceConfig) {
+            return initSessionInternal(previewSurfaceConfig,
+                    imageCaptureSurfaceConfig,
+                    null);
+        }
+
+        private Camera2SessionConfigImpl initSessionInternal(
+                @NonNull OutputSurfaceImpl previewSurfaceConfig,
+                @NonNull OutputSurfaceImpl imageCaptureSurfaceConfig,
+                @Nullable OutputSurfaceImpl postviewSurfaceConfig) {
+
+            mHandlerThread = new HandlerThread("LongCapture advanced extender impl");
+            mHandlerThread.start();
+            mBackgroundHandler = new Handler(mHandlerThread.getLooper());
+            Camera2SessionConfigImplBuilder builder =
+                    new Camera2SessionConfigImplBuilder()
+                            .setSessionTemplateId(CameraDevice.TEMPLATE_PREVIEW);
+
+            // Preview
+            if (previewSurfaceConfig.getSurface() != null) {
+                mPreviewOutputConfig = Camera2OutputConfigImplBuilder
+                        .newSurfaceConfig(previewSurfaceConfig.getSurface()).build();
+
+                builder.addOutputConfig(mPreviewOutputConfig);
+            }
+
+            // Image Capture
+            if (imageCaptureSurfaceConfig.getSurface() != null) {
+                mCaptureOutputConfig = Camera2OutputConfigImplBuilder.newSurfaceConfig(
+                        imageCaptureSurfaceConfig.getSurface()).build();
+                builder.addOutputConfig(mCaptureOutputConfig);
+            }
+
+            // postview
+            if (postviewSurfaceConfig != null) {
+                if (postviewSurfaceConfig.getImageFormat() == ImageFormat.YUV_420_888) {
+                    // For YUV format postview, it just configures the YUV surface into the camera.
+                    mPostviewOutputConfig = Camera2OutputConfigImplBuilder.newSurfaceConfig(
+                            postviewSurfaceConfig.getSurface()).build();
+                } else if (postviewSurfaceConfig.getImageFormat() == ImageFormat.JPEG) {
+                    // For JPEG format postview, because we can't configure two JPEG streams on
+                    // most devices, alternatively, we configure a YUV stream and convert it to
+                    // JPEG to the postview output surface.
+                    mPostviewOutputConfig = Camera2OutputConfigImplBuilder.newImageReaderConfig(
+                            postviewSurfaceConfig.getSize(), ImageFormat.YUV_420_888, 2
+                    ).build();
+                    mPostviewJpegOutputSurface = postviewSurfaceConfig.getSurface();
+                }
+
+                builder.addOutputConfig(mPostviewOutputConfig);
+            }
+
+            return builder.build();
+        }
+
+        @Override
+        public void deInitSession() {
+            mHandlerThread.quitSafely();
+        }
+
+        @Override
+        public void setParameters(@NonNull Map<CaptureRequest.Key<?>, Object> parameters) {
+            synchronized (mLock) {
+                for (CaptureRequest.Key<?> key : parameters.keySet()) {
+                    Object value = parameters.get(key);
+                    if (value != null) {
+                        mParameters.put(key, value);
+                    }
+                }
+            }
+        }
+
+        private void applyParameters(@NonNull RequestBuilder requestBuilder) {
+            synchronized (mLock) {
+                for (CaptureRequest.Key<?> key : mParameters.keySet()) {
+                    requestBuilder.setParameters(key, mParameters.get(key));
+                }
+            }
+        }
+
+        @Override
+        public int startTrigger(@NonNull Map<CaptureRequest.Key<?>, Object> triggers,
+                @NonNull CaptureCallback captureCallback) {
+            RequestBuilder builder = new RequestBuilder(mPreviewOutputConfig.getId(),
+                    CameraDevice.TEMPLATE_PREVIEW);
+            applyParameters(builder);
+            builder.setParameters(
+                    CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, EV_INDEX);
+
+            List<CaptureRequest.Key> availableKeys = getAvailableCaptureRequestKeys();
+            for (CaptureRequest.Key<?> key : triggers.keySet()) {
+                if (availableKeys.contains(key)) {
+                    builder.setParameters(key, triggers.get(key));
+                }
+            }
+
+            int seqId = mNextCaptureSequenceId.getAndIncrement();
+
+            RequestProcessorImpl.Callback callback = new RequestProcessorImpl.Callback() {
+                @Override
+                public void onCaptureStarted(@NonNull RequestProcessorImpl.Request request,
+                        long frameNumber,
+                        long timestamp) {
+                    captureCallback.onCaptureStarted(seqId, timestamp);
+                }
+
+                @Override
+                public void onCaptureProgressed(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull CaptureResult partialResult) {
+
+                }
+
+                @Override
+                public void onCaptureCompleted(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull TotalCaptureResult totalCaptureResult) {
+                    captureCallback.onCaptureProcessStarted(seqId);
+                }
+
+                @Override
+                public void onCaptureFailed(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull CaptureFailure captureFailure) {
+                    captureCallback.onCaptureFailed(seqId);
+                }
+
+                @Override
+                public void onCaptureBufferLost(@NonNull RequestProcessorImpl.Request request,
+                        long frameNumber, int outputStreamId) {
+                    captureCallback.onCaptureFailed(seqId);
+                }
+
+                @Override
+                public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) {
+                    captureCallback.onCaptureSequenceCompleted(seqId);
+                }
+
+                @Override
+                public void onCaptureSequenceAborted(int sequenceId) {
+                    captureCallback.onCaptureSequenceAborted(seqId);
+                }
+            };
+
+            mRequestProcessor.submit(builder.build(), callback);
+            return seqId;
+        }
+
+        private int getJpegOrientation() {
+            synchronized (mLock) {
+                if (mParameters.get(CaptureRequest.JPEG_ORIENTATION) != null) {
+                    return (int) mParameters.get(CaptureRequest.JPEG_ORIENTATION);
+                }
+            }
+            return 0;
+        }
+
+        @RequiresApi(21)
+        @Override
+        public void onCaptureSessionStart(@NonNull RequestProcessorImpl requestProcessor) {
+            mRequestProcessor = requestProcessor;
+
+            if (mPostviewFormat == ImageFormat.JPEG && mPostviewJpegOutputSurface != null) {
+                requestProcessor.setImageProcessor(mPostviewOutputConfig.getId(),
+                        new ImageProcessorImpl() {
+                            @Override
+                            public void onNextImageAvailable(int outputConfigId, long timestampNs,
+                                    ImageReferenceImpl imageReference, String physicalCameraId) {
+                                ImageProcessingUtil.convertYuvToJpegBytesIntoSurface(
+                                        imageReference.get(),
+                                        90,
+                                        getJpegOrientation(),
+                                        mPostviewJpegOutputSurface
+                                );
+
+                                imageReference.decrement();
+                            }
+                        }
+                );
+            }
+        }
+
+        @Override
+        public void onCaptureSessionEnd() {
+
+        }
+
+        @Override
+        public int startRepeating(@NonNull CaptureCallback captureCallback) {
+            RequestBuilder builder = new RequestBuilder(mPreviewOutputConfig.getId(),
+                    CameraDevice.TEMPLATE_PREVIEW);
+            applyParameters(builder);
+            builder.setParameters(
+                    CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, EV_INDEX);
+            final int seqId = mNextCaptureSequenceId.getAndIncrement();
+
+            RequestProcessorImpl.Callback callback = new RequestProcessorImpl.Callback() {
+                @Override
+                public void onCaptureStarted(@NonNull RequestProcessorImpl.Request request,
+                        long frameNumber,
+                        long timestamp) {
+                    captureCallback.onCaptureStarted(seqId, timestamp);
+                }
+
+                @Override
+                public void onCaptureProgressed(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull CaptureResult partialResult) {
+
+                }
+
+                @Override
+                public void onCaptureCompleted(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull TotalCaptureResult totalCaptureResult) {
+                    captureCallback.onCaptureProcessStarted(seqId);
+                }
+
+                @Override
+                public void onCaptureFailed(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull CaptureFailure captureFailure) {
+                    captureCallback.onCaptureFailed(seqId);
+                }
+
+                @Override
+                public void onCaptureBufferLost(@NonNull RequestProcessorImpl.Request request,
+                        long frameNumber, int outputStreamId) {
+                    captureCallback.onCaptureFailed(seqId);
+                }
+
+                @Override
+                public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) {
+                    captureCallback.onCaptureSequenceCompleted(seqId);
+                }
+
+                @Override
+                public void onCaptureSequenceAborted(int sequenceId) {
+                    captureCallback.onCaptureSequenceAborted(seqId);
+                }
+            };
+
+            mRequestProcessor.setRepeating(builder.build(), callback);
+
+            return seqId;
+        }
+
+        @Override
+        public void stopRepeating() {
+            mRequestProcessor.stopRepeating();
+        }
+
+        @Override
+        public int startCapture(@NonNull CaptureCallback callback) {
+            return startCaptureInternal(false, callback);
+        }
+
+        @Override
+        public int startCaptureWithPostview(@NonNull CaptureCallback callback) {
+            return startCaptureInternal(true, callback);
+        }
+
+        private int startCaptureInternal(boolean enablePostivew,
+                @NonNull CaptureCallback captureCallback) {
+
+            // Send postview request
+            if (enablePostivew) {
+                RequestBuilder builderPostview = new RequestBuilder(mPostviewOutputConfig.getId(),
+                        CameraDevice.TEMPLATE_PREVIEW);
+                applyParameters(builderPostview);
+                RequestProcessorImpl.Request postviewRequest = builderPostview.build();
+
+                mRequestProcessor.submit(postviewRequest, new DefaultRequestProcessorImpl());
+            }
+
+            captureCallback.onCaptureProcessProgressed(10);
+
+            // send still capture request
+            final int seqId = mNextCaptureSequenceId.getAndIncrement();
+            updateProcessProgressDelayed(captureCallback, 40, 1000);
+            updateProcessProgressDelayed(captureCallback, 70, 2000);
+            updateProcessProgressDelayed(captureCallback, 100, 3000);
+
+            mBackgroundHandler.postDelayed(() -> {
+                submitStillCapture(seqId, captureCallback);
+            }, 3000);
+            return seqId;
+        }
+
+        private void updateProcessProgressDelayed(CaptureCallback callback,
+                int progress, long delayInMs) {
+            mBackgroundHandler.postDelayed(() -> {
+                callback.onCaptureProcessProgressed(progress);
+            }, delayInMs);
+        }
+
+        private int submitStillCapture(int seqId, @NonNull CaptureCallback captureCallback) {
+            if (mRequestProcessor == null) {
+                return -1;
+            }
+            RequestBuilder builderStillCapture = new RequestBuilder(mCaptureOutputConfig.getId(),
+                    CameraDevice.TEMPLATE_STILL_CAPTURE);
+            applyParameters(builderStillCapture);
+            RequestProcessorImpl.Request stillcaptureRequest = builderStillCapture.build();
+
+            RequestProcessorImpl.Callback callback = new RequestProcessorImpl.Callback() {
+                private boolean mOnCaptureStartedInvokded = false;
+
+                @Override
+                public void onCaptureStarted(@NonNull RequestProcessorImpl.Request request,
+                        long frameNumber, long timestamp) {
+                    if (!mOnCaptureStartedInvokded) {
+                        mOnCaptureStartedInvokded = true;
+                        captureCallback.onCaptureStarted(seqId, timestamp);
+                    }
+                }
+
+                @Override
+                public void onCaptureProgressed(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull CaptureResult partialResult) {
+
+                }
+
+                @Override
+                public void onCaptureCompleted(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull TotalCaptureResult totalCaptureResult) {
+                }
+
+                @Override
+                public void onCaptureFailed(@NonNull RequestProcessorImpl.Request request,
+                        @NonNull CaptureFailure captureFailure) {
+                    captureCallback.onCaptureFailed(seqId);
+                }
+
+                @Override
+                public void onCaptureBufferLost(@NonNull RequestProcessorImpl.Request request,
+                        long frameNumber, int outputStreamId) {
+                    captureCallback.onCaptureFailed(seqId);
+                }
+
+                @Override
+                public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) {
+                    captureCallback.onCaptureSequenceCompleted(seqId);
+                }
+
+                @Override
+                public void onCaptureSequenceAborted(int sequenceId) {
+                    captureCallback.onCaptureSequenceAborted(seqId);
+                }
+            };
+
+            mRequestProcessor.submit(stillcaptureRequest, callback);
+
+            return seqId;
+        }
+        @Override
+        public void abortCapture(int captureSequenceId) {
+
+        }
+
+        @Nullable
+        @Override
+        public Pair<Long, Long> getRealtimeCaptureLatency() {
+            return null;
+        }
+    }
+}
+
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
index 5c32de8..415a8c5 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
@@ -16,101 +16,19 @@
 
 package androidx.camera.extensions.impl.advanced;
 
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.util.Range;
-import android.util.Size;
+import android.graphics.ImageFormat;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.List;
-import java.util.Map;
+import androidx.annotation.RequiresApi;
 
 /**
- * Stub advanced extender implementation for night.
- *
- * <p>This class should be implemented by OEM and deployed to the target devices.
+ * A sample night implementation for testing long processing capture. It is capable of outputting
+ * the postview(YUV format) and the process progress event. ImageAnalysis is not supported.
  *
  * @since 1.2
  */
-public class NightAdvancedExtenderImpl implements AdvancedExtenderImpl {
+@RequiresApi(21)
+public class NightAdvancedExtenderImpl extends LongCaptureAdvancedExtenderImpl {
     public NightAdvancedExtenderImpl() {
-    }
-
-    @Override
-    public boolean isExtensionAvailable(@NonNull String cameraId,
-            @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    public void init(@NonNull String cameraId,
-            @NonNull Map<String, CameraCharacteristics> characteristicsMap) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @Nullable
-    public Range<Long> getEstimatedCaptureLatencyRange(
-            @NonNull String cameraId, @Nullable Size size, int imageFormat) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public Map<Integer, List<Size>> getSupportedPreviewOutputResolutions(
-            @NonNull String cameraId) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(
-            @NonNull String cameraId) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public Map<Integer, List<Size>> getSupportedPostviewResolutions(
-            @NonNull Size captureSize) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @Nullable
-    public List<Size> getSupportedYuvAnalysisResolutions(
-            @NonNull String cameraId) {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public SessionProcessorImpl createSessionProcessor() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    @NonNull
-    public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    public boolean isCaptureProcessProgressAvailable() {
-        throw new RuntimeException("Stub, replace with implementation.");
-    }
-
-    @Override
-    public boolean isPostviewAvailable() {
-        throw new RuntimeException("Stub, replace with implementation.");
+        super(/* postviewFormat */ ImageFormat.YUV_420_888);
     }
 }
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/RequestBuilder.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/RequestBuilder.java
new file mode 100644
index 0000000..b83328b
--- /dev/null
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/RequestBuilder.java
@@ -0,0 +1,120 @@
+/*
+ * 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.camera.extensions.impl.advanced;
+
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A builder to build the {@link RequestProcessorImpl.Request} instance.
+ */
+public class RequestBuilder {
+    List<Integer> mTargetOutputConfigIds = new ArrayList<>();
+    Map<CaptureRequest.Key<?>, Object> mParameters = new HashMap<>();
+    int mTemplateId = CameraDevice.TEMPLATE_PREVIEW;
+
+    /**
+     * Construct the builder with default settings.
+     */
+    public RequestBuilder() {
+    }
+
+    /**
+     * Construct the builder.
+     */
+    public RequestBuilder(int targetOutputConfigId, int templateId) {
+        addTargetOutputConfigIds(targetOutputConfigId);
+        setTemplateId(templateId);
+    }
+
+
+    /**
+     * Adds the target outputconfig ids.
+     */
+    @NonNull
+    public RequestBuilder addTargetOutputConfigIds(int targetOutputConfigId) {
+        mTargetOutputConfigIds.add(targetOutputConfigId);
+        return this;
+    }
+
+    /**
+     * Sets the parameters
+     */
+    @NonNull
+    public RequestBuilder setParameters(@NonNull CaptureRequest.Key<?> key,
+            @NonNull Object value) {
+        mParameters.put(key, value);
+        return this;
+    }
+
+    /**
+     * Sets the template id.
+     */
+    @NonNull
+    public RequestBuilder setTemplateId(int templateId) {
+        mTemplateId = templateId;
+        return this;
+    }
+
+    /**
+     * construct {@link RequestProcessorImpl.Request} instance.
+     */
+    @NonNull
+    public RequestProcessorImpl.Request build() {
+        return new RequestProcessorRequest(
+                mTargetOutputConfigIds, mParameters, mTemplateId);
+    }
+
+    static class RequestProcessorRequest implements RequestProcessorImpl.Request {
+        final List<Integer> mTargetOutputConfigIds;
+        final Map<CaptureRequest.Key<?>, Object> mParameters;
+        final int mTemplateId;
+
+        RequestProcessorRequest(List<Integer> targetOutputConfigIds,
+                Map<CaptureRequest.Key<?>, Object> parameters,
+                int templateId) {
+            mTargetOutputConfigIds = targetOutputConfigIds;
+            mParameters = parameters;
+            mTemplateId = templateId;
+        }
+
+        @Override
+        @NonNull
+        public List<Integer> getTargetOutputConfigIds() {
+            return mTargetOutputConfigIds;
+        }
+
+        @Override
+        @NonNull
+        public Map<CaptureRequest.Key<?>, Object> getParameters() {
+            return mParameters;
+        }
+
+        @Override
+        @NonNull
+        public Integer getTemplateId() {
+            return mTemplateId;
+        }
+    }
+}
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioVideoSyncTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioVideoSyncTest.kt
index 48b91fd..257ecd5 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioVideoSyncTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/AudioVideoSyncTest.kt
@@ -198,6 +198,8 @@
         assertThat(timeDiff).isLessThan(diffThresholdUs)
 
         recording.stopSafely()
+        inOrder.verify(videoRecordEventListener, Mockito.timeout(5000L))
+            .accept(ArgumentMatchers.any(VideoRecordEvent.Finalize::class.java))
         file.delete()
     }
 
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
index 0ccbd4e..c132254 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
@@ -276,6 +276,13 @@
     fun tearDown() {
         for (recording in recordingsToStop) {
             recording.stop()
+            try {
+                // Wait for recording done to avoid overlapping to next recording test.
+                // Overlapping recording tests may lead to uncertainty and flaky-ness.
+                recording.listener.verifyFinalize(inOrder = false)
+            } catch (e: AssertionError) {
+                // Ignored.
+            }
         }
 
         if (this::cameraUseCaseAdapter.isInitialized) {
@@ -739,6 +746,8 @@
 
     @Test
     fun stop_WhenUseCaseDetached() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         // Arrange.
         val recording = createRecordingProcess()
 
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
index a00c5d8..8b56757 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
@@ -61,6 +61,8 @@
 import androidx.camera.testing.impl.mocks.helpers.CallTimesAtLeast
 import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_NONE
 import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_SOURCE_INACTIVE
+import androidx.camera.video.internal.compat.quirk.DeviceQuirks
+import androidx.camera.video.internal.compat.quirk.StopCodecAfterSurfaceRemovalCrashMediaServerQuirk
 import androidx.core.util.Consumer
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.LargeTest
@@ -426,6 +428,8 @@
 
     @Test
     fun stopRecording_when_useCaseUnbind() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         // Arrange.
         val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
         latchForVideoSaved = CountDownLatch(1)
@@ -454,6 +458,8 @@
 
     @Test
     fun stopRecordingWhenLifecycleStops() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         // Arrange.
         val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
         latchForVideoSaved = CountDownLatch(1)
@@ -482,6 +488,8 @@
 
     @Test
     fun start_finalizeImmediatelyWhenSourceInactive() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         val file = File.createTempFile("CameraX", ".tmp").apply { deleteOnExit() }
 
         instrumentation.runOnMainSync {
@@ -701,6 +709,12 @@
                 )
             }
 
+        mockVideoRecordEventConsumer.verifyAcceptCall(
+            VideoRecordEvent.Finalize::class.java,
+            true,
+            GENERAL_TIMEOUT
+        )
+
         file1.delete()
         file2.delete()
     }
@@ -812,6 +826,8 @@
 
     @Test
     fun canReuseRecorder_sourceInactive() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         val recorder = Recorder.Builder().build()
         val videoCapture1 = VideoCapture.withOutput(recorder)
 
@@ -1355,6 +1371,7 @@
         )
 }
 
+@RequiresApi(21)
 private class VideoCaptureMonitor : Consumer<VideoRecordEvent> {
     private var countDown: CountDownLatch? = null
 
@@ -1409,3 +1426,13 @@
         assumeTrue(msg, Camera2DeviceQuirks.get(Camera2ExtraCroppingQuirk::class.java) == null)
     }
 }
+
+@RequiresApi(21)
+fun assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk() {
+    // Skip for b/293978082. For tests that will unbind the VideoCapture before stop the recording,
+    // they should be skipped since media server will crash if the codec surface has been removed
+    // before MediaCodec.stop() is called.
+    assumeTrue(
+        DeviceQuirks.get(StopCodecAfterSurfaceRemovalCrashMediaServerQuirk::class.java) == null
+    )
+}
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/RecorderVideoCapabilities.java b/camera/camera-video/src/main/java/androidx/camera/video/RecorderVideoCapabilities.java
index 561cf39..9d2eb01 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/RecorderVideoCapabilities.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/RecorderVideoCapabilities.java
@@ -16,11 +16,7 @@
 
 package androidx.camera.video;
 
-import static androidx.camera.core.DynamicRange.BIT_DEPTH_UNSPECIFIED;
-import static androidx.camera.core.DynamicRange.ENCODING_HDR_UNSPECIFIED;
 import static androidx.camera.core.DynamicRange.ENCODING_HLG;
-import static androidx.camera.core.DynamicRange.ENCODING_SDR;
-import static androidx.camera.core.DynamicRange.ENCODING_UNSPECIFIED;
 import static androidx.camera.core.DynamicRange.SDR;
 import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
 import static androidx.camera.video.Quality.getSortedQualities;
@@ -40,6 +36,7 @@
 import androidx.camera.core.CameraInfo;
 import androidx.camera.core.DynamicRange;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.core.impl.DynamicRanges;
 import androidx.camera.core.impl.EncoderProfilesProvider;
 import androidx.camera.core.impl.EncoderProfilesProxy;
 import androidx.camera.core.impl.EncoderProfilesProxy.VideoProfileProxy;
@@ -54,7 +51,6 @@
 import androidx.camera.video.internal.encoder.VideoEncoderInfo;
 import androidx.camera.video.internal.workaround.QualityResolutionModifiedEncoderProfilesProvider;
 import androidx.camera.video.internal.workaround.QualityValidatedEncoderProfilesProvider;
-import androidx.core.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -241,7 +237,7 @@
     @Nullable
     private CapabilitiesByQuality generateCapabilitiesForNonFullySpecifiedDynamicRange(
             @NonNull DynamicRange dynamicRange) {
-        if (!canResolve(dynamicRange, getSupportedDynamicRanges())) {
+        if (!DynamicRanges.canResolve(dynamicRange, getSupportedDynamicRanges())) {
             return null;
         }
 
@@ -251,56 +247,4 @@
                 new DynamicRangeMatchedEncoderProfilesProvider(mProfilesProvider, dynamicRange);
         return new CapabilitiesByQuality(constrainedProvider);
     }
-
-    /**
-     * Returns {@code true} if the test dynamic range can resolve to the fully specified dynamic
-     * range set.
-     *
-     * <p>A range can resolve if test fields are unspecified and appropriately match the fields
-     * of the fully specified dynamic range, or the test fields exactly match the fields of
-     * the fully specified dynamic range.
-     */
-    private static boolean canResolve(@NonNull DynamicRange dynamicRangeToTest,
-            @NonNull Set<DynamicRange> fullySpecifiedDynamicRanges) {
-        if (dynamicRangeToTest.isFullySpecified()) {
-            return fullySpecifiedDynamicRanges.contains(dynamicRangeToTest);
-        } else {
-            for (DynamicRange fullySpecifiedDynamicRange : fullySpecifiedDynamicRanges) {
-                if (canMatchBitDepth(dynamicRangeToTest, fullySpecifiedDynamicRange)
-                        && canMatchEncoding(dynamicRangeToTest, fullySpecifiedDynamicRange)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-    }
-
-    private static boolean canMatchBitDepth(@NonNull DynamicRange dynamicRangeToTest,
-            @NonNull DynamicRange fullySpecifiedDynamicRange) {
-        Preconditions.checkState(fullySpecifiedDynamicRange.isFullySpecified(), "Fully specified "
-                + "range is not actually fully specified.");
-        if (dynamicRangeToTest.getBitDepth() == BIT_DEPTH_UNSPECIFIED) {
-            return true;
-        }
-
-        return dynamicRangeToTest.getBitDepth() == fullySpecifiedDynamicRange.getBitDepth();
-    }
-
-    private static boolean canMatchEncoding(@NonNull DynamicRange dynamicRangeToTest,
-            @NonNull DynamicRange fullySpecifiedDynamicRange) {
-        Preconditions.checkState(fullySpecifiedDynamicRange.isFullySpecified(), "Fully specified "
-                + "range is not actually fully specified.");
-        int encodingToTest = dynamicRangeToTest.getEncoding();
-        if (encodingToTest == ENCODING_UNSPECIFIED) {
-            return true;
-        }
-
-        int fullySpecifiedEncoding = fullySpecifiedDynamicRange.getEncoding();
-        if (encodingToTest == ENCODING_HDR_UNSPECIFIED && fullySpecifiedEncoding != ENCODING_SDR) {
-            return true;
-        }
-
-        return encodingToTest == fullySpecifiedEncoding;
-    }
 }
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProvider.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProvider.java
index 31d838b..84faba9 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProvider.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProvider.java
@@ -160,7 +160,8 @@
                 VideoEncoderConfig encoderConfig = toVideoEncoderConfig(baseVideoProfile);
                 VideoEncoderInfo encoderInfo = mVideoEncoderInfoFinder.apply(encoderConfig);
                 // Check if size is valid for the Encoder.
-                if (!encoderInfo.isSizeSupported(size.getWidth(), size.getHeight())) {
+                if (encoderInfo == null
+                        || !encoderInfo.isSizeSupported(size.getWidth(), size.getHeight())) {
                     continue;
                 }
                 // Add the encoderProfiles to the candidates of base EncoderProfiles.
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java
index c5bc087..0234352 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java
@@ -98,6 +98,9 @@
         if (CodecStuckOnFlushQuirk.load()) {
             quirks.add(new CodecStuckOnFlushQuirk());
         }
+        if (StopCodecAfterSurfaceRemovalCrashMediaServerQuirk.load()) {
+            quirks.add(new StopCodecAfterSurfaceRemovalCrashMediaServerQuirk());
+        }
 
         return quirks;
     }
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/StopCodecAfterSurfaceRemovalCrashMediaServerQuirk.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/StopCodecAfterSurfaceRemovalCrashMediaServerQuirk.java
new file mode 100644
index 0000000..fa1f22f
--- /dev/null
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/StopCodecAfterSurfaceRemovalCrashMediaServerQuirk.java
@@ -0,0 +1,44 @@
+/*
+ * 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.camera.video.internal.compat.quirk;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.impl.Quirk;
+
+/**
+ * <p>QuirkSummary
+ *     Bug Id: 293978082
+ *     Description: Quirk denotes that the media server die when codec surface has been removed
+ *                  from the camera repeating and then MediaCodec.stop() is called. Media server
+ *                  will recover soon but sometimes the camera server will get stuck and need to
+ *                  reboot the device to recover. We are not able to prevent camera from stopped
+ *                  by all paths but we should try to call MediaCodec.stop() as soon as possible.
+ *     Device(s): moto c
+ */
+@RequiresApi(21)
+public class StopCodecAfterSurfaceRemovalCrashMediaServerQuirk implements Quirk {
+
+    static boolean load() {
+        return isMotoC();
+    }
+
+    private static boolean isMotoC() {
+        return "motorola".equalsIgnoreCase(Build.BRAND) && "moto c".equalsIgnoreCase(Build.MODEL);
+    }
+}
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderImpl.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderImpl.java
index 92fc179..5eae605 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderImpl.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/encoder/EncoderImpl.java
@@ -56,6 +56,7 @@
 import androidx.camera.video.internal.compat.quirk.CodecStuckOnFlushQuirk;
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks;
 import androidx.camera.video.internal.compat.quirk.EncoderNotUsePersistentInputSurfaceQuirk;
+import androidx.camera.video.internal.compat.quirk.StopCodecAfterSurfaceRemovalCrashMediaServerQuirk;
 import androidx.camera.video.internal.compat.quirk.VideoEncoderSuspendDoesNotIncludeSuspendTimeQuirk;
 import androidx.camera.video.internal.workaround.EncoderFinder;
 import androidx.camera.video.internal.workaround.VideoTimebaseConverter;
@@ -850,7 +851,9 @@
                 if (!futures.isEmpty()) {
                     Logger.d(mTag, "encoded data and input buffers are returned");
                 }
-                if (mEncoderInput instanceof SurfaceInput && !mSourceStoppedSignalled) {
+                if (mEncoderInput instanceof SurfaceInput && !mSourceStoppedSignalled
+                        && !hasStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+                ) {
                     // For a SurfaceInput, the codec is in control of de-queuing buffers from the
                     // underlying BufferQueue. If we stop the codec, then it will stop de-queuing
                     // buffers and the BufferQueue may run out of input buffers, causing the camera
@@ -1028,6 +1031,10 @@
         return (bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
     }
 
+    private boolean hasStopCodecAfterSurfaceRemovalCrashMediaServerQuirk() {
+        return DeviceQuirks.get(StopCodecAfterSurfaceRemovalCrashMediaServerQuirk.class) != null;
+    }
+
     @SuppressWarnings("WeakerAccess") // synthetic accessor
     @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
     class MediaCodecCallback extends MediaCodec.Callback {
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProviderTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProviderTest.kt
index d607079..75cbe8d 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProviderTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/internal/QualityExploredEncoderProfilesProviderTest.kt
@@ -96,6 +96,23 @@
     }
 
     @Test
+    fun canNotExploreQualities_whenCannotFindEncoderInfo() {
+        // Arrange: SD is not a target quality.
+        val targetQualities = setOf(UHD, FHD, HD)
+
+        // Act: EncoderFinder always return null
+        val provider = QualityExploredEncoderProfilesProvider(
+            providerSupportOnlySdrFhd,
+            targetQualities,
+            setOf(SDR),
+            defaultCameraResolutions,
+        ) { null }
+
+        // Assert.
+        verifyQualitiesAreNotSupported(provider, SDR, QUALITY_2160P, QUALITY_720P)
+    }
+
+    @Test
     fun canNotExploreQualities_whenNoBaseProfile() {
         // Arrange: a provider doesn't have any supported qualities.
         val emptyProvider = FakeEncoderProfilesProvider.Builder().build()
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/VideoCaptureDeviceTest.kt b/camera/camera-view/src/androidTest/java/androidx/camera/view/VideoCaptureDeviceTest.kt
index 00c47c2..10f4461 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/VideoCaptureDeviceTest.kt
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/VideoCaptureDeviceTest.kt
@@ -27,6 +27,7 @@
 import android.provider.MediaStore
 import android.util.Log
 import androidx.annotation.MainThread
+import androidx.annotation.RequiresApi
 import androidx.camera.camera2.Camera2Config
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
 import androidx.camera.testing.impl.AndroidUtil.skipVideoRecordingTestIfNotSupportedByEmulator
@@ -48,6 +49,7 @@
 import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_SOURCE_INACTIVE
 import androidx.camera.video.internal.compat.quirk.DeviceQuirks
 import androidx.camera.video.internal.compat.quirk.MediaStoreVideoCannotWrite
+import androidx.camera.video.internal.compat.quirk.StopCodecAfterSurfaceRemovalCrashMediaServerQuirk
 import androidx.camera.view.CameraController.IMAGE_ANALYSIS
 import androidx.camera.view.CameraController.VIDEO_CAPTURE
 import androidx.camera.view.video.AudioConfig
@@ -65,6 +67,7 @@
 import java.util.concurrent.TimeUnit
 import org.junit.After
 import org.junit.Assume
+import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.BeforeClass
 import org.junit.Rule
@@ -217,7 +220,7 @@
 
     @Test
     fun canRecordToMediaStore() {
-        Assume.assumeTrue(
+        assumeTrue(
             "Ignore the test since the MediaStore.Video has compatibility issues.",
             DeviceQuirks.get(MediaStoreVideoCannotWrite::class.java) == null
         )
@@ -296,6 +299,8 @@
 
     @Test
     fun canRecordToFile_whenLifecycleStops() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         // Arrange.
         val file = createTempFile()
         val outputOptions = FileOutputOptions.Builder(file).build()
@@ -319,6 +324,8 @@
 
     @Test
     fun canRecordToFile_whenTargetQualityChanged() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         // Arrange.
         val file = createTempFile()
         val outputOptions = FileOutputOptions.Builder(file).build()
@@ -342,6 +349,8 @@
 
     @Test
     fun canRecordToFile_whenEnabledUseCasesChanged() {
+        assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk()
+
         // Arrange.
         val file = createTempFile()
         val outputOptions = FileOutputOptions.Builder(file).build()
@@ -682,3 +691,13 @@
         )
     }
 }
+
+@RequiresApi(21)
+fun assumeStopCodecAfterSurfaceRemovalCrashMediaServerQuirk() {
+    // Skip for b/293978082. For tests that will unbind the VideoCapture before stop the recording,
+    // they should be skipped since media server will crash if the codec surface has been removed
+    // before MediaCodec.stop() is called.
+    assumeTrue(
+        DeviceQuirks.get(StopCodecAfterSurfaceRemovalCrashMediaServerQuirk::class.java) == null
+    )
+}
diff --git a/camera/camera-viewfinder-core/api/current.txt b/camera/camera-viewfinder-core/api/current.txt
index e6f50d0..c56eefc 100644
--- a/camera/camera-viewfinder-core/api/current.txt
+++ b/camera/camera-viewfinder-core/api/current.txt
@@ -1 +1,68 @@
 // Signature format: 4.0
+package @RequiresApi(21) androidx.camera.viewfinder.surface {
+
+  public enum ImplementationMode {
+    method public static androidx.camera.viewfinder.surface.ImplementationMode valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.camera.viewfinder.surface.ImplementationMode[] values();
+    enum_constant public static final androidx.camera.viewfinder.surface.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.viewfinder.surface.ImplementationMode PERFORMANCE;
+    field public static final androidx.camera.viewfinder.surface.ImplementationMode.Companion Companion;
+  }
+
+  public static final class ImplementationMode.Companion {
+  }
+
+  public interface ViewfinderSurfaceProvider {
+    method public void onSurfaceRequested(androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest request);
+  }
+
+  public final class ViewfinderSurfaceRequest {
+    method public androidx.camera.viewfinder.surface.ImplementationMode? getImplementationMode();
+    method public int getLensFacing();
+    method public android.util.Size getResolution();
+    method public int getSensorOrientation();
+    method public void markSurfaceSafeToRelease();
+    method public void provideSurface(android.view.Surface surface, java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Result> resultListener);
+    method public boolean willNotProvideSurface();
+    property public final androidx.camera.viewfinder.surface.ImplementationMode? implementationMode;
+    property public final int lensFacing;
+    property public final android.util.Size resolution;
+    property public final int sensorOrientation;
+    field public static final androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Companion Companion;
+  }
+
+  public static final class ViewfinderSurfaceRequest.Builder {
+    ctor public ViewfinderSurfaceRequest.Builder(android.util.Size resolution);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest surfaceRequest);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder builder);
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest build();
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder setImplementationMode(androidx.camera.viewfinder.surface.ImplementationMode? implementationMode);
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder setLensFacing(int lensFacing);
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder setSensorOrientation(int sensorOrientation);
+  }
+
+  public static final class ViewfinderSurfaceRequest.Companion {
+  }
+
+  @com.google.auto.value.AutoValue public static final class ViewfinderSurfaceRequest.Result {
+    ctor public ViewfinderSurfaceRequest.Result(int code, android.view.Surface surface);
+    method public int component1();
+    method public android.view.Surface component2();
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Result copy(int code, android.view.Surface surface);
+    method public int getCode();
+    method public android.view.Surface getSurface();
+    property public final int code;
+    property public final android.view.Surface surface;
+    field public static final androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Result.Companion Companion;
+    field public static final int RESULT_INVALID_SURFACE = 2; // 0x2
+    field public static final int RESULT_REQUEST_CANCELLED = 1; // 0x1
+    field public static final int RESULT_SURFACE_ALREADY_PROVIDED = 3; // 0x3
+    field public static final int RESULT_SURFACE_USED_SUCCESSFULLY = 0; // 0x0
+    field public static final int RESULT_WILL_NOT_PROVIDE_SURFACE = 4; // 0x4
+  }
+
+  public static final class ViewfinderSurfaceRequest.Result.Companion {
+  }
+
+}
+
diff --git a/camera/camera-viewfinder-core/api/restricted_current.txt b/camera/camera-viewfinder-core/api/restricted_current.txt
index e6f50d0..c56eefc 100644
--- a/camera/camera-viewfinder-core/api/restricted_current.txt
+++ b/camera/camera-viewfinder-core/api/restricted_current.txt
@@ -1 +1,68 @@
 // Signature format: 4.0
+package @RequiresApi(21) androidx.camera.viewfinder.surface {
+
+  public enum ImplementationMode {
+    method public static androidx.camera.viewfinder.surface.ImplementationMode valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.camera.viewfinder.surface.ImplementationMode[] values();
+    enum_constant public static final androidx.camera.viewfinder.surface.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.viewfinder.surface.ImplementationMode PERFORMANCE;
+    field public static final androidx.camera.viewfinder.surface.ImplementationMode.Companion Companion;
+  }
+
+  public static final class ImplementationMode.Companion {
+  }
+
+  public interface ViewfinderSurfaceProvider {
+    method public void onSurfaceRequested(androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest request);
+  }
+
+  public final class ViewfinderSurfaceRequest {
+    method public androidx.camera.viewfinder.surface.ImplementationMode? getImplementationMode();
+    method public int getLensFacing();
+    method public android.util.Size getResolution();
+    method public int getSensorOrientation();
+    method public void markSurfaceSafeToRelease();
+    method public void provideSurface(android.view.Surface surface, java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Result> resultListener);
+    method public boolean willNotProvideSurface();
+    property public final androidx.camera.viewfinder.surface.ImplementationMode? implementationMode;
+    property public final int lensFacing;
+    property public final android.util.Size resolution;
+    property public final int sensorOrientation;
+    field public static final androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Companion Companion;
+  }
+
+  public static final class ViewfinderSurfaceRequest.Builder {
+    ctor public ViewfinderSurfaceRequest.Builder(android.util.Size resolution);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest surfaceRequest);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder builder);
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest build();
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder setImplementationMode(androidx.camera.viewfinder.surface.ImplementationMode? implementationMode);
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder setLensFacing(int lensFacing);
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Builder setSensorOrientation(int sensorOrientation);
+  }
+
+  public static final class ViewfinderSurfaceRequest.Companion {
+  }
+
+  @com.google.auto.value.AutoValue public static final class ViewfinderSurfaceRequest.Result {
+    ctor public ViewfinderSurfaceRequest.Result(int code, android.view.Surface surface);
+    method public int component1();
+    method public android.view.Surface component2();
+    method public androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Result copy(int code, android.view.Surface surface);
+    method public int getCode();
+    method public android.view.Surface getSurface();
+    property public final int code;
+    property public final android.view.Surface surface;
+    field public static final androidx.camera.viewfinder.surface.ViewfinderSurfaceRequest.Result.Companion Companion;
+    field public static final int RESULT_INVALID_SURFACE = 2; // 0x2
+    field public static final int RESULT_REQUEST_CANCELLED = 1; // 0x1
+    field public static final int RESULT_SURFACE_ALREADY_PROVIDED = 3; // 0x3
+    field public static final int RESULT_SURFACE_USED_SUCCESSFULLY = 0; // 0x0
+    field public static final int RESULT_WILL_NOT_PROVIDE_SURFACE = 4; // 0x4
+  }
+
+  public static final class ViewfinderSurfaceRequest.Result.Companion {
+  }
+
+}
+
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/impl/package-info.java b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/impl/package-info.java
new file mode 100644
index 0000000..7b9fae3
--- /dev/null
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/impl/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ */
+@RequiresApi(21)
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+package androidx.camera.viewfinder.impl;
+
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/impl/surface/DeferredSurface.kt b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/impl/surface/DeferredSurface.kt
new file mode 100644
index 0000000..6b27dd9
--- /dev/null
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/impl/surface/DeferredSurface.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.camera.viewfinder.impl.surface
+
+import android.view.Surface
+import androidx.annotation.GuardedBy
+import androidx.camera.impl.utils.Logger
+import androidx.camera.impl.utils.futures.Futures.nonCancellationPropagating
+import androidx.concurrent.futures.CallbackToFutureAdapter
+import com.google.common.util.concurrent.ListenableFuture
+
+/**
+ * A class for creating and tracking use of a [Surface] in an asynchronous manner.
+ */
+abstract class DeferredSurface : AutoCloseable {
+    private val lock = Any()
+    private val terminationFuture: ListenableFuture<Void?>
+
+    @GuardedBy("mLock")
+    private var closed = false
+
+    @GuardedBy("mLock")
+    private var terminationCompleterInternal: CallbackToFutureAdapter.Completer<Void?>? = null
+
+    init {
+        terminationFuture =
+            CallbackToFutureAdapter.getFuture {
+                synchronized(lock) {
+                    terminationCompleterInternal = it
+                }
+                "ViewfinderSurface-termination(" + this@DeferredSurface + ")"
+            }
+    }
+
+    fun getSurfaceAsync(): ListenableFuture<Surface> {
+        return provideSurfaceAsync()
+    }
+
+    fun getTerminationFutureAsync(): ListenableFuture<Void?> {
+        return nonCancellationPropagating(terminationFuture)
+    }
+
+    /**
+     * Close the surface.
+     *
+     *
+     *  After closing, the underlying surface resources can be safely released by
+     * [SurfaceView] or [TextureView] implementation.
+     */
+    override fun close() {
+        var terminationCompleter: CallbackToFutureAdapter.Completer<Void?>? = null
+        synchronized(lock) {
+            if (!closed) {
+                closed = true
+                terminationCompleter = terminationCompleterInternal
+                terminationCompleterInternal = null
+                Logger.d(
+                    TAG,
+                    "surface closed,  closed=true $this"
+                )
+            }
+        }
+        if (terminationCompleter != null) {
+            terminationCompleter!!.set(null)
+        }
+    }
+
+    protected abstract fun provideSurfaceAsync(): ListenableFuture<Surface>
+
+    /**
+     * The exception that is returned by the ListenableFuture of [getSurfaceAsync] if the
+     * deferrable surface is unable to produce a [Surface].
+     */
+    class SurfaceUnavailableException(message: String) : Exception(message)
+    companion object {
+        private const val TAG = "DeferredSurface"
+    }
+}
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ImplementationMode.kt b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ImplementationMode.kt
new file mode 100644
index 0000000..6afd5e6
--- /dev/null
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ImplementationMode.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.camera.viewfinder.surface
+
+import android.view.SurfaceView
+import android.view.TextureView
+import androidx.annotation.RestrictTo
+
+/**
+ * The implementation mode of a viewfinder.
+ *
+ *
+ *  User preference on how the viewfinder should render the viewfinder.
+ * The viewfinder is displayed with either a [SurfaceView] or a
+ * [TextureView]. A [SurfaceView] is generally better than a [TextureView]
+ * when it comes to certain key metrics, including power and latency. On the other hand,
+ * [TextureView] is better supported by a wider range of devices. The option is used to decide what
+ * is the best internal implementation given the device capabilities and user configurations.
+ */
+enum class ImplementationMode(private val id: Int) {
+    /**
+     * Use a [SurfaceView] for the viewfinder when possible. A SurfaceView has somewhat
+     * lower latency and less performance and power overhead than a TextureView. [SurfaceView]
+     * offers more control on a single drawing board, but does not support certain animations.
+     */
+    PERFORMANCE(0),
+
+    /**
+     * Use a [TextureView] for the viewfinder.
+     */
+    COMPATIBLE(1);
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun getId(): Int {
+        return id
+    }
+
+    companion object {
+        /**
+         * Convert an Int id to ImplementationMode
+         * @throws IllegalArgumentException if id doesn't below to any ImplementationMode
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @JvmStatic
+        fun fromId(id: Int): ImplementationMode {
+            for (implementationMode in ImplementationMode.values()) {
+                if (implementationMode.id == id) {
+                    return implementationMode
+                }
+            }
+            throw IllegalArgumentException("Unknown implementation mode id $id")
+        }
+    }
+}
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ViewfinderSurfaceProvider.kt b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ViewfinderSurfaceProvider.kt
new file mode 100644
index 0000000..c98d532
--- /dev/null
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ViewfinderSurfaceProvider.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.camera.viewfinder.surface
+
+import android.view.Surface
+
+/**
+ * A interface implemented by the application to provide a [Surface] for viewfinder.
+ *
+ * This interface is implemented by the application to provide a [Surface]. This
+ * will be called by application when it needs a Surface for viewfinder. It also signals when the
+ * Surface is no longer in use.
+ */
+interface ViewfinderSurfaceProvider {
+    /**
+     * Called when a new [Surface] has been requested by the camera.
+     *
+     *
+     * This is called every time a new surface is required to keep the viewfinder running.
+     * The camera may repeatedly request surfaces, but only a single request will be active at a
+     * time.
+     *
+     * @param request the request for a surface which contains the requirements of the
+     * surface and methods for completing the request.
+     */
+    fun onSurfaceRequested(request: ViewfinderSurfaceRequest)
+}
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ViewfinderSurfaceRequest.kt b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ViewfinderSurfaceRequest.kt
new file mode 100644
index 0000000..456280db
--- /dev/null
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/ViewfinderSurfaceRequest.kt
@@ -0,0 +1,631 @@
+/*
+ * 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.camera.viewfinder.surface
+
+import android.annotation.SuppressLint
+import android.hardware.camera2.CameraMetadata
+import android.util.Size
+import android.view.Surface
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+import androidx.camera.impl.utils.Logger
+import androidx.camera.impl.utils.executor.CameraExecutors
+import androidx.camera.impl.utils.futures.FutureCallback
+import androidx.camera.impl.utils.futures.Futures
+import androidx.camera.viewfinder.impl.surface.DeferredSurface
+import androidx.concurrent.futures.CallbackToFutureAdapter
+import androidx.core.util.Consumer
+import androidx.core.util.Preconditions
+import com.google.auto.value.AutoValue
+import com.google.common.util.concurrent.ListenableFuture
+import java.util.concurrent.CancellationException
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * The request to get a [Surface] to display camera feed.
+ *
+ *
+ * This request contains requirements for the surface resolution and camera
+ * device information from [CameraCharacteristics].
+ *
+ *  Calling [ViewfinderSurfaceRequest.markSurfaceSafeToRelease] will notify the
+ * surface provider that the surface is not needed and related resources can be released.
+ *
+ * Creates a new surface request with surface resolution, camera device, lens facing and
+ * sensor orientation information.
+ *
+ * @param resolution The requested surface resolution. It is the output surface size
+ *                   the camera is configured with, instead of {@link CameraViewfinder}
+ *                   view size.
+ * @param lensFacing The camera lens facing.
+ * @param sensorOrientation THe camera sensor orientation.
+ * @param implementationMode The {@link ImplementationMode} to apply to the viewfinder.
+ */
+class ViewfinderSurfaceRequest internal constructor(
+    val resolution: Size,
+    @LensFacingValue val lensFacing: Int,
+    @SensorOrientationDegreesValue val sensorOrientation: Int,
+    val implementationMode: ImplementationMode?
+) {
+    private val mInternalDeferredSurface: DeferredSurface
+    private val cancellationCompleter: CallbackToFutureAdapter.Completer<Void?>
+    private val sessionStatusFuture: ListenableFuture<Void?>
+    private val surfaceCompleter: CallbackToFutureAdapter.Completer<Surface>
+
+    private val surfaceFutureAsync: ListenableFuture<Surface>
+
+    init {
+        // To ensure concurrency and ordering, operations are chained. Completion can only be
+        // triggered externally by the top-level completer (mSurfaceCompleter). The other future
+        // completers are only completed by callbacks set up within the constructor of this class
+        // to ensure correct ordering of events.
+
+        // Cancellation listener must be called last to ensure the result can be retrieved from
+        // the session listener.
+        val surfaceRequestString =
+            "SurfaceRequest[size: " + resolution + ", id: " + this.hashCode() + "]"
+        val cancellationCompleterRef =
+            AtomicReference<CallbackToFutureAdapter.Completer<Void?>?>(null)
+        val requestCancellationFuture =
+            CallbackToFutureAdapter.getFuture {
+                cancellationCompleterRef.set(it)
+                "$surfaceRequestString-cancellation"
+            }
+        val requestCancellationCompleter =
+            Preconditions.checkNotNull(cancellationCompleterRef.get())
+        cancellationCompleter = requestCancellationCompleter
+
+        // Surface session status future completes and is responsible for finishing the
+        // cancellation listener.
+        val sessionStatusCompleterRef =
+            AtomicReference<CallbackToFutureAdapter.Completer<Void?>?>(null)
+        sessionStatusFuture =
+            CallbackToFutureAdapter.getFuture<Void?> {
+                sessionStatusCompleterRef.set(it)
+                "$surfaceRequestString-status"
+            }
+        Futures.addCallback<Void?>(sessionStatusFuture, object : FutureCallback<Void?> {
+            override fun onSuccess(result: Void?) {
+                // Cancellation didn't occur, so complete the cancellation future. There
+                // shouldn't ever be any standard listeners on this future, so nothing should be
+                // invoked.
+                Preconditions.checkState(requestCancellationCompleter.set(null))
+            }
+
+            override fun onFailure(t: Throwable) {
+                if (t is RequestCancelledException) {
+                    // Cancellation occurred. Notify listeners.
+                    Preconditions.checkState(
+                        requestCancellationFuture.cancel(false)
+                    )
+                } else {
+                    // Cancellation didn't occur, complete the future so cancellation listeners
+                    // are not invoked.
+                    Preconditions.checkState(requestCancellationCompleter.set(null))
+                }
+            }
+        }, CameraExecutors.directExecutor())
+
+        // Create the surface future/completer. This will be used to complete the rest of the
+        // future chain and can be set externally via SurfaceRequest methods.
+        val sessionStatusCompleter = Preconditions.checkNotNull(sessionStatusCompleterRef.get())
+        val surfaceCompleterRef =
+            AtomicReference<CallbackToFutureAdapter.Completer<Surface>?>(null)
+        surfaceFutureAsync =
+            CallbackToFutureAdapter.getFuture {
+                surfaceCompleterRef.set(it)
+                "$surfaceRequestString-Surface"
+            }
+        surfaceCompleter = Preconditions.checkNotNull(surfaceCompleterRef.get())
+
+        // Create the viewfinder surface which will be used for communicating when the
+        // camera and consumer are done using the surface. Note this anonymous inner class holds
+        // an implicit reference to the ViewfinderSurfaceRequest. This is by design, and ensures the
+        // ViewfinderSurfaceRequest and all contained future completers will not be garbage
+        // collected as long as the ViewfinderSurface is referenced externally (via
+        // getViewfinderSurface()).
+        mInternalDeferredSurface =
+            object : DeferredSurface() {
+                override fun provideSurfaceAsync(): ListenableFuture<Surface> {
+                    Logger.d(
+                        TAG,
+                        "mInternalViewfinderSurface + $this provideSurface"
+                    )
+                    return surfaceFutureAsync
+                }
+            }
+        val terminationFuture: ListenableFuture<Void?> =
+            mInternalDeferredSurface.getTerminationFutureAsync()
+
+        // Propagate surface completion to the session future.
+        Futures.addCallback<Surface>(surfaceFutureAsync, object : FutureCallback<Surface?> {
+            override fun onSuccess(result: Surface?) {
+                // On successful setting of a surface, defer completion of the session future to
+                // the ViewfinderSurface termination future. Once that future completes, then it
+                // is safe to release the Surface and associated resources.
+                Futures.propagate(terminationFuture, sessionStatusCompleter)
+            }
+
+            override fun onFailure(t: Throwable) {
+                // Translate cancellation into a SurfaceRequestCancelledException. Other
+                // exceptions mean either the request was completed via willNotProvideSurface() or a
+                // programming error occurred. In either case, the user will never see the
+                // session future (an immediate future will be returned instead), so complete the
+                // future so cancellation listeners are never called.
+                if (t is CancellationException) {
+                    Preconditions.checkState(
+                        sessionStatusCompleter.setException(
+                            RequestCancelledException(
+                                "$surfaceRequestString cancelled.", t
+                            )
+                        )
+                    )
+                } else {
+                    sessionStatusCompleter.set(null)
+                }
+            }
+        }, CameraExecutors.directExecutor())
+
+        // If the viewfinder surface is terminated, there are two cases:
+        // 1. The surface has not yet been provided to the camera (or marked as 'will not
+        //    complete'). Treat this as if the surface request has been cancelled.
+        // 2. The surface was already provided to the camera. In this case the camera is now
+        //    finished with the surface, so cancelling the surface future below will be a no-op.
+        terminationFuture.addListener({
+            Logger.d(
+                TAG,
+                ("mInternalViewfinderSurface + " + mInternalDeferredSurface + " " +
+                    "terminateFuture triggered")
+            )
+            surfaceFutureAsync.cancel(true)
+        }, CameraExecutors.directExecutor())
+    }
+
+    /**
+     * Closes the viewfinder surface to mark it as safe to release.
+     *
+     *
+     *  This method should be called by the user when the requested surface is not needed and
+     * related resources can be released.
+     */
+    fun markSurfaceSafeToRelease() {
+        mInternalDeferredSurface.close()
+    }
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun getSurface(): DeferredSurface {
+        return mInternalDeferredSurface
+    }
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @SuppressLint("PairedRegistration")
+    fun addRequestCancellationListener(
+        executor: Executor,
+        listener: Runnable
+    ) {
+        cancellationCompleter.addCancellationListener(listener, executor)
+    }
+
+    /**
+     * Completes the request for a [Surface] if it has not already been
+     * completed or cancelled.
+     *
+     *
+     * Once the camera no longer needs the provided surface, the `resultListener` will be
+     * invoked with a [Result] containing [Result.RESULT_SURFACE_USED_SUCCESSFULLY].
+     * At this point it is safe to release the surface and any underlying resources. Releasing
+     * the surface before receiving this signal may cause undesired behavior on lower API levels.
+     *
+     *
+     * If the request is cancelled by the camera before successfully attaching the
+     * provided surface to the camera, then the `resultListener` will be invoked with a
+     * [Result] containing [Result.RESULT_REQUEST_CANCELLED].
+     *
+     *
+     * If the request was previously completed via [.willNotProvideSurface], then
+     * `resultListener` will be invoked with a [Result] containing
+     * [Result.RESULT_WILL_NOT_PROVIDE_SURFACE].
+     *
+     *
+     * Upon returning from this method, the surface request is guaranteed to be complete.
+     * However, only the `resultListener` provided to the first invocation of this method
+     * should be used to track when the provided [Surface] is no longer in use by the
+     * camera, as subsequent invocations will always invoke the `resultListener` with a
+     * [Result] containing [Result.RESULT_SURFACE_ALREADY_PROVIDED].
+     *
+     * @param surface        The surface which will complete the request.
+     * @param executor       Executor used to execute the `resultListener`.
+     * @param resultListener Listener used to track how the surface is used by the camera in
+     * response to being provided by this method.
+     */
+    fun provideSurface(
+        surface: Surface,
+        executor: Executor,
+        resultListener: Consumer<Result?>
+    ) {
+        if (surfaceCompleter.set(surface) || surfaceFutureAsync.isCancelled) {
+            // Session will be pending completion (or surface request was cancelled). Return the
+            // session future.
+            Futures.addCallback(sessionStatusFuture, object : FutureCallback<Void?> {
+                override fun onSuccess(result: Void?) {
+                    resultListener.accept(
+                        Result(
+                            Result.RESULT_SURFACE_USED_SUCCESSFULLY,
+                            surface
+                        )
+                    )
+                }
+
+                override fun onFailure(t: Throwable) {
+                    Preconditions.checkState(
+                        t is RequestCancelledException, ("Camera " +
+                            "surface session should only fail with request " +
+                            "cancellation. Instead failed due to:\n" + t)
+                    )
+                    resultListener.accept(Result(Result.RESULT_REQUEST_CANCELLED, surface))
+                }
+            }, executor)
+        } else {
+            // Surface request is already complete
+            Preconditions.checkState(surfaceFutureAsync.isDone)
+            try {
+                surfaceFutureAsync.get()
+                // Getting this far means the surface was already provided.
+                executor.execute {
+                    resultListener.accept(
+                        Result(
+                            Result.RESULT_SURFACE_ALREADY_PROVIDED,
+                            surface
+                        )
+                    )
+                }
+            } catch (e: InterruptedException) {
+                executor.execute {
+                    resultListener.accept(
+                        Result(
+                            Result.RESULT_WILL_NOT_PROVIDE_SURFACE,
+                            surface
+                        )
+                    )
+                }
+            } catch (e: ExecutionException) {
+                executor.execute {
+                    resultListener.accept(
+                        Result(
+                            Result.RESULT_WILL_NOT_PROVIDE_SURFACE,
+                            surface
+                        )
+                    )
+                }
+            }
+        }
+    }
+
+    /**
+     * Signals that the request will never be fulfilled.
+     *
+     *
+     * This may be called in the case where the application may be shutting down and a
+     * surface will never be produced to fulfill the request.
+     *
+     *
+     * This will be called by CameraViewfinder as soon as it is known that the request will not
+     * be fulfilled. Failure to complete the SurfaceRequest via `willNotProvideSurface()`
+     * or [.provideSurface] may cause long delays in shutting
+     * down the camera.
+     *
+     *
+     * Upon returning from this method, the request is guaranteed to be complete, regardless
+     * of the return value. If the request was previously successfully completed by
+     * [.provideSurface], invoking this method will return
+     * `false`, and will have no effect on how the surface is used by the camera.
+     *
+     * @return `true` if this call to `willNotProvideSurface()` successfully
+     * completes the request, i.e., the request has not already been completed via
+     * [.provideSurface] or by a previous call to
+     * `willNotProvideSurface()` and has not already been cancelled by the camera.
+     */
+    fun willNotProvideSurface(): Boolean {
+        return surfaceCompleter.setException(
+            DeferredSurface.SurfaceUnavailableException(
+                ("Surface request will not complete.")
+            )
+        )
+    }
+
+    /**
+     * Builder for [ViewfinderSurfaceRequest].
+     */
+    class Builder {
+        private val resolution: Size
+
+        @LensFacingValue
+        private var lensFacing = CameraMetadata.LENS_FACING_BACK
+
+        @SensorOrientationDegreesValue
+        private var sensorOrientation = 0
+        private var implementationMode: ImplementationMode? = null
+
+        /**
+         * Constructor for [Builder].
+         *
+         *
+         * Creates a builder with viewfinder resolution.
+         *
+         * @param resolution viewfinder resolution.
+         */
+        constructor(resolution: Size) {
+            this.resolution = resolution
+        }
+
+        /**
+         * Constructor for [Builder].
+         *
+         *
+         * Creates a builder with other builder instance. The returned builder will be
+         * pre-populated with the state of the provided builder.
+         *
+         * @param builder [Builder] instance.
+         */
+        constructor(builder: Builder) {
+            resolution = builder.resolution
+            implementationMode = builder.implementationMode
+            lensFacing = builder.lensFacing
+            sensorOrientation = builder.sensorOrientation
+        }
+
+        /**
+         * Constructor for [Builder].
+         *
+         *
+         * Creates a builder with other [ViewfinderSurfaceRequest] instance. The
+         * returned builder will be pre-populated with the state of the provided
+         * [ViewfinderSurfaceRequest] instance.
+         *
+         * @param surfaceRequest [ViewfinderSurfaceRequest] instance.
+         */
+        constructor(surfaceRequest: ViewfinderSurfaceRequest) {
+            resolution = surfaceRequest.resolution
+            implementationMode = surfaceRequest.implementationMode
+            lensFacing = surfaceRequest.lensFacing
+            sensorOrientation = surfaceRequest.sensorOrientation
+        }
+
+        /**
+         * Sets the [ImplementationMode].
+         *
+         *
+         * **Possible values:**
+         *
+         *  * [PERFORMANCE][ImplementationMode.PERFORMANCE]
+         *  * [COMPATIBLE][ImplementationMode.COMPATIBLE]
+         *
+         * @param implementationMode The [ImplementationMode].
+         * @return This builder.
+         */
+        fun setImplementationMode(implementationMode: ImplementationMode?): Builder {
+            this.implementationMode = implementationMode
+            return this
+        }
+
+        /**
+         * Sets the lens facing.
+         *
+         *
+         * **Possible values:**
+         *
+         *  * [FRONT][CameraMetadata.LENS_FACING_FRONT]
+         *  * [BACK][CameraMetadata.LENS_FACING_BACK]
+         *  * [EXTERNAL][CameraMetadata.LENS_FACING_EXTERNAL]
+         *
+         *
+         *
+         * The value can be retrieved from [CameraCharacteristics] by key
+         * [CameraCharacteristics.LENS_FACING]. If not set,
+         * [CameraMetadata.LENS_FACING_BACK] will be used by default.
+         *
+         * @param lensFacing The lens facing.
+         * @return This builder.
+         */
+        fun setLensFacing(@LensFacingValue lensFacing: Int): Builder {
+            this.lensFacing = lensFacing
+            return this
+        }
+
+        /**
+         * Sets the sensor orientation.
+         *
+         *
+         * **Range of valid values:**<br></br>
+         * 0, 90, 180, 270
+         *
+         *
+         * The value can be retrieved from [CameraCharacteristics] by key
+         * [CameraCharacteristics.SENSOR_ORIENTATION]. If it is not
+         * set, 0 will be used by default.
+         *
+         * @param sensorOrientation
+         * @return this builder.
+         */
+        fun setSensorOrientation(@SensorOrientationDegreesValue sensorOrientation: Int): Builder {
+            this.sensorOrientation = sensorOrientation
+            return this
+        }
+
+        /**
+         * Builds the [ViewfinderSurfaceRequest].
+         * @return the instance of [ViewfinderSurfaceRequest].
+         *
+         * @throws IllegalArgumentException
+         */
+        fun build(): ViewfinderSurfaceRequest {
+            if ((lensFacing != CameraMetadata.LENS_FACING_FRONT
+                    ) && (lensFacing != CameraMetadata.LENS_FACING_BACK
+                    ) && (lensFacing != CameraMetadata.LENS_FACING_EXTERNAL)
+            ) {
+                throw IllegalArgumentException(
+                    ("Lens facing value: $lensFacing is invalid")
+                )
+            }
+            if ((sensorOrientation != 0
+                    ) && (sensorOrientation != 90
+                    ) && (sensorOrientation != 180
+                    ) && (sensorOrientation != 270)
+            ) {
+                throw IllegalArgumentException(
+                    ("Sensor orientation value: $sensorOrientation is invalid")
+                )
+            }
+            return ViewfinderSurfaceRequest(
+                resolution,
+                lensFacing,
+                sensorOrientation,
+                implementationMode
+            )
+        }
+    }
+
+    internal class RequestCancelledException(message: String, cause: Throwable) :
+        RuntimeException(message, cause)
+
+    /**
+     * Result of providing a surface to a [ViewfinderSurfaceRequest] via
+     * [.provideSurface].
+     *
+     * Can be used to compare to results returned to `resultListener` in
+     * [.provideSurface].
+     *
+     * @param code    One of [.RESULT_SURFACE_USED_SUCCESSFULLY],
+     * [.RESULT_REQUEST_CANCELLED], [.RESULT_INVALID_SURFACE],
+     * [.RESULT_SURFACE_ALREADY_PROVIDED], or
+     * [.RESULT_WILL_NOT_PROVIDE_SURFACE].
+     * @param surface The [Surface] used to complete the [ViewfinderSurfaceRequest].
+     */
+    @AutoValue
+    data class Result(@ResultCode val code: Int, val surface: Surface) {
+        /**
+         * Possible result codes.
+         *
+         */
+        @IntDef(
+            RESULT_SURFACE_USED_SUCCESSFULLY,
+            RESULT_REQUEST_CANCELLED,
+            RESULT_INVALID_SURFACE,
+            RESULT_SURFACE_ALREADY_PROVIDED,
+            RESULT_WILL_NOT_PROVIDE_SURFACE
+        )
+        @Retention(
+            AnnotationRetention.SOURCE
+        )
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        annotation class ResultCode()
+        companion object {
+            /**
+             * Provided surface was successfully used by the camera and eventually detached once no
+             * longer needed by the camera.
+             *
+             *
+             * This result denotes that it is safe to release the [Surface] and any underlying
+             * resources.
+             *
+             *
+             * For compatibility reasons, the [Surface] object should not be reused by
+             * future [SurfaceRequests][ViewfinderSurfaceRequest], and a new surface should be
+             * created instead.
+             */
+            const val RESULT_SURFACE_USED_SUCCESSFULLY = 0
+
+            /**
+             * Provided surface was never attached to the camera due to the
+             * [ViewfinderSurfaceRequest] being cancelled by the camera.
+             *
+             *
+             * It is safe to release or reuse [Surface], assuming it was not previously
+             * attached to a camera via [.provideSurface]. If
+             * reusing the surface for a future surface request, it should be verified that the
+             * surface still matches the resolution specified by
+             * [ViewfinderSurfaceRequest.resolution].
+             */
+            const val RESULT_REQUEST_CANCELLED = 1
+
+            /**
+             * Provided surface could not be used by the camera.
+             *
+             *
+             * This is likely due to the [Surface] being closed prematurely or the resolution
+             * of the surface not matching the resolution specified by
+             * [ViewfinderSurfaceRequest.resolution].
+             */
+            const val RESULT_INVALID_SURFACE = 2
+
+            /**
+             * Surface was not attached to the camera through this invocation of
+             * [.provideSurface] due to the
+             * [ViewfinderSurfaceRequest] already being complete with a surface.
+             *
+             *
+             * The [ViewfinderSurfaceRequest] has already been completed by a previous
+             * invocation of [.provideSurface].
+             *
+             *
+             * It is safe to release or reuse the [Surface], assuming it was not previously
+             * attached to a camera via [.provideSurface].
+             */
+            const val RESULT_SURFACE_ALREADY_PROVIDED = 3
+
+            /**
+             * Surface was not attached to the camera through this invocation of
+             * [.provideSurface] due to the
+             * [ViewfinderSurfaceRequest] already being marked as "will not provide surface".
+             *
+             *
+             * The [ViewfinderSurfaceRequest] has already been marked as 'will not provide
+             * surface' by a previous invocation of [.willNotProvideSurface].
+             *
+             *
+             * It is safe to release or reuse the [Surface], assuming it was not previously
+             * attached to a camera via [.provideSurface].
+             */
+            const val RESULT_WILL_NOT_PROVIDE_SURFACE = 4
+        }
+    }
+
+    /**
+     * Valid integer sensor orientation degrees values.
+     */
+    @IntDef(0, 90, 180, 270)
+    @Retention(AnnotationRetention.SOURCE)
+    internal annotation class SensorOrientationDegreesValue()
+
+    /**
+     * Valid integer sensor orientation degrees values.
+     */
+    @IntDef(
+        CameraMetadata.LENS_FACING_FRONT,
+        CameraMetadata.LENS_FACING_BACK,
+        CameraMetadata.LENS_FACING_EXTERNAL
+    )
+    @Retention(
+        AnnotationRetention.SOURCE
+    )
+    internal annotation class LensFacingValue()
+    companion object {
+        private const val TAG = "SurfaceRequest"
+    }
+}
diff --git a/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/package-info.java b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/package-info.java
new file mode 100644
index 0000000..e8f0a15
--- /dev/null
+++ b/camera/camera-viewfinder-core/src/main/java/androidx/camera/viewfinder/surface/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ */
+@RequiresApi(21)
+package androidx.camera.viewfinder.surface;
+
+import androidx.annotation.RequiresApi;
diff --git a/camera/integration-tests/avsynctestapp/build.gradle b/camera/integration-tests/avsynctestapp/build.gradle
index 1f8b8ef..9c5f5cf 100644
--- a/camera/integration-tests/avsynctestapp/build.gradle
+++ b/camera/integration-tests/avsynctestapp/build.gradle
@@ -49,7 +49,7 @@
     // Compose
     def compose_version = "1.4.0"
     implementation("androidx.activity:activity-compose:1.5.0")
-    implementation("androidx.compose.material:material:$compose_version")
+    implementation(project(":compose:material:material"))
     implementation("androidx.compose.ui:ui:$compose_version")
     implementation("androidx.compose.ui:ui-tooling-preview:$compose_version")
     implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
diff --git a/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/ui/widget/Button.kt b/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/ui/widget/Button.kt
index fb57929..e8b4117 100644
--- a/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/ui/widget/Button.kt
+++ b/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/ui/widget/Button.kt
@@ -18,14 +18,14 @@
 
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.shape.CornerSize
+import androidx.compose.material.ExperimentalMaterialApi
 import androidx.compose.material.FloatingActionButton
 import androidx.compose.material.FloatingActionButtonDefaults
 import androidx.compose.material.FloatingActionButtonElevation
+import androidx.compose.material.LocalRippleConfiguration
 import androidx.compose.material.MaterialTheme
+import androidx.compose.material.RippleConfiguration
 import androidx.compose.material.contentColorFor
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleAlpha
-import androidx.compose.material.ripple.RippleTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.remember
@@ -33,6 +33,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 
+@OptIn(ExperimentalMaterialApi::class)
 @Composable
 fun AdvancedFloatingActionButton(
     modifier: Modifier = Modifier,
@@ -45,9 +46,9 @@
     elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
     content: @Composable () -> Unit
 ) {
-    val rippleTheme = if (enabled) LocalRippleTheme.current else DisabledRippleTheme
-
-    CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+    CompositionLocalProvider(
+        LocalRippleConfiguration provides RippleConfiguration(isEnabled = enabled)
+    ) {
         FloatingActionButton(
             onClick = if (enabled) onClick else { {} },
             modifier = modifier,
@@ -60,12 +61,3 @@
         )
     }
 }
-
-private object DisabledRippleTheme : RippleTheme {
-
-    @Composable
-    override fun defaultColor(): Color = Color.Transparent
-
-    @Composable
-    override fun rippleAlpha(): RippleAlpha = RippleAlpha(0f, 0f, 0f, 0f)
-}
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraInfoDeviceTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraInfoDeviceTest.kt
new file mode 100644
index 0000000..e73da7a
--- /dev/null
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraInfoDeviceTest.kt
@@ -0,0 +1,116 @@
+/*
+ * 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.camera.integration.core
+
+import android.content.Context
+import androidx.camera.camera2.Camera2Config
+import androidx.camera.camera2.pipe.integration.CameraPipeConfig
+import androidx.camera.core.CameraXConfig
+import androidx.camera.core.DynamicRange
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.camera.testing.impl.CameraPipeConfigTestRule
+import androidx.camera.testing.impl.CameraUtil
+import androidx.camera.testing.impl.CoreAppTestUtil
+import androidx.concurrent.futures.await
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.LargeTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@LargeTest
+@RunWith(Parameterized::class)
+class CameraInfoDeviceTest(
+    private val implName: String,
+    private val cameraXConfig: CameraXConfig
+) {
+    @get:Rule
+    val useCamera = CameraUtil.grantCameraPermissionAndPreTest(
+        CameraUtil.PreTestCameraIdList(
+            if (implName == Camera2Config::class.simpleName) {
+                Camera2Config.defaultConfig()
+            } else {
+                CameraPipeConfig.defaultConfig()
+            }
+        )
+    )
+
+    @get:Rule
+    val cameraPipeConfigTestRule = CameraPipeConfigTestRule(
+        active = implName == CameraPipeConfig::class.simpleName,
+    )
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+    private lateinit var cameraProvider: ProcessCameraProvider
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun data() = listOf(
+            arrayOf(Camera2Config::class.simpleName, Camera2Config.defaultConfig()),
+            arrayOf(CameraPipeConfig::class.simpleName, CameraPipeConfig.defaultConfig())
+        )
+    }
+
+    @Before
+    fun setUp() = runBlocking {
+        assumeTrue(CameraUtil.deviceHasCamera())
+        CoreAppTestUtil.assumeCompatibleDevice()
+
+        withTimeout(10000) {
+            ProcessCameraProvider.configureInstance(cameraXConfig)
+            cameraProvider = ProcessCameraProvider.getInstance(context).await()
+        }
+    }
+
+    @After
+    fun tearDown() {
+        if (::cameraProvider.isInitialized) {
+            cameraProvider.shutdownAsync()[10, TimeUnit.SECONDS]
+        }
+    }
+
+    @Test
+    fun allCamerasAdvertiseSdr() {
+        cameraProvider.availableCameraInfos.forEach { cameraInfo ->
+            assertThat(cameraInfo.querySupportedDynamicRanges(setOf(DynamicRange.UNSPECIFIED)))
+                .contains(DynamicRange.SDR)
+        }
+    }
+
+    @Test
+    fun underSpecifiedDynamicRange_neverReturnedFromQuery() {
+        cameraProvider.availableCameraInfos.forEach { cameraInfo ->
+            cameraInfo.querySupportedDynamicRanges(setOf(DynamicRange.UNSPECIFIED)).forEach {
+                assertWithMessage(
+                    "$cameraInfo advertises under-specified dynamic range: $it"
+                ).that(
+                    it.isFullySpecified
+                ).isTrue()
+            }
+        }
+    }
+}
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index e89bff2..0bde846 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -345,8 +345,10 @@
     private OpenGLRenderer mPreviewRenderer;
     private DisplayManager.DisplayListener mDisplayListener;
     private RecordUi mRecordUi;
+    private DynamicRangeUi mDynamicRangeUi;
     private Quality mVideoQuality;
     private DynamicRange mDynamicRange = DynamicRange.SDR;
+    private Set<DynamicRange> mDisplaySupportedHighDynamicRanges = Collections.emptySet();
     private final Set<DynamicRange> mSelectableDynamicRanges = new HashSet<>();
     private int mVideoMirrorMode = MIRROR_MODE_ON_FRONT_ONLY;
     private boolean mIsPreviewStabilizationOn = false;
@@ -716,42 +718,6 @@
         });
 
         // Final reference to this record UI
-        mRecordUi.getButtonDynamicRange().setText(getDynamicRangeIconName(mDynamicRange));
-        mRecordUi.getButtonDynamicRange().setOnClickListener(view -> {
-            PopupMenu popup = new PopupMenu(this, view);
-            Menu menu = popup.getMenu();
-
-            final int groupId = Menu.NONE;
-            for (DynamicRange dynamicRange : mSelectableDynamicRanges) {
-                int itemId = dynamicRangeToItemId(dynamicRange);
-                menu.add(groupId, itemId, itemId, getDynamicRangeMenuItemName(dynamicRange));
-                if (Objects.equals(dynamicRange, mDynamicRange)) {
-                    // Apply the checked item for the selected dynamic range to the menu.
-                    menu.findItem(itemId).setChecked(true);
-                }
-            }
-
-            // Make menu single checkable
-            menu.setGroupCheckable(groupId, true, true);
-
-            popup.setOnMenuItemClickListener(item -> {
-                DynamicRange dynamicRange = itemIdToDynamicRange(item.getItemId());
-                if (!Objects.equals(dynamicRange, mDynamicRange)) {
-                    mDynamicRange = dynamicRange;
-                    if (Build.VERSION.SDK_INT >= 26) {
-                        updateWindowColorMode();
-                    }
-                    mRecordUi.getButtonDynamicRange()
-                            .setText(getDynamicRangeIconName(mDynamicRange));
-                    // Dynamic range changed, rebind UseCases
-                    tryBindUseCases();
-                }
-                return true;
-            });
-
-            popup.show();
-        });
-
         mRecordUi.getButtonQuality().setText(getQualityIconName(mVideoQuality));
         mRecordUi.getButtonQuality().setOnClickListener(view -> {
             PopupMenu popup = new PopupMenu(this, view);
@@ -799,6 +765,47 @@
         });
     }
 
+    private void setUpDynamicRangeButton() {
+        mDynamicRangeUi.setDisplayedDynamicRange(mDynamicRange);
+        mDynamicRangeUi.getButton().setOnClickListener(view -> {
+            PopupMenu popup = new PopupMenu(this, view);
+            Menu menu = popup.getMenu();
+
+            final int groupId = Menu.NONE;
+            for (DynamicRange dynamicRange : mSelectableDynamicRanges) {
+                int itemId = dynamicRangeToItemId(dynamicRange);
+                menu.add(groupId, itemId, itemId, getDynamicRangeMenuItemName(dynamicRange));
+                if (Objects.equals(dynamicRange, mDynamicRange)) {
+                    // Apply the checked item for the selected dynamic range to the menu.
+                    menu.findItem(itemId).setChecked(true);
+                }
+            }
+
+            // Make menu single checkable
+            menu.setGroupCheckable(groupId, true, true);
+
+            popup.setOnMenuItemClickListener(item -> {
+                DynamicRange dynamicRange = itemIdToDynamicRange(item.getItemId());
+                if (!Objects.equals(dynamicRange, mDynamicRange)) {
+                    setSelectedDynamicRange(dynamicRange);
+                    // Dynamic range changed, rebind UseCases
+                    tryBindUseCases();
+                }
+                return true;
+            });
+
+            popup.show();
+        });
+    }
+
+    private void setSelectedDynamicRange(@NonNull DynamicRange dynamicRange) {
+        mDynamicRange = dynamicRange;
+        if (Build.VERSION.SDK_INT >= 26) {
+            updateWindowColorMode();
+        }
+        mDynamicRangeUi.setDisplayedDynamicRange(mDynamicRange);
+    }
+
     @RequiresApi(26)
     private void updateWindowColorMode() {
         int colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
@@ -1155,6 +1162,7 @@
             mPhotoToggle.setVisibility(View.GONE);
             mPreviewToggle.setVisibility(View.GONE);
             mAnalysisToggle.setVisibility(View.GONE);
+            mDynamicRangeUi.getButton().setVisibility(View.GONE);
             mRecordUi.hideUi();
             if (!testCase.equals(SWITCH_TEST_CASE)) {
                 mCameraDirectionButton.setVisibility(View.GONE);
@@ -1190,10 +1198,30 @@
         }
     }
 
+    private void updateDynamicRangeUiState() {
+        // Only show dynamic range if video or preview are enabled
+        boolean visible = (mVideoToggle.isChecked() || mPreviewToggle.isChecked());
+        // Dynamic range is configurable if it's visible, there's more than 1 choice, and there
+        // isn't a recording in progress
+        boolean configurable = visible
+                && mSelectableDynamicRanges.size() > 1
+                && mRecordUi.getState() != RecordUi.State.RECORDING;
+
+        if (configurable) {
+            mDynamicRangeUi.setState(DynamicRangeUi.State.CONFIGURABLE);
+        } else if (visible) {
+            mDynamicRangeUi.setState(DynamicRangeUi.State.VISIBLE);
+        } else {
+            mDynamicRangeUi.setState(DynamicRangeUi.State.HIDDEN);
+        }
+    }
+
     @SuppressLint({"NullAnnotationGroup", "RestrictedApiAndroidX"})
     @OptIn(markerClass = androidx.camera.core.ExperimentalZeroShutterLag.class)
     private void updateButtonsUi() {
         mRecordUi.setEnabled(mVideoToggle.isChecked());
+        updateDynamicRangeUiState();
+
         mTakePicture.setEnabled(mPhotoToggle.isChecked());
         mCaptureQualityToggle.setEnabled(mPhotoToggle.isChecked());
         mZslToggle.setVisibility(getCameraInfo() != null
@@ -1276,6 +1304,7 @@
         mPreviewToggle.setOnCheckedChangeListener(mOnCheckedChangeListener);
 
         setUpRecordButton();
+        setUpDynamicRangeButton();
         setUpFlashButton();
         setUpTakePictureButton();
         setUpCameraDirectionButton();
@@ -1352,12 +1381,14 @@
 
         setContentView(R.layout.activity_camera_xmain);
         mImageCaptureExecutorService = Executors.newSingleThreadExecutor();
-        Display display = null;
+        mDisplaySupportedHighDynamicRanges = Collections.emptySet();
         if (Build.VERSION.SDK_INT >= 30) {
-            display = OpenGLActivity.Api30Impl.getDisplay(this);
+            Display display = OpenGLActivity.Api30Impl.getDisplay(this);
+            mDisplaySupportedHighDynamicRanges =
+                    OpenGLActivity.getHighDynamicRangesSupportedByDisplay(display);
         }
         OpenGLRenderer previewRenderer = mPreviewRenderer =
-                new OpenGLRenderer(OpenGLActivity.getHdrEncodingsSupportedByDisplay(display));
+                new OpenGLRenderer(mDisplaySupportedHighDynamicRanges);
         ViewStub viewFinderStub = findViewById(R.id.viewFinderStub);
         updatePreviewRatioAndScaleTypeByIntent(viewFinderStub);
         updateVideoMirrorModeByIntent(getIntent());
@@ -1391,13 +1422,14 @@
         mZoomResetToggle = findViewById(R.id.zoom_reset_toggle);
 
         mTextView = findViewById(R.id.textView);
+        mDynamicRangeUi = new DynamicRangeUi(findViewById(R.id.dynamic_range));
         mRecordUi = new RecordUi(
                 findViewById(R.id.Video),
                 findViewById(R.id.video_pause),
                 findViewById(R.id.video_stats),
                 findViewById(R.id.video_quality),
                 findViewById(R.id.video_persistent),
-                findViewById(R.id.video_dynamic_range)
+                (newState) -> updateDynamicRangeUiState()
         );
 
         setUpButtonEvents();
@@ -1631,8 +1663,7 @@
             // Reset video quality to avoid always fail by quality too large.
             mRecordUi.getButtonQuality().setText(getQualityIconName(mVideoQuality = QUALITY_AUTO));
             // Reset video dynamic range to avoid failure
-            mRecordUi.getButtonDynamicRange().setText(
-                    getDynamicRangeIconName(mDynamicRange = DynamicRange.SDR));
+            setSelectedDynamicRange(DynamicRange.SDR);
 
             reduceUseCaseToFindSupportedCombination();
 
@@ -1694,11 +1725,18 @@
     @SuppressLint("RestrictedApiAndroidX")
     private List<UseCase> buildUseCases() {
         List<UseCase> useCases = new ArrayList<>();
+        if (mVideoToggle.isChecked() || mPreviewToggle.isChecked()) {
+            // Update possible dynamic ranges for current camera
+            updateDynamicRangeConfiguration();
+        }
+
         if (mPreviewToggle.isChecked()) {
             Preview preview = new Preview.Builder()
                     .setTargetName("Preview")
                     .setTargetAspectRatio(mTargetAspectRatio)
                     .setPreviewStabilizationEnabled(mIsPreviewStabilizationOn)
+                    .setDynamicRange(
+                            mVideoToggle.isChecked() ? DynamicRange.UNSPECIFIED : mDynamicRange)
                     .build();
             resetViewIdlingResource();
             // Use the listener of the future to make sure the Preview setup the new surface.
@@ -1732,9 +1770,6 @@
         }
 
         if (mVideoToggle.isChecked()) {
-            // Update possible dynamic ranges for current camera
-            updateDynamicRangeConfiguration();
-
             // Recreate the Recorder except there's a running persistent recording, existing
             // Recorder. We may later consider reuse the Recorder everytime if the quality didn't
             // change.
@@ -1756,29 +1791,43 @@
         return useCases;
     }
 
+    @SuppressLint("RestrictedApiAndroidX")
     private void updateDynamicRangeConfiguration() {
         mSelectableDynamicRanges.clear();
 
-        // Get the list of available dynamic ranges for the current quality
-        VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(
-                mCamera.getCameraInfo());
-        Set<DynamicRange> supportedDynamicRanges =
-                videoCapabilities.getSupportedDynamicRanges();
+        Set<DynamicRange> supportedDynamicRanges = Collections.singleton(DynamicRange.SDR);
+        // ImageCapture and ImageAnalysis currently only support SDR, so only update supported
+        // ranges if they're not enabled
+        if (!mAnalysisToggle.isChecked() && !mPhotoToggle.isChecked()) {
+            if (mVideoToggle.isChecked()) {
+                // Get the list of available dynamic ranges for the current quality
+                VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(
+                        mCamera.getCameraInfo());
+                supportedDynamicRanges = videoCapabilities.getSupportedDynamicRanges();
+            } else if (mPreviewToggle.isChecked()) {
+                supportedDynamicRanges = new HashSet<>();
+                // Add SDR as its always available
+                supportedDynamicRanges.add(DynamicRange.SDR);
+
+                // Add all HDR dynamic ranges supported by the display
+                Set<DynamicRange> queryResult = mCamera.getCameraInfo()
+                        .querySupportedDynamicRanges(
+                                Collections.singleton(DynamicRange.UNSPECIFIED));
+                supportedDynamicRanges.addAll(queryResult);
+            }
+        }
 
         if (supportedDynamicRanges.size() > 1) {
-            mRecordUi.setDynamicRangeConfigurable(true);
             if (hasTenBitDynamicRange(supportedDynamicRanges)) {
                 mSelectableDynamicRanges.add(DynamicRange.HDR_UNSPECIFIED_10_BIT);
             }
-        } else {
-            mRecordUi.setDynamicRangeConfigurable(false);
         }
         mSelectableDynamicRanges.addAll(supportedDynamicRanges);
 
         // In case the previous dynamic range held in mDynamicRange isn't supported, reset
         // to SDR.
         if (!mSelectableDynamicRanges.contains(mDynamicRange)) {
-            mDynamicRange = DynamicRange.SDR;
+            setSelectedDynamicRange(DynamicRange.SDR);
         }
     }
 
@@ -2064,6 +2113,65 @@
         }
     }
 
+    private static class DynamicRangeUi {
+
+        enum State {
+            // Button can be selected to choose dynamic range
+            CONFIGURABLE,
+            // Button is visible, but cannot be selected
+            VISIBLE,
+            // Button is not visible, cannot be selected
+            HIDDEN
+        }
+
+        private State mState = State.HIDDEN;
+
+        private final Button mButtonDynamicRange;
+
+        DynamicRangeUi(@NonNull Button buttonDynamicRange) {
+            mButtonDynamicRange = buttonDynamicRange;
+        }
+
+        void setState(@NonNull State newState) {
+            if (newState != mState) {
+                mState = newState;
+                switch (newState) {
+                    case HIDDEN: {
+                        mButtonDynamicRange.setEnabled(false);
+                        mButtonDynamicRange.setVisibility(View.INVISIBLE);
+                        break;
+                    }
+                    case VISIBLE: {
+                        mButtonDynamicRange.setEnabled(false);
+                        mButtonDynamicRange.setVisibility(View.VISIBLE);
+                        break;
+                    }
+                    case CONFIGURABLE: {
+                        mButtonDynamicRange.setEnabled(true);
+                        mButtonDynamicRange.setVisibility(View.VISIBLE);
+                        break;
+                    }
+                }
+            }
+        }
+
+        @NonNull
+        Button getButton() {
+            return mButtonDynamicRange;
+        }
+
+        void setDisplayedDynamicRange(@NonNull DynamicRange dynamicRange) {
+            int resId = R.string.toggle_video_dyn_rng_unknown;
+            for (DynamicRangeUiData uiData : DYNAMIC_RANGE_UI_DATA) {
+                if (Objects.equals(dynamicRange, uiData.mDynamicRange)) {
+                    resId = uiData.mToggleLabelRes;
+                    break;
+                }
+            }
+            mButtonDynamicRange.setText(resId);
+        }
+    }
+
     @UiThread
     private static class RecordUi {
 
@@ -2076,22 +2184,20 @@
         private final TextView mTextStats;
         private final Button mButtonQuality;
         private final ToggleButton mButtonPersistent;
-        private final Button mButtonDynamicRange;
-        private boolean mDynamicRangeConfigurable = false;
-
         private boolean mEnabled = false;
         private State mState = State.IDLE;
+        private final Consumer<State> mNewStateConsumer;
 
         RecordUi(@NonNull Button buttonRecord, @NonNull Button buttonPause,
                 @NonNull TextView textStats, @NonNull Button buttonQuality,
                 @NonNull ToggleButton buttonPersistent,
-                @NonNull Button buttonDynamicRange) {
+                @NonNull Consumer<State> onNewState) {
             mButtonRecord = buttonRecord;
             mButtonPause = buttonPause;
             mTextStats = textStats;
             mButtonQuality = buttonQuality;
             mButtonPersistent = buttonPersistent;
-            mButtonDynamicRange = buttonDynamicRange;
+            mNewStateConsumer = onNewState;
         }
 
         void setEnabled(boolean enabled) {
@@ -2101,22 +2207,23 @@
                 mTextStats.setVisibility(View.VISIBLE);
                 mButtonQuality.setVisibility(View.VISIBLE);
                 mButtonPersistent.setVisibility(View.VISIBLE);
-                mButtonDynamicRange.setVisibility(View.VISIBLE);
                 updateUi();
             } else {
                 mButtonRecord.setText("Record");
                 mButtonRecord.setEnabled(false);
                 mButtonPause.setVisibility(View.INVISIBLE);
                 mButtonQuality.setVisibility(View.INVISIBLE);
-                mButtonDynamicRange.setVisibility(View.INVISIBLE);
                 mTextStats.setVisibility(View.GONE);
                 mButtonPersistent.setVisibility(View.INVISIBLE);
             }
         }
 
         void setState(@NonNull State state) {
-            mState = state;
-            updateUi();
+            if (state != mState) {
+                mState = state;
+                updateUi();
+                mNewStateConsumer.accept(state);
+            }
         }
 
         @NonNull
@@ -2131,14 +2238,6 @@
             mButtonPersistent.setVisibility(View.GONE);
         }
 
-        private void setDynamicRangeConfigurable(boolean configurable) {
-            if (configurable != mDynamicRangeConfigurable) {
-                mDynamicRangeConfigurable = configurable;
-                boolean buttonEnabled = mButtonDynamicRange.isEnabled();
-                mButtonDynamicRange.setEnabled(buttonEnabled && mDynamicRangeConfigurable);
-            }
-        }
-
         private void updateUi() {
             if (!mEnabled) {
                 return;
@@ -2151,7 +2250,6 @@
                     mButtonPause.setVisibility(View.INVISIBLE);
                     mButtonPersistent.setEnabled(true);
                     mButtonQuality.setEnabled(true);
-                    mButtonDynamicRange.setEnabled(mDynamicRangeConfigurable);
                     break;
                 case RECORDING:
                     mButtonRecord.setText("Stop");
@@ -2160,7 +2258,6 @@
                     mButtonPause.setVisibility(View.VISIBLE);
                     mButtonPersistent.setEnabled(false);
                     mButtonQuality.setEnabled(false);
-                    mButtonDynamicRange.setEnabled(false);
                     break;
                 case STOPPING:
                     mButtonRecord.setText("Saving");
@@ -2169,7 +2266,6 @@
                     mButtonPause.setVisibility(View.INVISIBLE);
                     mButtonPersistent.setEnabled(false);
                     mButtonQuality.setEnabled(true);
-                    mButtonDynamicRange.setEnabled(mDynamicRangeConfigurable);
                     break;
                 case PAUSED:
                     mButtonRecord.setText("Stop");
@@ -2178,7 +2274,6 @@
                     mButtonPause.setVisibility(View.VISIBLE);
                     mButtonPersistent.setEnabled(false);
                     mButtonQuality.setEnabled(true);
-                    mButtonDynamicRange.setEnabled(mDynamicRangeConfigurable);
                     break;
             }
         }
@@ -2203,10 +2298,6 @@
         ToggleButton getButtonPersistent() {
             return mButtonPersistent;
         }
-        @NonNull
-        Button getButtonDynamicRange() {
-            return mButtonDynamicRange;
-        }
     }
 
     Preview getPreview() {
@@ -2351,19 +2442,6 @@
     }
 
     @NonNull
-    private String getDynamicRangeIconName(@NonNull DynamicRange dynamicRange) {
-        int resId = R.string.toggle_video_dyn_rng_unknown;
-        for (DynamicRangeUiData uiData : DYNAMIC_RANGE_UI_DATA) {
-            if (Objects.equals(dynamicRange, uiData.mDynamicRange)) {
-                resId = uiData.mToggleLabelRes;
-                break;
-            }
-        }
-
-        return getString(resId);
-    }
-
-    @NonNull
     private static String getDynamicRangeMenuItemName(@NonNull DynamicRange dynamicRange) {
         String menuItemName = dynamicRange.toString();
         for (DynamicRangeUiData uiData : DYNAMIC_RANGE_UI_DATA) {
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLActivity.java
index 4faa7a9..00a0313 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLActivity.java
@@ -59,10 +59,11 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /** Activity which runs the camera preview with opengl processing */
@@ -136,7 +137,7 @@
             display = Api30Impl.getDisplay(this);
         }
         OpenGLRenderer renderer = mRenderer = new OpenGLRenderer(
-                getHdrEncodingsSupportedByDisplay(display));
+                getHighDynamicRangesSupportedByDisplay(display));
         ViewStub viewFinderStub = findViewById(R.id.viewFinderStub);
         View viewFinder = OpenGLActivity.chooseViewFinder(getIntent().getExtras(), viewFinderStub,
                 renderer);
@@ -267,20 +268,20 @@
     }
 
     /**
-     * Returns a list of HDR encodings supported by the display.
+     * Returns a list of HDR dynamic ranges supported by the display.
      *
-     * <p>The returned HDR encodings are the encodings from the {@link DynamicRange} class, such
-     * as {@link DynamicRange#ENCODING_HLG}. The returned list will never contain
-     * {@link DynamicRange#ENCODING_SDR}.
+     * <p>The returned HDR dynamic ranges are constants defined by the {@code DynamicRange} class.
+     * The returned list will never contain {@link DynamicRange#SDR}.
      *
      * <p>The list may be empty if the display does not support HDR, such as on pre-API 24 devices.
      */
     @NonNull
-    public static List<Integer> getHdrEncodingsSupportedByDisplay(@Nullable Display display) {
+    public static Set<DynamicRange> getHighDynamicRangesSupportedByDisplay(
+            @Nullable Display display) {
         if (display != null && Build.VERSION.SDK_INT >= 24) {
-            return Api24Impl.getHdrEncodingsSupportedByDisplay(display);
+            return Api24Impl.getHighDynamicRangesSupportedByDisplay(display);
         } else {
-            return Collections.emptyList();
+            return Collections.emptySet();
         }
     }
 
@@ -334,17 +335,19 @@
 
     @RequiresApi(24)
     static class Api24Impl {
-        private static final Map<Integer, Integer> DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE_ENCODING =
+        private static final Map<Integer, Set<DynamicRange>> DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE =
                 new HashMap<>();
 
         static {
-            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE_ENCODING.put(HDR_TYPE_HLG, DynamicRange.ENCODING_HLG);
-            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE_ENCODING.put(HDR_TYPE_HDR10,
-                    DynamicRange.ENCODING_HDR10);
-            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE_ENCODING.put(HDR_TYPE_HDR10_PLUS,
-                    DynamicRange.ENCODING_HDR10_PLUS);
-            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE_ENCODING.put(HDR_TYPE_DOLBY_VISION,
-                    DynamicRange.ENCODING_DOLBY_VISION);
+            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE.put(HDR_TYPE_HLG,
+                    Collections.singleton(DynamicRange.HLG_10_BIT));
+            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE.put(HDR_TYPE_HDR10,
+                    Collections.singleton(DynamicRange.HDR10_10_BIT));
+            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE.put(HDR_TYPE_HDR10_PLUS,
+                    Collections.singleton(DynamicRange.HDR10_PLUS_10_BIT));
+            DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE.put(HDR_TYPE_DOLBY_VISION,
+                    new HashSet<>(Arrays.asList(
+                            DynamicRange.DOLBY_VISION_8_BIT, DynamicRange.DOLBY_VISION_10_BIT)));
         }
 
         private Api24Impl() {
@@ -352,12 +355,14 @@
         }
 
         @DoNotInline
-        static List<Integer> getHdrEncodingsSupportedByDisplay(@NonNull Display display) {
+        static Set<DynamicRange> getHighDynamicRangesSupportedByDisplay(
+                @NonNull Display display) {
             return Arrays.stream(display.getHdrCapabilities().getSupportedHdrTypes())
                     .boxed()
-                    .map(DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE_ENCODING::get)
+                    .map(DISPLAY_HDR_TYPE_TO_DYNAMIC_RANGE::get)
+                    .flatMap(set -> Objects.requireNonNull(set).stream())
                     .filter(Objects::nonNull)
-                    .collect(Collectors.toList());
+                    .collect(Collectors.toSet());
         }
 
     }
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLRenderer.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLRenderer.java
index 60dafae..fe1c9b8 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLRenderer.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/OpenGLRenderer.java
@@ -42,9 +42,9 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -120,10 +120,10 @@
 
     private Pair<Executor, Consumer<Long>> mFrameUpdateListener;
 
-    private final List<Integer> mHdrEncodingsSupportedByOutput;
+    private final Set<DynamicRange> mHighDynamicRangesSupportedByOutput;
 
-    OpenGLRenderer(@NonNull List<Integer> hdrEncodingsSupportedByOutput) {
-        mHdrEncodingsSupportedByOutput = hdrEncodingsSupportedByOutput;
+    OpenGLRenderer(@NonNull Set<DynamicRange> highDynamicRangesSupportedByOutput) {
+        mHighDynamicRangesSupportedByOutput = highDynamicRangesSupportedByOutput;
         // Initialize the GL context on the GL thread
         mExecutor.execute(() -> mNativeContext = initContext());
     }
@@ -218,7 +218,7 @@
 
     private boolean outputSupportsDynamicRange(DynamicRange newDynamicRange) {
         if (!Objects.equals(newDynamicRange, DynamicRange.SDR)) {
-            return mHdrEncodingsSupportedByOutput.contains(newDynamicRange.getEncoding());
+            return mHighDynamicRangesSupportedByOutput.contains(newDynamicRange);
         }
         // SDR is always supported
         return true;
diff --git a/camera/integration-tests/coretestapp/src/main/res/layout/activity_camera_xmain.xml b/camera/integration-tests/coretestapp/src/main/res/layout/activity_camera_xmain.xml
index 81eb97a..27bbfa0 100644
--- a/camera/integration-tests/coretestapp/src/main/res/layout/activity_camera_xmain.xml
+++ b/camera/integration-tests/coretestapp/src/main/res/layout/activity_camera_xmain.xml
@@ -323,7 +323,7 @@
         app:layout_constraintTop_toBottomOf="@id/direction_toggle" />
 
     <Button
-        android:id="@+id/video_quality"
+        android:id="@+id/dynamic_range"
         android:layout_width="46dp"
         android:layout_height="wrap_content"
         android:layout_marginTop="1dp"
@@ -338,7 +338,7 @@
         />
 
     <Button
-        android:id="@+id/video_dynamic_range"
+        android:id="@+id/video_quality"
         android:layout_width="46dp"
         android:layout_height="wrap_content"
         android:layout_marginTop="1dp"
@@ -348,7 +348,7 @@
         android:textColor="#EEEEEE"
         android:textSize="14dp"
         android:visibility="invisible"
-        app:layout_constraintTop_toBottomOf="@id/video_persistent"
+        app:layout_constraintTop_toBottomOf="@id/dynamic_range"
         app:layout_constraintRight_toRightOf="parent"
         />
 
diff --git a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/BindUnbindUseCasesStressTest.kt b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/BindUnbindUseCasesStressTest.kt
index 421a844..88a6699 100644
--- a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/BindUnbindUseCasesStressTest.kt
+++ b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/BindUnbindUseCasesStressTest.kt
@@ -158,6 +158,8 @@
     @Test
     fun bindUnbindUseCases_checkPreviewInEachTime_withPreviewImageCaptureImageAnalysis():
         Unit = runBlocking {
+        assumeTrue(extensionsManager.isImageAnalysisSupported(
+            baseCameraSelector, config.extensionMode))
         val imageAnalysis = createImageAnalysis()
         assumeTrue(camera.isUseCasesCombinationSupported(preview, imageCapture, imageAnalysis))
         bindUseCases_checkOutput_thenUnbindAll_repeatedly(
@@ -171,6 +173,8 @@
     @Test
     fun bindUnbindUseCases_checkImageCaptureInEachTime_withPreviewImageCaptureImageAnalysis():
         Unit = runBlocking {
+        assumeTrue(extensionsManager.isImageAnalysisSupported(
+            baseCameraSelector, config.extensionMode))
         val imageAnalysis = createImageAnalysis()
         assumeTrue(camera.isUseCasesCombinationSupported(preview, imageCapture, imageAnalysis))
         bindUseCases_checkOutput_thenUnbindAll_repeatedly(
@@ -184,6 +188,8 @@
     @Test
     fun bindUnbindUseCases_checkImageAnalysisInEachTime_withPreviewImageCaptureImageAnalysis():
         Unit = runBlocking {
+        assumeTrue(extensionsManager.isImageAnalysisSupported(
+            baseCameraSelector, config.extensionMode))
         val imageAnalysis = createImageAnalysis()
         assumeTrue(camera.isUseCasesCombinationSupported(preview, imageCapture, imageAnalysis))
         bindUseCases_checkOutput_thenUnbindAll_repeatedly(
@@ -286,6 +292,8 @@
     @Test
     fun checkPreview_afterBindUnbindUseCasesRepeatedly_withPreviewImageCaptureImageAnalysis():
         Unit = runBlocking {
+        assumeTrue(extensionsManager.isImageAnalysisSupported(
+            baseCameraSelector, config.extensionMode))
         val imageAnalysis = createImageAnalysis()
         assumeTrue(camera.isUseCasesCombinationSupported(preview, imageCapture, imageAnalysis))
         bindUseCases_unbindAll_repeatedly_thenCheckOutput(
@@ -299,6 +307,8 @@
     @Test
     fun checkImageCapture_afterBindUnbindUseCasesRepeatedly_withPreviewImageCaptureImageAnalysis():
         Unit = runBlocking {
+        assumeTrue(extensionsManager.isImageAnalysisSupported(
+            baseCameraSelector, config.extensionMode))
         val imageAnalysis = createImageAnalysis()
         assumeTrue(camera.isUseCasesCombinationSupported(preview, imageCapture, imageAnalysis))
         bindUseCases_unbindAll_repeatedly_thenCheckOutput(
@@ -312,6 +322,8 @@
     @Test
     fun checkImageAnalysis_afterBindUnbindUseCasesRepeatedly_withPreviewImageCaptureImageAnalysis():
         Unit = runBlocking {
+        assumeTrue(extensionsManager.isImageAnalysisSupported(
+            baseCameraSelector, config.extensionMode))
         val imageAnalysis = createImageAnalysis()
         assumeTrue(camera.isUseCasesCombinationSupported(preview, imageCapture, imageAnalysis))
         bindUseCases_unbindAll_repeatedly_thenCheckOutput(
diff --git a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
index c06e615..859569e 100644
--- a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
+++ b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
@@ -665,20 +665,20 @@
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
         Intent intent = new Intent();
         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
-        switch (item.getItemId()) {
-            case R.id.menu_camera2_extensions:
-                if (Build.VERSION.SDK_INT >= 31) {
-                    mCameraProvider.unbindAll();
-                    intent.setClassName(this, Camera2ExtensionsActivity.class.getName());
-                    startActivity(intent);
-                    finish();
-                }
-                return true;
-            case R.id.menu_validation_tool:
-                intent.setClassName(this, CameraValidationResultActivity.class.getName());
+        int itemId = item.getItemId();
+        if (itemId == R.id.menu_camera2_extensions) {
+            if (Build.VERSION.SDK_INT >= 31) {
+                mCameraProvider.unbindAll();
+                intent.setClassName(this, Camera2ExtensionsActivity.class.getName());
                 startActivity(intent);
                 finish();
-                return true;
+            }
+            return true;
+        } else if (itemId == R.id.menu_validation_tool) {
+            intent.setClassName(this, CameraValidationResultActivity.class.getName());
+            startActivity(intent);
+            finish();
+            return true;
         }
 
         return super.onOptionsItemSelected(item);
diff --git a/camera/integration-tests/uiwidgetstestapp/build.gradle b/camera/integration-tests/uiwidgetstestapp/build.gradle
index d7508be..27c73ed 100644
--- a/camera/integration-tests/uiwidgetstestapp/build.gradle
+++ b/camera/integration-tests/uiwidgetstestapp/build.gradle
@@ -89,7 +89,7 @@
 
     // Compose
     implementation 'androidx.activity:activity-compose:1.4.0'
-    implementation 'androidx.compose.material:material:1.4.0'
+    implementation project(':compose:material:material')
     implementation 'androidx.compose.animation:animation:1.4.0'
     implementation 'androidx.compose.runtime:runtime:1.4.0'
     implementation 'androidx.compose.ui:ui-tooling:1.4.0'
@@ -122,7 +122,16 @@
 
     // Testing for Compose
     // Test rules and transitive dependencies:
-    androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.1.1")
+    androidTestImplementation(project(":compose:ui:ui-test-junit4"))
+    androidTestImplementation(project(":compose:runtime:runtime"))
+    androidTestImplementation(project(":compose:ui:ui"))
+    androidTestImplementation(project(":compose:runtime:runtime-saveable"))
+    androidTestImplementation(project(":compose:ui:ui-geometry"))
+    androidTestImplementation(project(":compose:ui:ui-util"))
+    androidTestImplementation(project(":compose:ui:ui-graphics"))
+    androidTestImplementation(project(":compose:ui:ui-unit"))
+    androidTestImplementation(project(":compose:ui:ui-text"))
+    androidTestImplementation(project(":collection:collection"))
     // Needed for createComposeRule, but not createAndroidComposeRule:
-    debugImplementation("androidx.compose.ui:ui-test-manifest:1.1.1")
+    debugImplementation(project(":compose:ui:ui-test-manifest"))
 }
diff --git a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/components/TabRow.kt b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/components/TabRow.kt
index 0cae0bb..5a3786e 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/components/TabRow.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/components/TabRow.kt
@@ -34,7 +34,7 @@
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Surface
 import androidx.compose.material.Text
-import androidx.compose.material.ripple.rememberRipple
+import androidx.compose.material.ripple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
@@ -117,7 +117,7 @@
                 onClick = onSelected,
                 role = Role.Tab,
                 interactionSource = remember { MutableInteractionSource() },
-                indication = rememberRipple(
+                indication = ripple(
                     bounded = false,
                     radius = Dp.Unspecified,
                     color = Color.Unspecified
diff --git a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreenState.kt b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreenState.kt
index 72fdd51e..c3178fe 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreenState.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreenState.kt
@@ -45,6 +45,8 @@
 import androidx.compose.material.icons.sharp.FlashOn
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.listSaver
@@ -75,7 +77,7 @@
     initialLensFacing: Int = DEFAULT_LENS_FACING,
     initialFlashMode: Int = DEFAULT_FLASH_MODE
 ) {
-    var lensFacing by mutableStateOf(initialLensFacing)
+    var lensFacing by mutableIntStateOf(initialLensFacing)
         private set
 
     var hasFlashUnit by mutableStateOf(false)
@@ -84,17 +86,17 @@
     var isCameraReady by mutableStateOf(false)
         private set
 
-    var flashMode: Int by mutableStateOf(getValidInitialFlashMode(initialFlashMode))
+    var flashMode: Int by mutableIntStateOf(getValidInitialFlashMode(initialFlashMode))
         private set
 
     var flashModeIcon: ImageVector = getFlashModeImageVector()
         private set
         get() = getFlashModeImageVector()
 
-    var linearZoom by mutableStateOf(0f)
+    var linearZoom by mutableFloatStateOf(0f)
         private set
 
-    var zoomRatio by mutableStateOf(1f)
+    var zoomRatio by mutableFloatStateOf(1f)
         private set
 
     var qrCodeBoundingBox by mutableStateOf<Rect?>(null)
diff --git a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreenState.kt b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreenState.kt
index e5df82b..29346cc 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreenState.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreenState.kt
@@ -41,6 +41,8 @@
 import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_SOURCE_INACTIVE
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.listSaver
@@ -61,16 +63,16 @@
 class VideoCaptureScreenState(
     initialLensFacing: Int = DEFAULT_LENS_FACING
 ) {
-    var lensFacing by mutableStateOf(initialLensFacing)
+    var lensFacing by mutableIntStateOf(initialLensFacing)
         private set
 
     var isCameraReady by mutableStateOf(false)
         private set
 
-    var linearZoom by mutableStateOf(0f)
+    var linearZoom by mutableFloatStateOf(0f)
         private set
 
-    var zoomRatio by mutableStateOf(1f)
+    var zoomRatio by mutableFloatStateOf(1f)
         private set
 
     private var recording: Recording? = null
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/EffectsFragment.kt b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/EffectsFragment.kt
index 1d811a0..ca25ba9 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/EffectsFragment.kt
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/EffectsFragment.kt
@@ -217,6 +217,7 @@
     private fun stopRecording() {
         record.text = "Record"
         recording?.stop()
+        recording = null
     }
 
     private fun getNewVideoOutputMediaStoreOptions(): MediaStoreOutputOptions {
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/MainActivity.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/MainActivity.java
index 35c9e82..3e94241 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/MainActivity.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/MainActivity.java
@@ -169,25 +169,19 @@
     @SuppressLint("NonConstantResourceId")
     @Override
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.preview_view:
-                mFragmentType = FragmentType.PREVIEW_VIEW;
-                break;
-            case R.id.camera_controller:
-                mFragmentType = FragmentType.CAMERA_CONTROLLER;
-                break;
-            case R.id.transform:
-                mFragmentType = FragmentType.TRANSFORM;
-                break;
-            case R.id.compose_ui:
-                mFragmentType = FragmentType.COMPOSE_UI;
-                break;
-            case R.id.mlkit:
-                mFragmentType = FragmentType.MLKIT;
-                break;
-            case R.id.effects:
-                mFragmentType = FragmentType.EFFECTS;
-                break;
+        int itemId = item.getItemId();
+        if (itemId == R.id.preview_view) {
+            mFragmentType = FragmentType.PREVIEW_VIEW;
+        } else if (itemId == R.id.camera_controller) {
+            mFragmentType = FragmentType.CAMERA_CONTROLLER;
+        } else if (itemId == R.id.transform) {
+            mFragmentType = FragmentType.TRANSFORM;
+        } else if (itemId == R.id.compose_ui) {
+            mFragmentType = FragmentType.COMPOSE_UI;
+        } else if (itemId == R.id.mlkit) {
+            mFragmentType = FragmentType.MLKIT;
+        } else if (itemId == R.id.effects) {
+            mFragmentType = FragmentType.EFFECTS;
         }
         startFragment();
         return true;
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt
index 4f5c8ae7..44af50ca 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt
@@ -16,17 +16,23 @@
 
 package androidx.camera.integration.view
 
+import android.annotation.SuppressLint
 import androidx.camera.core.CameraEffect
 
 /**
  * A tone mapping effect for Preview/VideoCapture UseCase.
  */
+@SuppressLint("RestrictedApiAndroidX")
 internal class ToneMappingSurfaceEffect(
     targets: Int = PREVIEW or VIDEO_CAPTURE,
     private val processor: ToneMappingSurfaceProcessor = ToneMappingSurfaceProcessor()
 ) :
     CameraEffect(
-        targets, processor.getGlExecutor(), processor, {}
+        targets,
+        TRANSFORMATION_CAMERA_AND_SURFACE_ROTATION,
+        processor.getGlExecutor(),
+        processor,
+        {}
     ) {
 
     fun release() {
diff --git a/camera/integration-tests/viewtestapp/src/main/res/layout-land/effects_view.xml b/camera/integration-tests/viewtestapp/src/main/res/layout-land/effects_view.xml
index cbf1b36..dbdca03 100644
--- a/camera/integration-tests/viewtestapp/src/main/res/layout-land/effects_view.xml
+++ b/camera/integration-tests/viewtestapp/src/main/res/layout-land/effects_view.xml
@@ -1,12 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?><!--
   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.
@@ -14,13 +11,12 @@
   limitations under the License.
   -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
     <RelativeLayout
-        android:layout_width="match_parent"
+        android:layout_width="0dp"
         android:layout_weight="1"
-        android:layout_height="0dp">
+        android:layout_height="match_parent">
         <androidx.camera.view.PreviewView
             android:id="@+id/preview_view"
             android:layout_width="match_parent"
@@ -51,14 +47,15 @@
         </LinearLayout>
     </RelativeLayout>
     <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
         android:layout_margin="20dp">
         <LinearLayout
             android:orientation="vertical"
-            android:layout_width="0dp"
+            android:layout_width="match_parent"
             android:layout_weight="1"
-            android:layout_height="match_parent">
+            android:layout_height="0dp">
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
@@ -84,9 +81,9 @@
         </LinearLayout>
         <LinearLayout
             android:orientation="vertical"
-            android:layout_width="0dp"
+            android:layout_width="match_parent"
             android:layout_weight="1"
-            android:layout_height="match_parent">
+            android:layout_height="0dp">
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/cardview/cardview/src/main/java/androidx/cardview/widget/CardView.java b/cardview/cardview/src/main/java/androidx/cardview/widget/CardView.java
index 08b5580..b940212 100644
--- a/cardview/cardview/src/main/java/androidx/cardview/widget/CardView.java
+++ b/cardview/cardview/src/main/java/androidx/cardview/widget/CardView.java
@@ -86,8 +86,6 @@
     static {
         if (Build.VERSION.SDK_INT >= 21) {
             IMPL = new CardViewApi21Impl();
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            IMPL = new CardViewApi17Impl();
         } else {
             IMPL = new CardViewBaseImpl();
         }
diff --git a/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewApi17Impl.java b/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewApi17Impl.java
deleted file mode 100644
index 49387fd..0000000
--- a/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewApi17Impl.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2018 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.cardview.widget;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
-
-import androidx.annotation.RequiresApi;
-
-@RequiresApi(17)
-class CardViewApi17Impl extends CardViewBaseImpl {
-
-    @Override
-    public void initStatic() {
-        RoundRectDrawableWithShadow.sRoundRectHelper =
-                new RoundRectDrawableWithShadow.RoundRectHelper() {
-                    @Override
-                    public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius,
-                            Paint paint) {
-                        canvas.drawRoundRect(bounds, cornerRadius, cornerRadius, paint);
-                    }
-                };
-    }
-}
diff --git a/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewBaseImpl.java b/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewBaseImpl.java
index bc6cd5d..c5a8dec 100644
--- a/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewBaseImpl.java
+++ b/cardview/cardview/src/main/java/androidx/cardview/widget/CardViewBaseImpl.java
@@ -17,64 +17,17 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Rect;
-import android.graphics.RectF;
 
 import androidx.annotation.Nullable;
 
 class CardViewBaseImpl implements CardViewImpl {
 
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final RectF mCornerRect = new RectF();
-
     @Override
     public void initStatic() {
-        // Draws a round rect using 7 draw operations. This is faster than using
-        // canvas.drawRoundRect before JBMR1 because API 11-16 used alpha mask textures to draw
-        // shapes.
         RoundRectDrawableWithShadow.sRoundRectHelper =
-                new RoundRectDrawableWithShadow.RoundRectHelper() {
-            @Override
-            public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius,
-                    Paint paint) {
-                final float twoRadius = cornerRadius * 2;
-                final float innerWidth = bounds.width() - twoRadius - 1;
-                final float innerHeight = bounds.height() - twoRadius - 1;
-                if (cornerRadius >= 1f) {
-                    // increment corner radius to account for half pixels.
-                    float roundedCornerRadius = cornerRadius + .5f;
-                    mCornerRect.set(-roundedCornerRadius, -roundedCornerRadius, roundedCornerRadius,
-                            roundedCornerRadius);
-                    int saved = canvas.save();
-                    canvas.translate(bounds.left + roundedCornerRadius,
-                            bounds.top + roundedCornerRadius);
-                    canvas.drawArc(mCornerRect, 180, 90, true, paint);
-                    canvas.translate(innerWidth, 0);
-                    canvas.rotate(90);
-                    canvas.drawArc(mCornerRect, 180, 90, true, paint);
-                    canvas.translate(innerHeight, 0);
-                    canvas.rotate(90);
-                    canvas.drawArc(mCornerRect, 180, 90, true, paint);
-                    canvas.translate(innerWidth, 0);
-                    canvas.rotate(90);
-                    canvas.drawArc(mCornerRect, 180, 90, true, paint);
-                    canvas.restoreToCount(saved);
-                    //draw top and bottom pieces
-                    canvas.drawRect(bounds.left + roundedCornerRadius - 1f, bounds.top,
-                            bounds.right - roundedCornerRadius + 1f,
-                            bounds.top + roundedCornerRadius, paint);
-
-                    canvas.drawRect(bounds.left + roundedCornerRadius - 1f,
-                            bounds.bottom - roundedCornerRadius,
-                            bounds.right - roundedCornerRadius + 1f, bounds.bottom, paint);
-                }
-                // center
-                canvas.drawRect(bounds.left, bounds.top + cornerRadius,
-                        bounds.right, bounds.bottom - cornerRadius , paint);
-            }
-        };
+                (canvas, bounds, cornerRadius, paint) ->
+                        canvas.drawRoundRect(bounds, cornerRadius, cornerRadius, paint);
     }
 
     @Override
diff --git a/collection/collection-ktx/api/1.4.0-beta02.txt b/collection/collection-ktx/api/1.4.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/collection/collection-ktx/api/1.4.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/collection/collection-ktx/api/restricted_1.4.0-beta02.txt b/collection/collection-ktx/api/restricted_1.4.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/collection/collection-ktx/api/restricted_1.4.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/collection/collection/api/1.4.0-beta02.txt b/collection/collection/api/1.4.0-beta02.txt
new file mode 100644
index 0000000..66c91fb
--- /dev/null
+++ b/collection/collection/api/1.4.0-beta02.txt
@@ -0,0 +1,2067 @@
+// Signature format: 4.0
+package androidx.collection {
+
+  public class ArrayMap<K, V> extends androidx.collection.SimpleArrayMap<K,V> implements java.util.Map<K,V> {
+    ctor public ArrayMap();
+    ctor public ArrayMap(androidx.collection.SimpleArrayMap?);
+    ctor public ArrayMap(int);
+    method public boolean containsAll(java.util.Collection<?>);
+    method public boolean containsKey(Object?);
+    method public boolean containsValue(Object?);
+    method public java.util.Set<java.util.Map.Entry<K!,V!>!> entrySet();
+    method public V! get(Object?);
+    method public java.util.Set<K!> keySet();
+    method public void putAll(java.util.Map<? extends K,? extends V>);
+    method public V! remove(Object?);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public java.util.Collection<V!> values();
+  }
+
+  public final class ArrayMapKt {
+    method public static inline <K, V> androidx.collection.ArrayMap<K,V> arrayMapOf();
+    method public static <K, V> androidx.collection.ArrayMap<K,V> arrayMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+  }
+
+  public final class ArraySet<E> implements java.util.Collection<E> kotlin.jvm.internal.markers.KMutableCollection kotlin.jvm.internal.markers.KMutableSet java.util.Set<E> {
+    ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
+    ctor public ArraySet(E![]? array);
+    ctor public ArraySet();
+    ctor public ArraySet(optional int capacity);
+    ctor public ArraySet(java.util.Collection<? extends E>? set);
+    method public boolean add(E element);
+    method public void addAll(androidx.collection.ArraySet<? extends E> array);
+    method public boolean addAll(java.util.Collection<? extends E> elements);
+    method public void clear();
+    method public operator boolean contains(E element);
+    method public boolean containsAll(java.util.Collection<E!> elements);
+    method public void ensureCapacity(int minimumCapacity);
+    method public int getSize();
+    method public int indexOf(Object? key);
+    method public boolean isEmpty();
+    method public java.util.Iterator<E> iterator();
+    method public boolean remove(E element);
+    method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
+    method public boolean removeAll(java.util.Collection<E!> elements);
+    method public E removeAt(int index);
+    method public boolean retainAll(java.util.Collection<E!> elements);
+    method public Object![] toArray();
+    method public <T> T![] toArray(T![] array);
+    method public E valueAt(int index);
+    property public int size;
+  }
+
+  public final class ArraySetKt {
+    method public static inline <T> androidx.collection.ArraySet<T> arraySetOf();
+    method public static <T> androidx.collection.ArraySet<T> arraySetOf(T... values);
+  }
+
+  public final class CircularArray<E> {
+    ctor public CircularArray();
+    ctor public CircularArray(optional int minCapacity);
+    method public void addFirst(E element);
+    method public void addLast(E element);
+    method public void clear();
+    method public operator E get(int index);
+    method public E getFirst();
+    method public E getLast();
+    method public boolean isEmpty();
+    method public E popFirst();
+    method public E popLast();
+    method public void removeFromEnd(int count);
+    method public void removeFromStart(int count);
+    method public int size();
+    property public final E first;
+    property public final E last;
+  }
+
+  public final class CircularIntArray {
+    ctor public CircularIntArray();
+    ctor public CircularIntArray(optional int minCapacity);
+    method public void addFirst(int element);
+    method public void addLast(int element);
+    method public void clear();
+    method public operator int get(int index);
+    method public int getFirst();
+    method public int getLast();
+    method public boolean isEmpty();
+    method public int popFirst();
+    method public int popLast();
+    method public void removeFromEnd(int count);
+    method public void removeFromStart(int count);
+    method public int size();
+    property public final int first;
+    property public final int last;
+  }
+
+  public abstract sealed class FloatFloatMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(float key);
+    method public final int getCapacity();
+    method public final float getOrDefault(float key, float defaultValue);
+    method public final inline float getOrElse(float key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class FloatFloatMapKt {
+    method public static androidx.collection.FloatFloatMap emptyFloatFloatMap();
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf();
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4, float key5, float value5);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf();
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4, float key5, float value5);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FloatFloatPair {
+    ctor public FloatFloatPair(float first, float second);
+    method public inline operator float component1();
+    method public inline operator float component2();
+    method public inline float getFirst();
+    method public inline float getSecond();
+    property public final inline float first;
+    property public final inline float second;
+  }
+
+  public abstract sealed class FloatIntMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(float key);
+    method public final int getCapacity();
+    method public final int getOrDefault(float key, int defaultValue);
+    method public final inline int getOrElse(float key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class FloatIntMapKt {
+    method public static androidx.collection.FloatIntMap emptyFloatIntMap();
+    method public static androidx.collection.FloatIntMap floatIntMapOf();
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4, float key5, int value5);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf();
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4, float key5, int value5);
+  }
+
+  public abstract sealed class FloatList {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float element);
+    method public final boolean containsAll(androidx.collection.FloatList elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final float elementAt(@IntRange(from=0L) int index);
+    method public final inline float elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Float> defaultValue);
+    method public final float first();
+    method public final inline float first(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super java.lang.Float,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super java.lang.Float,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super java.lang.Float,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Float,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(float element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final float last();
+    method public final inline float last(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(float element);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class FloatListKt {
+    method public static androidx.collection.FloatList emptyFloatList();
+    method public static androidx.collection.FloatList floatListOf();
+    method public static androidx.collection.FloatList floatListOf(float element1);
+    method public static androidx.collection.FloatList floatListOf(float element1, float element2);
+    method public static androidx.collection.FloatList floatListOf(float element1, float element2, float element3);
+    method public static androidx.collection.FloatList floatListOf(float... elements);
+    method public static inline androidx.collection.MutableFloatList mutableFloatListOf();
+    method public static androidx.collection.MutableFloatList mutableFloatListOf(float element1);
+    method public static androidx.collection.MutableFloatList mutableFloatListOf(float element1, float element2);
+    method public static androidx.collection.MutableFloatList mutableFloatListOf(float element1, float element2, float element3);
+    method public static inline androidx.collection.MutableFloatList mutableFloatListOf(float... elements);
+  }
+
+  public abstract sealed class FloatLongMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(float key);
+    method public final int getCapacity();
+    method public final long getOrDefault(float key, long defaultValue);
+    method public final inline long getOrElse(float key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class FloatLongMapKt {
+    method public static androidx.collection.FloatLongMap emptyFloatLongMap();
+    method public static androidx.collection.FloatLongMap floatLongMapOf();
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4, float key5, long value5);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf();
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4, float key5, long value5);
+  }
+
+  public abstract sealed class FloatObjectMap<V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(float key);
+    method public final int getCapacity();
+    method public final V getOrDefault(float key, V defaultValue);
+    method public final inline V getOrElse(float key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class FloatObjectMapKt {
+    method public static <V> androidx.collection.FloatObjectMap<V> emptyFloatObjectMap();
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf();
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4, float key5, V value5);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf();
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4, float key5, V value5);
+  }
+
+  public abstract sealed class FloatSet {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline float first();
+    method public final inline float first(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class FloatSetKt {
+    method public static androidx.collection.FloatSet emptyFloatSet();
+    method public static androidx.collection.FloatSet floatSetOf();
+    method public static androidx.collection.FloatSet floatSetOf(float element1);
+    method public static androidx.collection.FloatSet floatSetOf(float element1, float element2);
+    method public static androidx.collection.FloatSet floatSetOf(float element1, float element2, float element3);
+    method public static androidx.collection.FloatSet floatSetOf(float... elements);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf();
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float element1);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float element1, float element2);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float element1, float element2, float element3);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float... elements);
+  }
+
+  public abstract sealed class IntFloatMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(int key);
+    method public final int getCapacity();
+    method public final float getOrDefault(int key, float defaultValue);
+    method public final inline float getOrElse(int key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class IntFloatMapKt {
+    method public static androidx.collection.IntFloatMap emptyIntFloatMap();
+    method public static androidx.collection.IntFloatMap intFloatMapOf();
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4, int key5, float value5);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf();
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4, int key5, float value5);
+  }
+
+  public abstract sealed class IntIntMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(int key);
+    method public final int getCapacity();
+    method public final int getOrDefault(int key, int defaultValue);
+    method public final inline int getOrElse(int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class IntIntMapKt {
+    method public static androidx.collection.IntIntMap emptyIntIntMap();
+    method public static androidx.collection.IntIntMap intIntMapOf();
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4, int key5, int value5);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf();
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4, int key5, int value5);
+  }
+
+  @kotlin.jvm.JvmInline public final value class IntIntPair {
+    ctor public IntIntPair(int first, int second);
+    method public inline operator int component1();
+    method public inline operator int component2();
+    method public int getFirst();
+    method public int getSecond();
+    property public final int first;
+    property public final int second;
+  }
+
+  public abstract sealed class IntList {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int element);
+    method public final boolean containsAll(androidx.collection.IntList elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final int elementAt(@IntRange(from=0L) int index);
+    method public final inline int elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> defaultValue);
+    method public final int first();
+    method public final inline int first(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super java.lang.Integer,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super java.lang.Integer,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Integer,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(int element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final int last();
+    method public final inline int last(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(int element);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class IntListKt {
+    method public static androidx.collection.IntList emptyIntList();
+    method public static androidx.collection.IntList intListOf();
+    method public static androidx.collection.IntList intListOf(int element1);
+    method public static androidx.collection.IntList intListOf(int element1, int element2);
+    method public static androidx.collection.IntList intListOf(int element1, int element2, int element3);
+    method public static androidx.collection.IntList intListOf(int... elements);
+    method public static inline androidx.collection.MutableIntList mutableIntListOf();
+    method public static androidx.collection.MutableIntList mutableIntListOf(int element1);
+    method public static androidx.collection.MutableIntList mutableIntListOf(int element1, int element2);
+    method public static androidx.collection.MutableIntList mutableIntListOf(int element1, int element2, int element3);
+    method public static inline androidx.collection.MutableIntList mutableIntListOf(int... elements);
+  }
+
+  public abstract sealed class IntLongMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(int key);
+    method public final int getCapacity();
+    method public final long getOrDefault(int key, long defaultValue);
+    method public final inline long getOrElse(int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class IntLongMapKt {
+    method public static androidx.collection.IntLongMap emptyIntLongMap();
+    method public static androidx.collection.IntLongMap intLongMapOf();
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4, int key5, long value5);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf();
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4, int key5, long value5);
+  }
+
+  public abstract sealed class IntObjectMap<V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(int key);
+    method public final int getCapacity();
+    method public final V getOrDefault(int key, V defaultValue);
+    method public final inline V getOrElse(int key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class IntObjectMapKt {
+    method public static <V> androidx.collection.IntObjectMap<V> emptyIntObjectMap();
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf();
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4, int key5, V value5);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf();
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4, int key5, V value5);
+  }
+
+  public abstract sealed class IntSet {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline int first();
+    method public final inline int first(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class IntSetKt {
+    method public static androidx.collection.IntSet emptyIntSet();
+    method public static androidx.collection.IntSet intSetOf();
+    method public static androidx.collection.IntSet intSetOf(int element1);
+    method public static androidx.collection.IntSet intSetOf(int element1, int element2);
+    method public static androidx.collection.IntSet intSetOf(int element1, int element2, int element3);
+    method public static androidx.collection.IntSet intSetOf(int... elements);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf();
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int element1);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int element1, int element2);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int element1, int element2, int element3);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int... elements);
+  }
+
+  public abstract sealed class LongFloatMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(long key);
+    method public final int getCapacity();
+    method public final float getOrDefault(long key, float defaultValue);
+    method public final inline float getOrElse(long key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class LongFloatMapKt {
+    method public static androidx.collection.LongFloatMap emptyLongFloatMap();
+    method public static androidx.collection.LongFloatMap longFloatMapOf();
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4, long key5, float value5);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf();
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4, long key5, float value5);
+  }
+
+  public abstract sealed class LongIntMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(long key);
+    method public final int getCapacity();
+    method public final int getOrDefault(long key, int defaultValue);
+    method public final inline int getOrElse(long key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class LongIntMapKt {
+    method public static androidx.collection.LongIntMap emptyLongIntMap();
+    method public static androidx.collection.LongIntMap longIntMapOf();
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4, long key5, int value5);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf();
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4, long key5, int value5);
+  }
+
+  public abstract sealed class LongList {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long element);
+    method public final boolean containsAll(androidx.collection.LongList elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final long elementAt(@IntRange(from=0L) int index);
+    method public final inline long elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Long> defaultValue);
+    method public final long first();
+    method public final inline long first(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super java.lang.Long,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super java.lang.Long,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super java.lang.Long,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Long,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(long element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final long last();
+    method public final inline long last(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(long element);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class LongListKt {
+    method public static androidx.collection.LongList emptyLongList();
+    method public static androidx.collection.LongList longListOf();
+    method public static androidx.collection.LongList longListOf(long element1);
+    method public static androidx.collection.LongList longListOf(long element1, long element2);
+    method public static androidx.collection.LongList longListOf(long element1, long element2, long element3);
+    method public static androidx.collection.LongList longListOf(long... elements);
+    method public static inline androidx.collection.MutableLongList mutableLongListOf();
+    method public static androidx.collection.MutableLongList mutableLongListOf(long element1);
+    method public static androidx.collection.MutableLongList mutableLongListOf(long element1, long element2);
+    method public static androidx.collection.MutableLongList mutableLongListOf(long element1, long element2, long element3);
+    method public static inline androidx.collection.MutableLongList mutableLongListOf(long... elements);
+  }
+
+  public abstract sealed class LongLongMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(long key);
+    method public final int getCapacity();
+    method public final long getOrDefault(long key, long defaultValue);
+    method public final inline long getOrElse(long key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class LongLongMapKt {
+    method public static androidx.collection.LongLongMap emptyLongLongMap();
+    method public static androidx.collection.LongLongMap longLongMapOf();
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4, long key5, long value5);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf();
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4, long key5, long value5);
+  }
+
+  public final class LongLongPair {
+    ctor public LongLongPair(long first, long second);
+    method public inline operator long component1();
+    method public inline operator long component2();
+    method public long getFirst();
+    method public long getSecond();
+    property public final long first;
+    property public final long second;
+  }
+
+  public abstract sealed class LongObjectMap<V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(long key);
+    method public final int getCapacity();
+    method public final V getOrDefault(long key, V defaultValue);
+    method public final inline V getOrElse(long key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class LongObjectMapKt {
+    method public static <V> androidx.collection.LongObjectMap<V> emptyLongObjectMap();
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf();
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4, long key5, V value5);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf();
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4, long key5, V value5);
+  }
+
+  public abstract sealed class LongSet {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline long first();
+    method public final inline long first(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class LongSetKt {
+    method public static androidx.collection.LongSet emptyLongSet();
+    method public static androidx.collection.LongSet longSetOf();
+    method public static androidx.collection.LongSet longSetOf(long element1);
+    method public static androidx.collection.LongSet longSetOf(long element1, long element2);
+    method public static androidx.collection.LongSet longSetOf(long element1, long element2, long element3);
+    method public static androidx.collection.LongSet longSetOf(long... elements);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf();
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long element1);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long element1, long element2);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long element1, long element2, long element3);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long... elements);
+  }
+
+  public class LongSparseArray<E> implements java.lang.Cloneable {
+    ctor public LongSparseArray();
+    ctor public LongSparseArray(optional int initialCapacity);
+    method public void append(long key, E value);
+    method public void clear();
+    method public androidx.collection.LongSparseArray<E> clone();
+    method public boolean containsKey(long key);
+    method public boolean containsValue(E value);
+    method @Deprecated public void delete(long key);
+    method public operator E? get(long key);
+    method public E get(long key, E defaultValue);
+    method public int indexOfKey(long key);
+    method public int indexOfValue(E value);
+    method public boolean isEmpty();
+    method public long keyAt(int index);
+    method public void put(long key, E value);
+    method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
+    method public E? putIfAbsent(long key, E value);
+    method public void remove(long key);
+    method public boolean remove(long key, E value);
+    method public void removeAt(int index);
+    method public E? replace(long key, E value);
+    method public boolean replace(long key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
+    method public int size();
+    method public E valueAt(int index);
+  }
+
+  public final class LongSparseArrayKt {
+    method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
+    method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
+    method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
+    method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
+    method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
+    method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
+    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
+  }
+
+  public class LruCache<K, V> {
+    ctor public LruCache(@IntRange(from=1L, to=kotlin.jvm.internal.LongCompanionObject.MAX_VALUE) int maxSize);
+    method protected V? create(K key);
+    method public final int createCount();
+    method protected void entryRemoved(boolean evicted, K key, V oldValue, V? newValue);
+    method public final void evictAll();
+    method public final int evictionCount();
+    method public final operator V? get(K key);
+    method public final int hitCount();
+    method public final int maxSize();
+    method public final int missCount();
+    method public final V? put(K key, V value);
+    method public final int putCount();
+    method public final V? remove(K key);
+    method public void resize(@IntRange(from=1L, to=kotlin.jvm.internal.LongCompanionObject.MAX_VALUE) int maxSize);
+    method public final int size();
+    method protected int sizeOf(K key, V value);
+    method public final java.util.Map<K,V> snapshot();
+    method public void trimToSize(int maxSize);
+  }
+
+  public final class LruCacheKt {
+    method public static inline <K, V> androidx.collection.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
+  }
+
+  public final class MutableFloatFloatMap extends androidx.collection.FloatFloatMap {
+    ctor public MutableFloatFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(float key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatFloatMap from);
+    method public void put(float key, float value);
+    method public float put(float key, float value, float default);
+    method public void putAll(androidx.collection.FloatFloatMap from);
+    method public void remove(float key);
+    method public boolean remove(float key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public operator void set(float key, float value);
+    method public int trim();
+  }
+
+  public final class MutableFloatIntMap extends androidx.collection.FloatIntMap {
+    ctor public MutableFloatIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(float key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatIntMap from);
+    method public void put(float key, int value);
+    method public int put(float key, int value, int default);
+    method public void putAll(androidx.collection.FloatIntMap from);
+    method public void remove(float key);
+    method public boolean remove(float key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public operator void set(float key, int value);
+    method public int trim();
+  }
+
+  public final class MutableFloatList extends androidx.collection.FloatList {
+    ctor public MutableFloatList(optional int initialCapacity);
+    method public boolean add(float element);
+    method public void add(@IntRange(from=0L) int index, float element);
+    method public boolean addAll(androidx.collection.FloatList elements);
+    method public boolean addAll(float[] elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.FloatList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, float[] elements);
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.FloatList elements);
+    method public inline operator void minusAssign(float element);
+    method public operator void minusAssign(float[] elements);
+    method public operator void plusAssign(androidx.collection.FloatList elements);
+    method public inline operator void plusAssign(float element);
+    method public operator void plusAssign(float[] elements);
+    method public boolean remove(float element);
+    method public boolean removeAll(androidx.collection.FloatList elements);
+    method public boolean removeAll(float[] elements);
+    method public float removeAt(@IntRange(from=0L) int index);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.FloatList elements);
+    method public boolean retainAll(float[] elements);
+    method public operator float set(@IntRange(from=0L) int index, float element);
+    method public void sort();
+    method public void sortDescending();
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableFloatLongMap extends androidx.collection.FloatLongMap {
+    ctor public MutableFloatLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(float key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatLongMap from);
+    method public void put(float key, long value);
+    method public long put(float key, long value, long default);
+    method public void putAll(androidx.collection.FloatLongMap from);
+    method public void remove(float key);
+    method public boolean remove(float key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public operator void set(float key, long value);
+    method public int trim();
+  }
+
+  public final class MutableFloatObjectMap<V> extends androidx.collection.FloatObjectMap<V> {
+    ctor public MutableFloatObjectMap(optional int initialCapacity);
+    method public void clear();
+    method public inline V getOrPut(float key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatObjectMap<V> from);
+    method public V? put(float key, V value);
+    method public void putAll(androidx.collection.FloatObjectMap<V> from);
+    method public V? remove(float key);
+    method public boolean remove(float key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public operator void set(float key, V value);
+    method public int trim();
+  }
+
+  public final class MutableFloatSet extends androidx.collection.FloatSet {
+    ctor public MutableFloatSet(optional int initialCapacity);
+    method public boolean add(float element);
+    method public boolean addAll(androidx.collection.FloatSet elements);
+    method public boolean addAll(float[] elements);
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.FloatSet elements);
+    method public operator void minusAssign(float element);
+    method public operator void minusAssign(float[] elements);
+    method public operator void plusAssign(androidx.collection.FloatSet elements);
+    method public operator void plusAssign(float element);
+    method public operator void plusAssign(float[] elements);
+    method public boolean remove(float element);
+    method public boolean removeAll(androidx.collection.FloatSet elements);
+    method public boolean removeAll(float[] elements);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public final class MutableIntFloatMap extends androidx.collection.IntFloatMap {
+    ctor public MutableIntFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(int key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntFloatMap from);
+    method public void put(int key, float value);
+    method public float put(int key, float value, float default);
+    method public void putAll(androidx.collection.IntFloatMap from);
+    method public void remove(int key);
+    method public boolean remove(int key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public operator void set(int key, float value);
+    method public int trim();
+  }
+
+  public final class MutableIntIntMap extends androidx.collection.IntIntMap {
+    ctor public MutableIntIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntIntMap from);
+    method public void put(int key, int value);
+    method public int put(int key, int value, int default);
+    method public void putAll(androidx.collection.IntIntMap from);
+    method public void remove(int key);
+    method public boolean remove(int key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public operator void set(int key, int value);
+    method public int trim();
+  }
+
+  public final class MutableIntList extends androidx.collection.IntList {
+    ctor public MutableIntList(optional int initialCapacity);
+    method public boolean add(int element);
+    method public void add(@IntRange(from=0L) int index, int element);
+    method public boolean addAll(androidx.collection.IntList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.IntList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, int[] elements);
+    method public boolean addAll(int[] elements);
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.IntList elements);
+    method public inline operator void minusAssign(int element);
+    method public operator void minusAssign(int[] elements);
+    method public operator void plusAssign(androidx.collection.IntList elements);
+    method public inline operator void plusAssign(int element);
+    method public operator void plusAssign(int[] elements);
+    method public boolean remove(int element);
+    method public boolean removeAll(androidx.collection.IntList elements);
+    method public boolean removeAll(int[] elements);
+    method public int removeAt(@IntRange(from=0L) int index);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.IntList elements);
+    method public boolean retainAll(int[] elements);
+    method public operator int set(@IntRange(from=0L) int index, int element);
+    method public void sort();
+    method public void sortDescending();
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableIntLongMap extends androidx.collection.IntLongMap {
+    ctor public MutableIntLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntLongMap from);
+    method public void put(int key, long value);
+    method public long put(int key, long value, long default);
+    method public void putAll(androidx.collection.IntLongMap from);
+    method public void remove(int key);
+    method public boolean remove(int key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public operator void set(int key, long value);
+    method public int trim();
+  }
+
+  public final class MutableIntObjectMap<V> extends androidx.collection.IntObjectMap<V> {
+    ctor public MutableIntObjectMap(optional int initialCapacity);
+    method public void clear();
+    method public inline V getOrPut(int key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntObjectMap<V> from);
+    method public V? put(int key, V value);
+    method public void putAll(androidx.collection.IntObjectMap<V> from);
+    method public V? remove(int key);
+    method public boolean remove(int key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public operator void set(int key, V value);
+    method public int trim();
+  }
+
+  public final class MutableIntSet extends androidx.collection.IntSet {
+    ctor public MutableIntSet(optional int initialCapacity);
+    method public boolean add(int element);
+    method public boolean addAll(androidx.collection.IntSet elements);
+    method public boolean addAll(int[] elements);
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.IntSet elements);
+    method public operator void minusAssign(int element);
+    method public operator void minusAssign(int[] elements);
+    method public operator void plusAssign(androidx.collection.IntSet elements);
+    method public operator void plusAssign(int element);
+    method public operator void plusAssign(int[] elements);
+    method public boolean remove(int element);
+    method public boolean removeAll(androidx.collection.IntSet elements);
+    method public boolean removeAll(int[] elements);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public final class MutableLongFloatMap extends androidx.collection.LongFloatMap {
+    ctor public MutableLongFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(long key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongFloatMap from);
+    method public void put(long key, float value);
+    method public float put(long key, float value, float default);
+    method public void putAll(androidx.collection.LongFloatMap from);
+    method public void remove(long key);
+    method public boolean remove(long key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public operator void set(long key, float value);
+    method public int trim();
+  }
+
+  public final class MutableLongIntMap extends androidx.collection.LongIntMap {
+    ctor public MutableLongIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(long key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongIntMap from);
+    method public void put(long key, int value);
+    method public int put(long key, int value, int default);
+    method public void putAll(androidx.collection.LongIntMap from);
+    method public void remove(long key);
+    method public boolean remove(long key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public operator void set(long key, int value);
+    method public int trim();
+  }
+
+  public final class MutableLongList extends androidx.collection.LongList {
+    ctor public MutableLongList(optional int initialCapacity);
+    method public void add(@IntRange(from=0L) int index, long element);
+    method public boolean add(long element);
+    method public boolean addAll(androidx.collection.LongList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.LongList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, long[] elements);
+    method public boolean addAll(long[] elements);
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.LongList elements);
+    method public inline operator void minusAssign(long element);
+    method public operator void minusAssign(long[] elements);
+    method public operator void plusAssign(androidx.collection.LongList elements);
+    method public inline operator void plusAssign(long element);
+    method public operator void plusAssign(long[] elements);
+    method public boolean remove(long element);
+    method public boolean removeAll(androidx.collection.LongList elements);
+    method public boolean removeAll(long[] elements);
+    method public long removeAt(@IntRange(from=0L) int index);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.LongList elements);
+    method public boolean retainAll(long[] elements);
+    method public operator long set(@IntRange(from=0L) int index, long element);
+    method public void sort();
+    method public void sortDescending();
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableLongLongMap extends androidx.collection.LongLongMap {
+    ctor public MutableLongLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(long key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongLongMap from);
+    method public void put(long key, long value);
+    method public long put(long key, long value, long default);
+    method public void putAll(androidx.collection.LongLongMap from);
+    method public void remove(long key);
+    method public boolean remove(long key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public operator void set(long key, long value);
+    method public int trim();
+  }
+
+  public final class MutableLongObjectMap<V> extends androidx.collection.LongObjectMap<V> {
+    ctor public MutableLongObjectMap(optional int initialCapacity);
+    method public void clear();
+    method public inline V getOrPut(long key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongObjectMap<V> from);
+    method public V? put(long key, V value);
+    method public void putAll(androidx.collection.LongObjectMap<V> from);
+    method public V? remove(long key);
+    method public boolean remove(long key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public operator void set(long key, V value);
+    method public int trim();
+  }
+
+  public final class MutableLongSet extends androidx.collection.LongSet {
+    ctor public MutableLongSet(optional int initialCapacity);
+    method public boolean add(long element);
+    method public boolean addAll(androidx.collection.LongSet elements);
+    method public boolean addAll(long[] elements);
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.LongSet elements);
+    method public operator void minusAssign(long element);
+    method public operator void minusAssign(long[] elements);
+    method public operator void plusAssign(androidx.collection.LongSet elements);
+    method public operator void plusAssign(long element);
+    method public operator void plusAssign(long[] elements);
+    method public boolean remove(long element);
+    method public boolean removeAll(androidx.collection.LongSet elements);
+    method public boolean removeAll(long[] elements);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public final class MutableObjectFloatMap<K> extends androidx.collection.ObjectFloatMap<K> {
+    ctor public MutableObjectFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(K key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ObjectFloatMap<K> from);
+    method public void put(K key, float value);
+    method public float put(K key, float value, float default);
+    method public void putAll(androidx.collection.ObjectFloatMap<K> from);
+    method public void remove(K key);
+    method public boolean remove(K key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public operator void set(K key, float value);
+    method public int trim();
+  }
+
+  public final class MutableObjectIntMap<K> extends androidx.collection.ObjectIntMap<K> {
+    ctor public MutableObjectIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(K key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ObjectIntMap<K> from);
+    method public void put(K key, int value);
+    method public int put(K key, int value, int default);
+    method public void putAll(androidx.collection.ObjectIntMap<K> from);
+    method public void remove(K key);
+    method public boolean remove(K key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public operator void set(K key, int value);
+    method public int trim();
+  }
+
+  public final class MutableObjectList<E> extends androidx.collection.ObjectList<E> {
+    ctor public MutableObjectList(optional int initialCapacity);
+    method public boolean add(E element);
+    method public void add(@IntRange(from=0L) int index, E element);
+    method public boolean addAll(androidx.collection.ObjectList<E> elements);
+    method public boolean addAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean addAll(E![] elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.ObjectList<E> elements);
+    method public boolean addAll(@IntRange(from=0L) int index, E![] elements);
+    method public boolean addAll(@IntRange(from=0L) int index, java.util.Collection<? extends E> elements);
+    method public boolean addAll(Iterable<? extends E> elements);
+    method public boolean addAll(java.util.List<? extends E> elements);
+    method public boolean addAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public java.util.List<E> asList();
+    method public java.util.List<E> asMutableList();
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void minusAssign(androidx.collection.ScatterSet<E> elements);
+    method public inline operator void minusAssign(E element);
+    method public operator void minusAssign(E![] elements);
+    method public operator void minusAssign(Iterable<? extends E> elements);
+    method public operator void minusAssign(java.util.List<? extends E> elements);
+    method public operator void minusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public operator void plusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void plusAssign(androidx.collection.ScatterSet<E> elements);
+    method public inline operator void plusAssign(E element);
+    method public operator void plusAssign(E![] elements);
+    method public operator void plusAssign(Iterable<? extends E> elements);
+    method public operator void plusAssign(java.util.List<? extends E> elements);
+    method public operator void plusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public boolean remove(E element);
+    method public boolean removeAll(androidx.collection.ObjectList<E> elements);
+    method public boolean removeAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean removeAll(E![] elements);
+    method public boolean removeAll(Iterable<? extends E> elements);
+    method public boolean removeAll(java.util.List<? extends E> elements);
+    method public boolean removeAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public E removeAt(@IntRange(from=0L) int index);
+    method public inline void removeIf(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.ObjectList<E> elements);
+    method public boolean retainAll(E![] elements);
+    method public boolean retainAll(Iterable<? extends E> elements);
+    method public boolean retainAll(java.util.Collection<? extends E> elements);
+    method public boolean retainAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public operator E set(@IntRange(from=0L) int index, E element);
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableObjectLongMap<K> extends androidx.collection.ObjectLongMap<K> {
+    ctor public MutableObjectLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(K key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ObjectLongMap<K> from);
+    method public void put(K key, long value);
+    method public long put(K key, long value, long default);
+    method public void putAll(androidx.collection.ObjectLongMap<K> from);
+    method public void remove(K key);
+    method public boolean remove(K key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public operator void set(K key, long value);
+    method public int trim();
+  }
+
+  public final class MutableScatterMap<K, V> extends androidx.collection.ScatterMap<K,V> {
+    ctor public MutableScatterMap(optional int initialCapacity);
+    method public java.util.Map<K,V> asMutableMap();
+    method public void clear();
+    method public inline V compute(K key, kotlin.jvm.functions.Function2<? super K,? super V,? extends V> computeBlock);
+    method public inline V getOrPut(K key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ObjectList<K> keys);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ScatterMap<K,V> from);
+    method public inline operator void plusAssign(Iterable<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public inline operator void plusAssign(java.util.Map<K,? extends V> from);
+    method public inline operator void plusAssign(kotlin.Pair<? extends K,? extends V> pair);
+    method public inline operator void plusAssign(kotlin.Pair<? extends K,? extends V>![] pairs);
+    method public inline operator void plusAssign(kotlin.sequences.Sequence<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public V? put(K key, V value);
+    method public void putAll(androidx.collection.ScatterMap<K,V> from);
+    method public void putAll(Iterable<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public void putAll(java.util.Map<K,? extends V> from);
+    method public void putAll(kotlin.Pair<? extends K,? extends V>![] pairs);
+    method public void putAll(kotlin.sequences.Sequence<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public operator void set(K key, V value);
+    method public int trim();
+  }
+
+  public final class MutableScatterSet<E> extends androidx.collection.ScatterSet<E> {
+    ctor public MutableScatterSet(optional int initialCapacity);
+    method public boolean add(E element);
+    method public boolean addAll(androidx.collection.ObjectList<E> elements);
+    method public boolean addAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean addAll(E![] elements);
+    method public boolean addAll(Iterable<? extends E> elements);
+    method public boolean addAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public java.util.Set<E> asMutableSet();
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void minusAssign(androidx.collection.ScatterSet<E> elements);
+    method public operator void minusAssign(E element);
+    method public operator void minusAssign(E![] elements);
+    method public operator void minusAssign(Iterable<? extends E> elements);
+    method public operator void minusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public operator void plusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void plusAssign(androidx.collection.ScatterSet<E> elements);
+    method public operator void plusAssign(E element);
+    method public operator void plusAssign(E![] elements);
+    method public operator void plusAssign(Iterable<? extends E> elements);
+    method public operator void plusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public boolean remove(E element);
+    method public boolean removeAll(androidx.collection.ObjectList<E> elements);
+    method public boolean removeAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean removeAll(E![] elements);
+    method public boolean removeAll(Iterable<? extends E> elements);
+    method public boolean removeAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public inline void removeIf(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public abstract sealed class ObjectFloatMap<K> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(K key);
+    method public final int getCapacity();
+    method public final float getOrDefault(K key, float defaultValue);
+    method public final inline float getOrElse(K key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class ObjectFloatMapKt {
+    method public static <K> androidx.collection.ObjectFloatMap<K> emptyObjectFloatMap();
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf();
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4, K key5, float value5);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMap();
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4, K key5, float value5);
+  }
+
+  public abstract sealed class ObjectIntMap<K> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(K key);
+    method public final int getCapacity();
+    method public final int getOrDefault(K key, int defaultValue);
+    method public final inline int getOrElse(K key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class ObjectIntMapKt {
+    method public static <K> androidx.collection.ObjectIntMap<K> emptyObjectIntMap();
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf();
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4, K key5, int value5);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMap();
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4, K key5, int value5);
+  }
+
+  public abstract sealed class ObjectList<E> {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public abstract java.util.List<E> asList();
+    method public final operator boolean contains(E element);
+    method public final boolean containsAll(androidx.collection.ObjectList<E> elements);
+    method public final boolean containsAll(E![] elements);
+    method public final boolean containsAll(Iterable<? extends E> elements);
+    method public final boolean containsAll(java.util.List<? extends E> elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final E elementAt(@IntRange(from=0L) int index);
+    method public final inline E elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends E> defaultValue);
+    method public final E first();
+    method public final inline E first(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline E? firstOrNull();
+    method public final inline E? firstOrNull(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super E,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super E,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super E,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super E,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super E,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super E,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super E,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super E,kotlin.Unit> block);
+    method public final operator E get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(E element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, optional kotlin.jvm.functions.Function1<? super E,? extends java.lang.CharSequence>? transform);
+    method public final E last();
+    method public final inline E last(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(E element);
+    method public final inline E? lastOrNull();
+    method public final inline E? lastOrNull(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class ObjectListKt {
+    method public static <E> androidx.collection.ObjectList<E> emptyObjectList();
+    method public static inline <E> androidx.collection.MutableObjectList<E> mutableObjectListOf();
+    method public static <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E element1);
+    method public static <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E element1, E element2);
+    method public static <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E element1, E element2, E element3);
+    method public static inline <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E... elements);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf();
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E element1);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E element1, E element2);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E element1, E element2, E element3);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E... elements);
+  }
+
+  public abstract sealed class ObjectLongMap<K> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(K key);
+    method public final int getCapacity();
+    method public final long getOrDefault(K key, long defaultValue);
+    method public final inline long getOrElse(K key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class ObjectLongMapKt {
+    method public static <K> androidx.collection.ObjectLongMap<K> emptyObjectLongMap();
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf();
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4, K key5, long value5);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMap();
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4, K key5, long value5);
+  }
+
+  public abstract sealed class ScatterMap<K, V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public final java.util.Map<K,V> asMap();
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super V,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(K key);
+    method public final int getCapacity();
+    method public final V getOrDefault(K key, V defaultValue);
+    method public final inline V getOrElse(K key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, optional kotlin.jvm.functions.Function2<? super K,? super V,? extends java.lang.CharSequence>? transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+  }
+
+  public final class ScatterMapKt {
+    method public static <K, V> androidx.collection.ScatterMap<K,V> emptyScatterMap();
+    method public static <K, V> androidx.collection.MutableScatterMap<K,V> mutableScatterMapOf();
+    method public static <K, V> androidx.collection.MutableScatterMap<K,V> mutableScatterMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+  }
+
+  public abstract sealed class ScatterSet<E> {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final java.util.Set<E> asSet();
+    method public final operator boolean contains(E element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline E first();
+    method public final inline E first(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline E? firstOrNull(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super E,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, optional kotlin.jvm.functions.Function1<? super E,? extends java.lang.CharSequence>? transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+  }
+
+  public final class ScatterSetKt {
+    method public static <E> androidx.collection.ScatterSet<E> emptyScatterSet();
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf();
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E element1);
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E element1, E element2);
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E element1, E element2, E element3);
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E... elements);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf();
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E element1);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E element1, E element2);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E element1, E element2, E element3);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E... elements);
+  }
+
+  public class SimpleArrayMap<K, V> {
+    ctor public SimpleArrayMap();
+    ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
+    ctor public SimpleArrayMap(optional int capacity);
+    method public void clear();
+    method public boolean containsKey(K key);
+    method public boolean containsValue(V value);
+    method public void ensureCapacity(int minimumCapacity);
+    method public operator V? get(K key);
+    method public V getOrDefault(Object? key, V defaultValue);
+    method public int indexOfKey(K key);
+    method public boolean isEmpty();
+    method public K keyAt(int index);
+    method public V? put(K key, V value);
+    method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
+    method public V? putIfAbsent(K key, V value);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public V removeAt(int index);
+    method public V? replace(K key, V value);
+    method public boolean replace(K key, V oldValue, V newValue);
+    method public V setValueAt(int index, V value);
+    method public int size();
+    method public V valueAt(int index);
+  }
+
+  public class SparseArrayCompat<E> implements java.lang.Cloneable {
+    ctor public SparseArrayCompat();
+    ctor public SparseArrayCompat(optional int initialCapacity);
+    method public void append(int key, E value);
+    method public void clear();
+    method public androidx.collection.SparseArrayCompat<E> clone();
+    method public boolean containsKey(int key);
+    method public boolean containsValue(E value);
+    method @Deprecated public void delete(int key);
+    method public operator E? get(int key);
+    method public E get(int key, E defaultValue);
+    method public final boolean getIsEmpty();
+    method public int indexOfKey(int key);
+    method public int indexOfValue(E value);
+    method public boolean isEmpty();
+    method public int keyAt(int index);
+    method public void put(int key, E value);
+    method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
+    method public E? putIfAbsent(int key, E value);
+    method public void remove(int key);
+    method public boolean remove(int key, Object? value);
+    method public void removeAt(int index);
+    method public void removeAtRange(int index, int size);
+    method public E? replace(int key, E value);
+    method public boolean replace(int key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
+    method public int size();
+    method public E valueAt(int index);
+    property public final boolean isEmpty;
+  }
+
+  public final class SparseArrayKt {
+    method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
+    method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+    method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
+    method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
+    method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
+    method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
+    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
+  }
+
+}
+
diff --git a/collection/collection/api/restricted_1.4.0-beta01.txt b/collection/collection/api/restricted_1.4.0-beta01.txt
index 2bbe99a..e9e19da 100644
--- a/collection/collection/api/restricted_1.4.0-beta01.txt
+++ b/collection/collection/api/restricted_1.4.0-beta01.txt
@@ -2187,3 +2187,11 @@
 
 }
 
+package androidx.collection.internal {
+
+  public final class PackingHelpers_jvmKt {
+    method @kotlin.PublishedApi internal static inline float floatFromBits(int bits);
+  }
+
+}
+
diff --git a/collection/collection/api/restricted_1.4.0-beta02.txt b/collection/collection/api/restricted_1.4.0-beta02.txt
new file mode 100644
index 0000000..e9e19da
--- /dev/null
+++ b/collection/collection/api/restricted_1.4.0-beta02.txt
@@ -0,0 +1,2197 @@
+// Signature format: 4.0
+package androidx.collection {
+
+  public class ArrayMap<K, V> extends androidx.collection.SimpleArrayMap<K,V> implements java.util.Map<K,V> {
+    ctor public ArrayMap();
+    ctor public ArrayMap(androidx.collection.SimpleArrayMap?);
+    ctor public ArrayMap(int);
+    method public boolean containsAll(java.util.Collection<?>);
+    method public boolean containsKey(Object?);
+    method public boolean containsValue(Object?);
+    method public java.util.Set<java.util.Map.Entry<K!,V!>!> entrySet();
+    method public V! get(Object?);
+    method public java.util.Set<K!> keySet();
+    method public void putAll(java.util.Map<? extends K,? extends V>);
+    method public V! remove(Object?);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public java.util.Collection<V!> values();
+  }
+
+  public final class ArrayMapKt {
+    method public static inline <K, V> androidx.collection.ArrayMap<K,V> arrayMapOf();
+    method public static <K, V> androidx.collection.ArrayMap<K,V> arrayMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+  }
+
+  public final class ArraySet<E> implements java.util.Collection<E> kotlin.jvm.internal.markers.KMutableCollection kotlin.jvm.internal.markers.KMutableSet java.util.Set<E> {
+    ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
+    ctor public ArraySet(E![]? array);
+    ctor public ArraySet();
+    ctor public ArraySet(optional int capacity);
+    ctor public ArraySet(java.util.Collection<? extends E>? set);
+    method public boolean add(E element);
+    method public void addAll(androidx.collection.ArraySet<? extends E> array);
+    method public boolean addAll(java.util.Collection<? extends E> elements);
+    method public void clear();
+    method public operator boolean contains(E element);
+    method public boolean containsAll(java.util.Collection<E!> elements);
+    method public void ensureCapacity(int minimumCapacity);
+    method public int getSize();
+    method public int indexOf(Object? key);
+    method public boolean isEmpty();
+    method public java.util.Iterator<E> iterator();
+    method public boolean remove(E element);
+    method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
+    method public boolean removeAll(java.util.Collection<E!> elements);
+    method public E removeAt(int index);
+    method public boolean retainAll(java.util.Collection<E!> elements);
+    method public Object![] toArray();
+    method public <T> T![] toArray(T![] array);
+    method public E valueAt(int index);
+    property public int size;
+  }
+
+  public final class ArraySetKt {
+    method public static inline <T> androidx.collection.ArraySet<T> arraySetOf();
+    method public static <T> androidx.collection.ArraySet<T> arraySetOf(T... values);
+  }
+
+  public final class CircularArray<E> {
+    ctor public CircularArray();
+    ctor public CircularArray(optional int minCapacity);
+    method public void addFirst(E element);
+    method public void addLast(E element);
+    method public void clear();
+    method public operator E get(int index);
+    method public E getFirst();
+    method public E getLast();
+    method public boolean isEmpty();
+    method public E popFirst();
+    method public E popLast();
+    method public void removeFromEnd(int count);
+    method public void removeFromStart(int count);
+    method public int size();
+    property public final E first;
+    property public final E last;
+  }
+
+  public final class CircularIntArray {
+    ctor public CircularIntArray();
+    ctor public CircularIntArray(optional int minCapacity);
+    method public void addFirst(int element);
+    method public void addLast(int element);
+    method public void clear();
+    method public operator int get(int index);
+    method public int getFirst();
+    method public int getLast();
+    method public boolean isEmpty();
+    method public int popFirst();
+    method public int popLast();
+    method public void removeFromEnd(int count);
+    method public void removeFromStart(int count);
+    method public int size();
+    property public final int first;
+    property public final int last;
+  }
+
+  public abstract sealed class FloatFloatMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(float key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(float key);
+    method public final int getCapacity();
+    method public final float getOrDefault(float key, float defaultValue);
+    method public final inline float getOrElse(float key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal float[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal float[] values;
+  }
+
+  public final class FloatFloatMapKt {
+    method public static androidx.collection.FloatFloatMap emptyFloatFloatMap();
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf();
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4);
+    method public static androidx.collection.FloatFloatMap floatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4, float key5, float value5);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf();
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4);
+    method public static androidx.collection.MutableFloatFloatMap mutableFloatFloatMapOf(float key1, float value1, float key2, float value2, float key3, float value3, float key4, float value4, float key5, float value5);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FloatFloatPair {
+    ctor public FloatFloatPair(float first, float second);
+    method public inline operator float component1();
+    method public inline operator float component2();
+    method public inline float getFirst();
+    method public inline float getSecond();
+    property public final inline float first;
+    property public final inline float second;
+  }
+
+  public abstract sealed class FloatIntMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(float key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(float key);
+    method public final int getCapacity();
+    method public final int getOrDefault(float key, int defaultValue);
+    method public final inline int getOrElse(float key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal float[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal int[] values;
+  }
+
+  public final class FloatIntMapKt {
+    method public static androidx.collection.FloatIntMap emptyFloatIntMap();
+    method public static androidx.collection.FloatIntMap floatIntMapOf();
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4);
+    method public static androidx.collection.FloatIntMap floatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4, float key5, int value5);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf();
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4);
+    method public static androidx.collection.MutableFloatIntMap mutableFloatIntMapOf(float key1, int value1, float key2, int value2, float key3, int value3, float key4, int value4, float key5, int value5);
+  }
+
+  public abstract sealed class FloatList {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float element);
+    method public final boolean containsAll(androidx.collection.FloatList elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final float elementAt(@IntRange(from=0L) int index);
+    method public final inline float elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Float> defaultValue);
+    method public final float first();
+    method public final inline float first(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super java.lang.Float,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super java.lang.Float,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super java.lang.Float,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Float,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(float element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final float last();
+    method public final inline float last(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(float element);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal int _size;
+    field @kotlin.PublishedApi internal float[] content;
+  }
+
+  public final class FloatListKt {
+    method public static androidx.collection.FloatList emptyFloatList();
+    method public static androidx.collection.FloatList floatListOf();
+    method public static androidx.collection.FloatList floatListOf(float element1);
+    method public static androidx.collection.FloatList floatListOf(float element1, float element2);
+    method public static androidx.collection.FloatList floatListOf(float element1, float element2, float element3);
+    method public static androidx.collection.FloatList floatListOf(float... elements);
+    method public static inline androidx.collection.MutableFloatList mutableFloatListOf();
+    method public static androidx.collection.MutableFloatList mutableFloatListOf(float element1);
+    method public static androidx.collection.MutableFloatList mutableFloatListOf(float element1, float element2);
+    method public static androidx.collection.MutableFloatList mutableFloatListOf(float element1, float element2, float element3);
+    method public static inline androidx.collection.MutableFloatList mutableFloatListOf(float... elements);
+  }
+
+  public abstract sealed class FloatLongMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(float key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(float key);
+    method public final int getCapacity();
+    method public final long getOrDefault(float key, long defaultValue);
+    method public final inline long getOrElse(float key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal float[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal long[] values;
+  }
+
+  public final class FloatLongMapKt {
+    method public static androidx.collection.FloatLongMap emptyFloatLongMap();
+    method public static androidx.collection.FloatLongMap floatLongMapOf();
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4);
+    method public static androidx.collection.FloatLongMap floatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4, float key5, long value5);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf();
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4);
+    method public static androidx.collection.MutableFloatLongMap mutableFloatLongMapOf(float key1, long value1, float key2, long value2, float key3, long value3, float key4, long value4, float key5, long value5);
+  }
+
+  public abstract sealed class FloatObjectMap<V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float key);
+    method public final boolean containsKey(float key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(float key);
+    method public final int getCapacity();
+    method public final V getOrDefault(float key, V defaultValue);
+    method public final inline V getOrElse(float key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal float[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal Object![] values;
+  }
+
+  public final class FloatObjectMapKt {
+    method public static <V> androidx.collection.FloatObjectMap<V> emptyFloatObjectMap();
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf();
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4);
+    method public static <V> androidx.collection.FloatObjectMap<V> floatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4, float key5, V value5);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf();
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4);
+    method public static <V> androidx.collection.MutableFloatObjectMap<V> mutableFloatObjectMapOf(float key1, V value1, float key2, V value2, float key3, V value3, float key4, V value4, float key5, V value5);
+  }
+
+  public abstract sealed class FloatSet {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(float element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline float first();
+    method public final inline float first(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndex(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal float[] elements;
+    field @kotlin.PublishedApi internal long[] metadata;
+  }
+
+  public final class FloatSetKt {
+    method public static androidx.collection.FloatSet emptyFloatSet();
+    method public static androidx.collection.FloatSet floatSetOf();
+    method public static androidx.collection.FloatSet floatSetOf(float element1);
+    method public static androidx.collection.FloatSet floatSetOf(float element1, float element2);
+    method public static androidx.collection.FloatSet floatSetOf(float element1, float element2, float element3);
+    method public static androidx.collection.FloatSet floatSetOf(float... elements);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf();
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float element1);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float element1, float element2);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float element1, float element2, float element3);
+    method public static androidx.collection.MutableFloatSet mutableFloatSetOf(float... elements);
+  }
+
+  public abstract sealed class IntFloatMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(int key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(int key);
+    method public final int getCapacity();
+    method public final float getOrDefault(int key, float defaultValue);
+    method public final inline float getOrElse(int key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal int[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal float[] values;
+  }
+
+  public final class IntFloatMapKt {
+    method public static androidx.collection.IntFloatMap emptyIntFloatMap();
+    method public static androidx.collection.IntFloatMap intFloatMapOf();
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4);
+    method public static androidx.collection.IntFloatMap intFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4, int key5, float value5);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf();
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4);
+    method public static androidx.collection.MutableIntFloatMap mutableIntFloatMapOf(int key1, float value1, int key2, float value2, int key3, float value3, int key4, float value4, int key5, float value5);
+  }
+
+  public abstract sealed class IntIntMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(int key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(int key);
+    method public final int getCapacity();
+    method public final int getOrDefault(int key, int defaultValue);
+    method public final inline int getOrElse(int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal int[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal int[] values;
+  }
+
+  public final class IntIntMapKt {
+    method public static androidx.collection.IntIntMap emptyIntIntMap();
+    method public static androidx.collection.IntIntMap intIntMapOf();
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4);
+    method public static androidx.collection.IntIntMap intIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4, int key5, int value5);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf();
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4);
+    method public static androidx.collection.MutableIntIntMap mutableIntIntMapOf(int key1, int value1, int key2, int value2, int key3, int value3, int key4, int value4, int key5, int value5);
+  }
+
+  @kotlin.jvm.JvmInline public final value class IntIntPair {
+    ctor public IntIntPair(int first, int second);
+    method public inline operator int component1();
+    method public inline operator int component2();
+    method public int getFirst();
+    method public int getSecond();
+    property public final int first;
+    property public final int second;
+  }
+
+  public abstract sealed class IntList {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int element);
+    method public final boolean containsAll(androidx.collection.IntList elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final int elementAt(@IntRange(from=0L) int index);
+    method public final inline int elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> defaultValue);
+    method public final int first();
+    method public final inline int first(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super java.lang.Integer,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super java.lang.Integer,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Integer,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(int element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final int last();
+    method public final inline int last(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(int element);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal int _size;
+    field @kotlin.PublishedApi internal int[] content;
+  }
+
+  public final class IntListKt {
+    method public static androidx.collection.IntList emptyIntList();
+    method public static androidx.collection.IntList intListOf();
+    method public static androidx.collection.IntList intListOf(int element1);
+    method public static androidx.collection.IntList intListOf(int element1, int element2);
+    method public static androidx.collection.IntList intListOf(int element1, int element2, int element3);
+    method public static androidx.collection.IntList intListOf(int... elements);
+    method public static inline androidx.collection.MutableIntList mutableIntListOf();
+    method public static androidx.collection.MutableIntList mutableIntListOf(int element1);
+    method public static androidx.collection.MutableIntList mutableIntListOf(int element1, int element2);
+    method public static androidx.collection.MutableIntList mutableIntListOf(int element1, int element2, int element3);
+    method public static inline androidx.collection.MutableIntList mutableIntListOf(int... elements);
+  }
+
+  public abstract sealed class IntLongMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(int key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(int key);
+    method public final int getCapacity();
+    method public final long getOrDefault(int key, long defaultValue);
+    method public final inline long getOrElse(int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal int[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal long[] values;
+  }
+
+  public final class IntLongMapKt {
+    method public static androidx.collection.IntLongMap emptyIntLongMap();
+    method public static androidx.collection.IntLongMap intLongMapOf();
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4);
+    method public static androidx.collection.IntLongMap intLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4, int key5, long value5);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf();
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4);
+    method public static androidx.collection.MutableIntLongMap mutableIntLongMapOf(int key1, long value1, int key2, long value2, int key3, long value3, int key4, long value4, int key5, long value5);
+  }
+
+  public abstract sealed class IntObjectMap<V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int key);
+    method public final boolean containsKey(int key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(int key);
+    method public final int getCapacity();
+    method public final V getOrDefault(int key, V defaultValue);
+    method public final inline V getOrElse(int key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal int[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal Object![] values;
+  }
+
+  public final class IntObjectMapKt {
+    method public static <V> androidx.collection.IntObjectMap<V> emptyIntObjectMap();
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf();
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4);
+    method public static <V> androidx.collection.IntObjectMap<V> intObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4, int key5, V value5);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf();
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4);
+    method public static <V> androidx.collection.MutableIntObjectMap<V> mutableIntObjectMapOf(int key1, V value1, int key2, V value2, int key3, V value3, int key4, V value4, int key5, V value5);
+  }
+
+  public abstract sealed class IntSet {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(int element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline int first();
+    method public final inline int first(kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndex(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal int[] elements;
+    field @kotlin.PublishedApi internal long[] metadata;
+  }
+
+  public final class IntSetKt {
+    method public static androidx.collection.IntSet emptyIntSet();
+    method public static androidx.collection.IntSet intSetOf();
+    method public static androidx.collection.IntSet intSetOf(int element1);
+    method public static androidx.collection.IntSet intSetOf(int element1, int element2);
+    method public static androidx.collection.IntSet intSetOf(int element1, int element2, int element3);
+    method public static androidx.collection.IntSet intSetOf(int... elements);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf();
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int element1);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int element1, int element2);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int element1, int element2, int element3);
+    method public static androidx.collection.MutableIntSet mutableIntSetOf(int... elements);
+  }
+
+  public abstract sealed class LongFloatMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(long key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(long key);
+    method public final int getCapacity();
+    method public final float getOrDefault(long key, float defaultValue);
+    method public final inline float getOrElse(long key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal long[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal float[] values;
+  }
+
+  public final class LongFloatMapKt {
+    method public static androidx.collection.LongFloatMap emptyLongFloatMap();
+    method public static androidx.collection.LongFloatMap longFloatMapOf();
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4);
+    method public static androidx.collection.LongFloatMap longFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4, long key5, float value5);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf();
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4);
+    method public static androidx.collection.MutableLongFloatMap mutableLongFloatMapOf(long key1, float value1, long key2, float value2, long key3, float value3, long key4, float value4, long key5, float value5);
+  }
+
+  public abstract sealed class LongIntMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(long key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(long key);
+    method public final int getCapacity();
+    method public final int getOrDefault(long key, int defaultValue);
+    method public final inline int getOrElse(long key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal long[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal int[] values;
+  }
+
+  public final class LongIntMapKt {
+    method public static androidx.collection.LongIntMap emptyLongIntMap();
+    method public static androidx.collection.LongIntMap longIntMapOf();
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4);
+    method public static androidx.collection.LongIntMap longIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4, long key5, int value5);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf();
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4);
+    method public static androidx.collection.MutableLongIntMap mutableLongIntMapOf(long key1, int value1, long key2, int value2, long key3, int value3, long key4, int value4, long key5, int value5);
+  }
+
+  public abstract sealed class LongList {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long element);
+    method public final boolean containsAll(androidx.collection.LongList elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final long elementAt(@IntRange(from=0L) int index);
+    method public final inline long elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Long> defaultValue);
+    method public final long first();
+    method public final inline long first(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super java.lang.Long,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super java.lang.Long,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super java.lang.Long,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Long,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(long element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final long last();
+    method public final inline long last(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(long element);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal int _size;
+    field @kotlin.PublishedApi internal long[] content;
+  }
+
+  public final class LongListKt {
+    method public static androidx.collection.LongList emptyLongList();
+    method public static androidx.collection.LongList longListOf();
+    method public static androidx.collection.LongList longListOf(long element1);
+    method public static androidx.collection.LongList longListOf(long element1, long element2);
+    method public static androidx.collection.LongList longListOf(long element1, long element2, long element3);
+    method public static androidx.collection.LongList longListOf(long... elements);
+    method public static inline androidx.collection.MutableLongList mutableLongListOf();
+    method public static androidx.collection.MutableLongList mutableLongListOf(long element1);
+    method public static androidx.collection.MutableLongList mutableLongListOf(long element1, long element2);
+    method public static androidx.collection.MutableLongList mutableLongListOf(long element1, long element2, long element3);
+    method public static inline androidx.collection.MutableLongList mutableLongListOf(long... elements);
+  }
+
+  public abstract sealed class LongLongMap {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(long key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(long key);
+    method public final int getCapacity();
+    method public final long getOrDefault(long key, long defaultValue);
+    method public final inline long getOrElse(long key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal long[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal long[] values;
+  }
+
+  public final class LongLongMapKt {
+    method public static androidx.collection.LongLongMap emptyLongLongMap();
+    method public static androidx.collection.LongLongMap longLongMapOf();
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4);
+    method public static androidx.collection.LongLongMap longLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4, long key5, long value5);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf();
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4);
+    method public static androidx.collection.MutableLongLongMap mutableLongLongMapOf(long key1, long value1, long key2, long value2, long key3, long value3, long key4, long value4, long key5, long value5);
+  }
+
+  public final class LongLongPair {
+    ctor public LongLongPair(long first, long second);
+    method public inline operator long component1();
+    method public inline operator long component2();
+    method public long getFirst();
+    method public long getSecond();
+    property public final long first;
+    property public final long second;
+  }
+
+  public abstract sealed class LongObjectMap<V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long key);
+    method public final boolean containsKey(long key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(long key);
+    method public final int getCapacity();
+    method public final V getOrDefault(long key, V defaultValue);
+    method public final inline V getOrElse(long key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal long[] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal Object![] values;
+  }
+
+  public final class LongObjectMapKt {
+    method public static <V> androidx.collection.LongObjectMap<V> emptyLongObjectMap();
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf();
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4);
+    method public static <V> androidx.collection.LongObjectMap<V> longObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4, long key5, V value5);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf();
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4);
+    method public static <V> androidx.collection.MutableLongObjectMap<V> mutableLongObjectMapOf(long key1, V value1, long key2, V value2, long key3, V value3, long key4, V value4, long key5, V value5);
+  }
+
+  public abstract sealed class LongSet {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(long element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline long first();
+    method public final inline long first(kotlin.jvm.functions.Function1<? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndex(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal long[] elements;
+    field @kotlin.PublishedApi internal long[] metadata;
+  }
+
+  public final class LongSetKt {
+    method public static androidx.collection.LongSet emptyLongSet();
+    method public static androidx.collection.LongSet longSetOf();
+    method public static androidx.collection.LongSet longSetOf(long element1);
+    method public static androidx.collection.LongSet longSetOf(long element1, long element2);
+    method public static androidx.collection.LongSet longSetOf(long element1, long element2, long element3);
+    method public static androidx.collection.LongSet longSetOf(long... elements);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf();
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long element1);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long element1, long element2);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long element1, long element2, long element3);
+    method public static androidx.collection.MutableLongSet mutableLongSetOf(long... elements);
+  }
+
+  public class LongSparseArray<E> implements java.lang.Cloneable {
+    ctor public LongSparseArray();
+    ctor public LongSparseArray(optional int initialCapacity);
+    method public void append(long key, E value);
+    method public void clear();
+    method public androidx.collection.LongSparseArray<E> clone();
+    method public boolean containsKey(long key);
+    method public boolean containsValue(E value);
+    method @Deprecated public void delete(long key);
+    method public operator E? get(long key);
+    method public E get(long key, E defaultValue);
+    method public int indexOfKey(long key);
+    method public int indexOfValue(E value);
+    method public boolean isEmpty();
+    method public long keyAt(int index);
+    method public void put(long key, E value);
+    method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
+    method public E? putIfAbsent(long key, E value);
+    method public void remove(long key);
+    method public boolean remove(long key, E value);
+    method public void removeAt(int index);
+    method public E? replace(long key, E value);
+    method public boolean replace(long key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
+    method public int size();
+    method public E valueAt(int index);
+  }
+
+  public final class LongSparseArrayKt {
+    method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
+    method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
+    method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
+    method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
+    method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
+    method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
+    method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
+    method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
+  }
+
+  public class LruCache<K, V> {
+    ctor public LruCache(@IntRange(from=1L, to=kotlin.jvm.internal.LongCompanionObject.MAX_VALUE) int maxSize);
+    method protected V? create(K key);
+    method public final int createCount();
+    method protected void entryRemoved(boolean evicted, K key, V oldValue, V? newValue);
+    method public final void evictAll();
+    method public final int evictionCount();
+    method public final operator V? get(K key);
+    method public final int hitCount();
+    method public final int maxSize();
+    method public final int missCount();
+    method public final V? put(K key, V value);
+    method public final int putCount();
+    method public final V? remove(K key);
+    method public void resize(@IntRange(from=1L, to=kotlin.jvm.internal.LongCompanionObject.MAX_VALUE) int maxSize);
+    method public final int size();
+    method protected int sizeOf(K key, V value);
+    method public final java.util.Map<K,V> snapshot();
+    method public void trimToSize(int maxSize);
+  }
+
+  public final class LruCacheKt {
+    method public static inline <K, V> androidx.collection.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
+  }
+
+  public final class MutableFloatFloatMap extends androidx.collection.FloatFloatMap {
+    ctor public MutableFloatFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(float key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatFloatMap from);
+    method public void put(float key, float value);
+    method public float put(float key, float value, float default);
+    method public void putAll(androidx.collection.FloatFloatMap from);
+    method public void remove(float key);
+    method public boolean remove(float key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(float key, float value);
+    method public int trim();
+  }
+
+  public final class MutableFloatIntMap extends androidx.collection.FloatIntMap {
+    ctor public MutableFloatIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(float key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatIntMap from);
+    method public void put(float key, int value);
+    method public int put(float key, int value, int default);
+    method public void putAll(androidx.collection.FloatIntMap from);
+    method public void remove(float key);
+    method public boolean remove(float key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(float key, int value);
+    method public int trim();
+  }
+
+  public final class MutableFloatList extends androidx.collection.FloatList {
+    ctor public MutableFloatList(optional int initialCapacity);
+    method public boolean add(float element);
+    method public void add(@IntRange(from=0L) int index, float element);
+    method public boolean addAll(androidx.collection.FloatList elements);
+    method public boolean addAll(float[] elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.FloatList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, float[] elements);
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.FloatList elements);
+    method public inline operator void minusAssign(float element);
+    method public operator void minusAssign(float[] elements);
+    method public operator void plusAssign(androidx.collection.FloatList elements);
+    method public inline operator void plusAssign(float element);
+    method public operator void plusAssign(float[] elements);
+    method public boolean remove(float element);
+    method public boolean removeAll(androidx.collection.FloatList elements);
+    method public boolean removeAll(float[] elements);
+    method public float removeAt(@IntRange(from=0L) int index);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.FloatList elements);
+    method public boolean retainAll(float[] elements);
+    method public operator float set(@IntRange(from=0L) int index, float element);
+    method public void sort();
+    method public void sortDescending();
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableFloatLongMap extends androidx.collection.FloatLongMap {
+    ctor public MutableFloatLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(float key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatLongMap from);
+    method public void put(float key, long value);
+    method public long put(float key, long value, long default);
+    method public void putAll(androidx.collection.FloatLongMap from);
+    method public void remove(float key);
+    method public boolean remove(float key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(float key, long value);
+    method public int trim();
+  }
+
+  public final class MutableFloatObjectMap<V> extends androidx.collection.FloatObjectMap<V> {
+    ctor public MutableFloatObjectMap(optional int initialCapacity);
+    method public void clear();
+    method public inline V getOrPut(float key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.FloatList keys);
+    method public inline operator void minusAssign(androidx.collection.FloatSet keys);
+    method public inline operator void minusAssign(float key);
+    method public inline operator void minusAssign(float[] keys);
+    method public inline operator void plusAssign(androidx.collection.FloatObjectMap<V> from);
+    method public V? put(float key, V value);
+    method public void putAll(androidx.collection.FloatObjectMap<V> from);
+    method public V? remove(float key);
+    method public boolean remove(float key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Float,? super V,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal V? removeValueAt(int index);
+    method public operator void set(float key, V value);
+    method public int trim();
+  }
+
+  public final class MutableFloatSet extends androidx.collection.FloatSet {
+    ctor public MutableFloatSet(optional int initialCapacity);
+    method public boolean add(float element);
+    method public boolean addAll(androidx.collection.FloatSet elements);
+    method public boolean addAll(float[] elements);
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.FloatSet elements);
+    method public operator void minusAssign(float element);
+    method public operator void minusAssign(float[] elements);
+    method public operator void plusAssign(androidx.collection.FloatSet elements);
+    method public operator void plusAssign(float element);
+    method public operator void plusAssign(float[] elements);
+    method public boolean remove(float element);
+    method public boolean removeAll(androidx.collection.FloatSet elements);
+    method public boolean removeAll(float[] elements);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public final class MutableIntFloatMap extends androidx.collection.IntFloatMap {
+    ctor public MutableIntFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(int key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntFloatMap from);
+    method public void put(int key, float value);
+    method public float put(int key, float value, float default);
+    method public void putAll(androidx.collection.IntFloatMap from);
+    method public void remove(int key);
+    method public boolean remove(int key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(int key, float value);
+    method public int trim();
+  }
+
+  public final class MutableIntIntMap extends androidx.collection.IntIntMap {
+    ctor public MutableIntIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntIntMap from);
+    method public void put(int key, int value);
+    method public int put(int key, int value, int default);
+    method public void putAll(androidx.collection.IntIntMap from);
+    method public void remove(int key);
+    method public boolean remove(int key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(int key, int value);
+    method public int trim();
+  }
+
+  public final class MutableIntList extends androidx.collection.IntList {
+    ctor public MutableIntList(optional int initialCapacity);
+    method public boolean add(int element);
+    method public void add(@IntRange(from=0L) int index, int element);
+    method public boolean addAll(androidx.collection.IntList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.IntList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, int[] elements);
+    method public boolean addAll(int[] elements);
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.IntList elements);
+    method public inline operator void minusAssign(int element);
+    method public operator void minusAssign(int[] elements);
+    method public operator void plusAssign(androidx.collection.IntList elements);
+    method public inline operator void plusAssign(int element);
+    method public operator void plusAssign(int[] elements);
+    method public boolean remove(int element);
+    method public boolean removeAll(androidx.collection.IntList elements);
+    method public boolean removeAll(int[] elements);
+    method public int removeAt(@IntRange(from=0L) int index);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.IntList elements);
+    method public boolean retainAll(int[] elements);
+    method public operator int set(@IntRange(from=0L) int index, int element);
+    method public void sort();
+    method public void sortDescending();
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableIntLongMap extends androidx.collection.IntLongMap {
+    ctor public MutableIntLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntLongMap from);
+    method public void put(int key, long value);
+    method public long put(int key, long value, long default);
+    method public void putAll(androidx.collection.IntLongMap from);
+    method public void remove(int key);
+    method public boolean remove(int key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(int key, long value);
+    method public int trim();
+  }
+
+  public final class MutableIntObjectMap<V> extends androidx.collection.IntObjectMap<V> {
+    ctor public MutableIntObjectMap(optional int initialCapacity);
+    method public void clear();
+    method public inline V getOrPut(int key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.IntList keys);
+    method public inline operator void minusAssign(androidx.collection.IntSet keys);
+    method public inline operator void minusAssign(int key);
+    method public inline operator void minusAssign(int[] keys);
+    method public inline operator void plusAssign(androidx.collection.IntObjectMap<V> from);
+    method public V? put(int key, V value);
+    method public void putAll(androidx.collection.IntObjectMap<V> from);
+    method public V? remove(int key);
+    method public boolean remove(int key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super V,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal V? removeValueAt(int index);
+    method public operator void set(int key, V value);
+    method public int trim();
+  }
+
+  public final class MutableIntSet extends androidx.collection.IntSet {
+    ctor public MutableIntSet(optional int initialCapacity);
+    method public boolean add(int element);
+    method public boolean addAll(androidx.collection.IntSet elements);
+    method public boolean addAll(int[] elements);
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.IntSet elements);
+    method public operator void minusAssign(int element);
+    method public operator void minusAssign(int[] elements);
+    method public operator void plusAssign(androidx.collection.IntSet elements);
+    method public operator void plusAssign(int element);
+    method public operator void plusAssign(int[] elements);
+    method public boolean remove(int element);
+    method public boolean removeAll(androidx.collection.IntSet elements);
+    method public boolean removeAll(int[] elements);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public final class MutableLongFloatMap extends androidx.collection.LongFloatMap {
+    ctor public MutableLongFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(long key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongFloatMap from);
+    method public void put(long key, float value);
+    method public float put(long key, float value, float default);
+    method public void putAll(androidx.collection.LongFloatMap from);
+    method public void remove(long key);
+    method public boolean remove(long key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(long key, float value);
+    method public int trim();
+  }
+
+  public final class MutableLongIntMap extends androidx.collection.LongIntMap {
+    ctor public MutableLongIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(long key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongIntMap from);
+    method public void put(long key, int value);
+    method public int put(long key, int value, int default);
+    method public void putAll(androidx.collection.LongIntMap from);
+    method public void remove(long key);
+    method public boolean remove(long key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(long key, int value);
+    method public int trim();
+  }
+
+  public final class MutableLongList extends androidx.collection.LongList {
+    ctor public MutableLongList(optional int initialCapacity);
+    method public void add(@IntRange(from=0L) int index, long element);
+    method public boolean add(long element);
+    method public boolean addAll(androidx.collection.LongList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.LongList elements);
+    method public boolean addAll(@IntRange(from=0L) int index, long[] elements);
+    method public boolean addAll(long[] elements);
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.LongList elements);
+    method public inline operator void minusAssign(long element);
+    method public operator void minusAssign(long[] elements);
+    method public operator void plusAssign(androidx.collection.LongList elements);
+    method public inline operator void plusAssign(long element);
+    method public operator void plusAssign(long[] elements);
+    method public boolean remove(long element);
+    method public boolean removeAll(androidx.collection.LongList elements);
+    method public boolean removeAll(long[] elements);
+    method public long removeAt(@IntRange(from=0L) int index);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.LongList elements);
+    method public boolean retainAll(long[] elements);
+    method public operator long set(@IntRange(from=0L) int index, long element);
+    method public void sort();
+    method public void sortDescending();
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableLongLongMap extends androidx.collection.LongLongMap {
+    ctor public MutableLongLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(long key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongLongMap from);
+    method public void put(long key, long value);
+    method public long put(long key, long value, long default);
+    method public void putAll(androidx.collection.LongLongMap from);
+    method public void remove(long key);
+    method public boolean remove(long key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(long key, long value);
+    method public int trim();
+  }
+
+  public final class MutableLongObjectMap<V> extends androidx.collection.LongObjectMap<V> {
+    ctor public MutableLongObjectMap(optional int initialCapacity);
+    method public void clear();
+    method public inline V getOrPut(long key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.LongList keys);
+    method public inline operator void minusAssign(androidx.collection.LongSet keys);
+    method public inline operator void minusAssign(long key);
+    method public inline operator void minusAssign(long[] keys);
+    method public inline operator void plusAssign(androidx.collection.LongObjectMap<V> from);
+    method public V? put(long key, V value);
+    method public void putAll(androidx.collection.LongObjectMap<V> from);
+    method public V? remove(long key);
+    method public boolean remove(long key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super java.lang.Long,? super V,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal V? removeValueAt(int index);
+    method public operator void set(long key, V value);
+    method public int trim();
+  }
+
+  public final class MutableLongSet extends androidx.collection.LongSet {
+    ctor public MutableLongSet(optional int initialCapacity);
+    method public boolean add(long element);
+    method public boolean addAll(androidx.collection.LongSet elements);
+    method public boolean addAll(long[] elements);
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.LongSet elements);
+    method public operator void minusAssign(long element);
+    method public operator void minusAssign(long[] elements);
+    method public operator void plusAssign(androidx.collection.LongSet elements);
+    method public operator void plusAssign(long element);
+    method public operator void plusAssign(long[] elements);
+    method public boolean remove(long element);
+    method public boolean removeAll(androidx.collection.LongSet elements);
+    method public boolean removeAll(long[] elements);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public final class MutableObjectFloatMap<K> extends androidx.collection.ObjectFloatMap<K> {
+    ctor public MutableObjectFloatMap(optional int initialCapacity);
+    method public void clear();
+    method public inline float getOrPut(K key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ObjectFloatMap<K> from);
+    method public void put(K key, float value);
+    method public float put(K key, float value, float default);
+    method public void putAll(androidx.collection.ObjectFloatMap<K> from);
+    method public void remove(K key);
+    method public boolean remove(K key, float value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(K key, float value);
+    method public int trim();
+  }
+
+  public final class MutableObjectIntMap<K> extends androidx.collection.ObjectIntMap<K> {
+    ctor public MutableObjectIntMap(optional int initialCapacity);
+    method public void clear();
+    method public inline int getOrPut(K key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ObjectIntMap<K> from);
+    method public void put(K key, int value);
+    method public int put(K key, int value, int default);
+    method public void putAll(androidx.collection.ObjectIntMap<K> from);
+    method public void remove(K key);
+    method public boolean remove(K key, int value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(K key, int value);
+    method public int trim();
+  }
+
+  public final class MutableObjectList<E> extends androidx.collection.ObjectList<E> {
+    ctor public MutableObjectList(optional int initialCapacity);
+    method public boolean add(E element);
+    method public void add(@IntRange(from=0L) int index, E element);
+    method public boolean addAll(androidx.collection.ObjectList<E> elements);
+    method public boolean addAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean addAll(E![] elements);
+    method public boolean addAll(@IntRange(from=0L) int index, androidx.collection.ObjectList<E> elements);
+    method public boolean addAll(@IntRange(from=0L) int index, E![] elements);
+    method public boolean addAll(@IntRange(from=0L) int index, java.util.Collection<? extends E> elements);
+    method public boolean addAll(Iterable<? extends E> elements);
+    method public boolean addAll(java.util.List<? extends E> elements);
+    method public boolean addAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public java.util.List<E> asList();
+    method public java.util.List<E> asMutableList();
+    method public void clear();
+    method public void ensureCapacity(int capacity);
+    method public inline int getCapacity();
+    method public operator void minusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void minusAssign(androidx.collection.ScatterSet<E> elements);
+    method public inline operator void minusAssign(E element);
+    method public operator void minusAssign(E![] elements);
+    method public operator void minusAssign(Iterable<? extends E> elements);
+    method public operator void minusAssign(java.util.List<? extends E> elements);
+    method public operator void minusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public operator void plusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void plusAssign(androidx.collection.ScatterSet<E> elements);
+    method public inline operator void plusAssign(E element);
+    method public operator void plusAssign(E![] elements);
+    method public operator void plusAssign(Iterable<? extends E> elements);
+    method public operator void plusAssign(java.util.List<? extends E> elements);
+    method public operator void plusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public boolean remove(E element);
+    method public boolean removeAll(androidx.collection.ObjectList<E> elements);
+    method public boolean removeAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean removeAll(E![] elements);
+    method public boolean removeAll(Iterable<? extends E> elements);
+    method public boolean removeAll(java.util.List<? extends E> elements);
+    method public boolean removeAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public E removeAt(@IntRange(from=0L) int index);
+    method public inline void removeIf(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public void removeRange(@IntRange(from=0L) int start, @IntRange(from=0L) int end);
+    method public boolean retainAll(androidx.collection.ObjectList<E> elements);
+    method public boolean retainAll(E![] elements);
+    method public boolean retainAll(Iterable<? extends E> elements);
+    method public boolean retainAll(java.util.Collection<? extends E> elements);
+    method public boolean retainAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public operator E set(@IntRange(from=0L) int index, E element);
+    method public void trim(optional int minCapacity);
+    property public final inline int capacity;
+  }
+
+  public final class MutableObjectLongMap<K> extends androidx.collection.ObjectLongMap<K> {
+    ctor public MutableObjectLongMap(optional int initialCapacity);
+    method public void clear();
+    method public inline long getOrPut(K key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ObjectLongMap<K> from);
+    method public void put(K key, long value);
+    method public long put(K key, long value, long default);
+    method public void putAll(androidx.collection.ObjectLongMap<K> from);
+    method public void remove(K key);
+    method public boolean remove(K key, long value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal void removeValueAt(int index);
+    method public operator void set(K key, long value);
+    method public int trim();
+  }
+
+  public final class MutableScatterMap<K, V> extends androidx.collection.ScatterMap<K,V> {
+    ctor public MutableScatterMap(optional int initialCapacity);
+    method public java.util.Map<K,V> asMutableMap();
+    method public void clear();
+    method public inline V compute(K key, kotlin.jvm.functions.Function2<? super K,? super V,? extends V> computeBlock);
+    method @kotlin.PublishedApi internal int findInsertIndex(K key);
+    method public inline V getOrPut(K key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public inline operator void minusAssign(androidx.collection.ObjectList<K> keys);
+    method public inline operator void minusAssign(androidx.collection.ScatterSet<K> keys);
+    method public inline operator void minusAssign(Iterable<? extends K> keys);
+    method public inline operator void minusAssign(K key);
+    method public inline operator void minusAssign(K![] keys);
+    method public inline operator void minusAssign(kotlin.sequences.Sequence<? extends K> keys);
+    method public inline operator void plusAssign(androidx.collection.ScatterMap<K,V> from);
+    method public inline operator void plusAssign(Iterable<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public inline operator void plusAssign(java.util.Map<K,? extends V> from);
+    method public inline operator void plusAssign(kotlin.Pair<? extends K,? extends V> pair);
+    method public inline operator void plusAssign(kotlin.Pair<? extends K,? extends V>![] pairs);
+    method public inline operator void plusAssign(kotlin.sequences.Sequence<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public V? put(K key, V value);
+    method public void putAll(androidx.collection.ScatterMap<K,V> from);
+    method public void putAll(Iterable<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public void putAll(java.util.Map<K,? extends V> from);
+    method public void putAll(kotlin.Pair<? extends K,? extends V>![] pairs);
+    method public void putAll(kotlin.sequences.Sequence<? extends kotlin.Pair<? extends K,? extends V>> pairs);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public inline void removeIf(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal V? removeValueAt(int index);
+    method public operator void set(K key, V value);
+    method public int trim();
+  }
+
+  public final class MutableScatterSet<E> extends androidx.collection.ScatterSet<E> {
+    ctor public MutableScatterSet(optional int initialCapacity);
+    method public boolean add(E element);
+    method public boolean addAll(androidx.collection.ObjectList<E> elements);
+    method public boolean addAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean addAll(E![] elements);
+    method public boolean addAll(Iterable<? extends E> elements);
+    method public boolean addAll(kotlin.sequences.Sequence<? extends E> elements);
+    method public java.util.Set<E> asMutableSet();
+    method public void clear();
+    method public operator void minusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void minusAssign(androidx.collection.ScatterSet<E> elements);
+    method public operator void minusAssign(E element);
+    method public operator void minusAssign(E![] elements);
+    method public operator void minusAssign(Iterable<? extends E> elements);
+    method public operator void minusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public operator void plusAssign(androidx.collection.ObjectList<E> elements);
+    method public operator void plusAssign(androidx.collection.ScatterSet<E> elements);
+    method public operator void plusAssign(E element);
+    method public operator void plusAssign(E![] elements);
+    method public operator void plusAssign(Iterable<? extends E> elements);
+    method public operator void plusAssign(kotlin.sequences.Sequence<? extends E> elements);
+    method public boolean remove(E element);
+    method public boolean removeAll(androidx.collection.ObjectList<E> elements);
+    method public boolean removeAll(androidx.collection.ScatterSet<E> elements);
+    method public boolean removeAll(E![] elements);
+    method public boolean removeAll(Iterable<? extends E> elements);
+    method public boolean removeAll(kotlin.sequences.Sequence<? extends E> elements);
+    method @kotlin.PublishedApi internal void removeElementAt(int index);
+    method public inline void removeIf(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method @IntRange(from=0L) public int trim();
+  }
+
+  public abstract sealed class ObjectFloatMap<K> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(float value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(K key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> block);
+    method public final operator float get(K key);
+    method public final int getCapacity();
+    method public final float getOrDefault(K key, float defaultValue);
+    method public final inline float getOrElse(K key, kotlin.jvm.functions.Function0<java.lang.Float> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super K,? super java.lang.Float,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal Object![] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal float[] values;
+  }
+
+  public final class ObjectFloatMapKt {
+    method public static <K> androidx.collection.ObjectFloatMap<K> emptyObjectFloatMap();
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf();
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4);
+    method public static <K> androidx.collection.MutableObjectFloatMap<K> mutableObjectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4, K key5, float value5);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMap();
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4);
+    method public static <K> androidx.collection.ObjectFloatMap<K> objectFloatMapOf(K key1, float value1, K key2, float value2, K key3, float value3, K key4, float value4, K key5, float value5);
+  }
+
+  public abstract sealed class ObjectIntMap<K> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(int value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(K key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final operator int get(K key);
+    method public final int getCapacity();
+    method public final int getOrDefault(K key, int defaultValue);
+    method public final inline int getOrElse(K key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super K,? super java.lang.Integer,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal Object![] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal int[] values;
+  }
+
+  public final class ObjectIntMapKt {
+    method public static <K> androidx.collection.ObjectIntMap<K> emptyObjectIntMap();
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf();
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4);
+    method public static <K> androidx.collection.MutableObjectIntMap<K> mutableObjectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4, K key5, int value5);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMap();
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4);
+    method public static <K> androidx.collection.ObjectIntMap<K> objectIntMapOf(K key1, int value1, K key2, int value2, K key3, int value3, K key4, int value4, K key5, int value5);
+  }
+
+  public abstract sealed class ObjectList<E> {
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public abstract java.util.List<E> asList();
+    method public final operator boolean contains(E element);
+    method public final boolean containsAll(androidx.collection.ObjectList<E> elements);
+    method public final boolean containsAll(E![] elements);
+    method public final boolean containsAll(Iterable<? extends E> elements);
+    method public final boolean containsAll(java.util.List<? extends E> elements);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final E elementAt(@IntRange(from=0L) int index);
+    method public final inline E elementAtOrElse(@IntRange(from=0L) int index, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends E> defaultValue);
+    method public final E first();
+    method public final inline E first(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline E? firstOrNull();
+    method public final inline E? firstOrNull(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super E,? extends R> operation);
+    method public final inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super E,? extends R> operation);
+    method public final inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super E,? super R,? extends R> operation);
+    method public final inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super E,? super R,? extends R> operation);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super E,kotlin.Unit> block);
+    method public final inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super E,kotlin.Unit> block);
+    method public final inline void forEachReversed(kotlin.jvm.functions.Function1<? super E,kotlin.Unit> block);
+    method public final inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super E,kotlin.Unit> block);
+    method public final operator E get(@IntRange(from=0L) int index);
+    method public final inline kotlin.ranges.IntRange getIndices();
+    method @IntRange(from=-1L) public final inline int getLastIndex();
+    method @IntRange(from=0L) public final int getSize();
+    method public final int indexOf(E element);
+    method public final inline int indexOfFirst(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline int indexOfLast(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, optional kotlin.jvm.functions.Function1<? super E,? extends java.lang.CharSequence>? transform);
+    method public final E last();
+    method public final inline E last(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final int lastIndexOf(E element);
+    method public final inline E? lastOrNull();
+    method public final inline E? lastOrNull(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final boolean none();
+    method public final inline boolean reversedAny(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    property public final inline kotlin.ranges.IntRange indices;
+    property @IntRange(from=-1L) public final inline int lastIndex;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal int _size;
+    field @kotlin.PublishedApi internal Object![] content;
+  }
+
+  public final class ObjectListKt {
+    method public static <E> androidx.collection.ObjectList<E> emptyObjectList();
+    method public static inline <E> androidx.collection.MutableObjectList<E> mutableObjectListOf();
+    method public static <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E element1);
+    method public static <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E element1, E element2);
+    method public static <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E element1, E element2, E element3);
+    method public static inline <E> androidx.collection.MutableObjectList<E> mutableObjectListOf(E... elements);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf();
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E element1);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E element1, E element2);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E element1, E element2, E element3);
+    method public static <E> androidx.collection.ObjectList<E> objectListOf(E... elements);
+  }
+
+  public abstract sealed class ObjectLongMap<K> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(long value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,java.lang.Boolean> predicate);
+    method @kotlin.PublishedApi internal final int findKeyIndex(K key);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> block);
+    method public final operator long get(K key);
+    method public final int getCapacity();
+    method public final long getOrDefault(K key, long defaultValue);
+    method public final inline long getOrElse(K key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, optional CharSequence prefix, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(optional CharSequence separator, kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final inline String joinToString(kotlin.jvm.functions.Function2<? super K,? super java.lang.Long,? extends java.lang.CharSequence> transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal Object![] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal long[] values;
+  }
+
+  public final class ObjectLongMapKt {
+    method public static <K> androidx.collection.ObjectLongMap<K> emptyObjectLongMap();
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf();
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4);
+    method public static <K> androidx.collection.MutableObjectLongMap<K> mutableObjectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4, K key5, long value5);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMap();
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4);
+    method public static <K> androidx.collection.ObjectLongMap<K> objectLongMapOf(K key1, long value1, K key2, long value2, K key3, long value3, K key4, long value4, K key5, long value5);
+  }
+
+  public abstract sealed class ScatterMap<K, V> {
+    method public final inline boolean all(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public final java.util.Map<K,V> asMap();
+    method public final operator boolean contains(K key);
+    method public final boolean containsKey(K key);
+    method public final boolean containsValue(V value);
+    method public final int count();
+    method public final inline int count(kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function2<? super K,? super V,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndexed(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method public final inline void forEachKey(kotlin.jvm.functions.Function1<? super K,kotlin.Unit> block);
+    method public final inline void forEachValue(kotlin.jvm.functions.Function1<? super V,kotlin.Unit> block);
+    method public final operator V? get(K key);
+    method public final int getCapacity();
+    method public final V getOrDefault(K key, V defaultValue);
+    method public final inline V getOrElse(K key, kotlin.jvm.functions.Function0<? extends V> defaultValue);
+    method public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, optional kotlin.jvm.functions.Function2<? super K,? super V,? extends java.lang.CharSequence>? transform);
+    method public final boolean none();
+    property public final int capacity;
+    property public final int size;
+    field @kotlin.PublishedApi internal Object![] keys;
+    field @kotlin.PublishedApi internal long[] metadata;
+    field @kotlin.PublishedApi internal Object![] values;
+  }
+
+  public final class ScatterMapKt {
+    method public static <K, V> androidx.collection.ScatterMap<K,V> emptyScatterMap();
+    method @kotlin.PublishedApi internal static inline boolean isFull(long value);
+    method @kotlin.PublishedApi internal static inline int lowestBitSet(long);
+    method @kotlin.PublishedApi internal static inline long maskEmptyOrDeleted(long);
+    method @kotlin.PublishedApi internal static inline long match(long, int m);
+    method public static <K, V> androidx.collection.MutableScatterMap<K,V> mutableScatterMapOf();
+    method public static <K, V> androidx.collection.MutableScatterMap<K,V> mutableScatterMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+    method @kotlin.PublishedApi internal static inline long readRawMetadata(long[] data, int offset);
+    field @kotlin.PublishedApi internal static final long BitmaskLsb = 72340172838076673L; // 0x101010101010101L
+    field @kotlin.PublishedApi internal static final long BitmaskMsb = -9187201950435737472L; // 0x8080808080808080L
+    field @kotlin.PublishedApi internal static final long Sentinel = 255L; // 0xffL
+  }
+
+  public abstract sealed class ScatterSet<E> {
+    method public final inline boolean all(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final boolean any();
+    method public final inline boolean any(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final java.util.Set<E> asSet();
+    method public final operator boolean contains(E element);
+    method @IntRange(from=0L) public final int count();
+    method @IntRange(from=0L) public final inline int count(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline E first();
+    method public final inline E first(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline E? firstOrNull(kotlin.jvm.functions.Function1<? super E,java.lang.Boolean> predicate);
+    method public final inline void forEach(kotlin.jvm.functions.Function1<? super E,kotlin.Unit> block);
+    method @kotlin.PublishedApi internal final inline void forEachIndex(kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> block);
+    method @IntRange(from=0L) public final int getCapacity();
+    method @IntRange(from=0L) public final int getSize();
+    method public final boolean isEmpty();
+    method public final boolean isNotEmpty();
+    method public final String joinToString();
+    method public final String joinToString(optional CharSequence separator);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated);
+    method public final String joinToString(optional CharSequence separator, optional CharSequence prefix, optional CharSequence postfix, optional int limit, optional CharSequence truncated, optional kotlin.jvm.functions.Function1<? super E,? extends java.lang.CharSequence>? transform);
+    method public final boolean none();
+    property @IntRange(from=0L) public final int capacity;
+    property @IntRange(from=0L) public final int size;
+    field @kotlin.PublishedApi internal Object![] elements;
+    field @kotlin.PublishedApi internal long[] metadata;
+  }
+
+  public final class ScatterSetKt {
+    method public static <E> androidx.collection.ScatterSet<E> emptyScatterSet();
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf();
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E element1);
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E element1, E element2);
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E element1, E element2, E element3);
+    method public static <E> androidx.collection.MutableScatterSet<E> mutableScatterSetOf(E... elements);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf();
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E element1);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E element1, E element2);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E element1, E element2, E element3);
+    method public static <E> androidx.collection.ScatterSet<E> scatterSetOf(E... elements);
+  }
+
+  public class SimpleArrayMap<K, V> {
+    ctor public SimpleArrayMap();
+    ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
+    ctor public SimpleArrayMap(optional int capacity);
+    method public void clear();
+    method public boolean containsKey(K key);
+    method public boolean containsValue(V value);
+    method public void ensureCapacity(int minimumCapacity);
+    method public operator V? get(K key);
+    method public V getOrDefault(Object? key, V defaultValue);
+    method public int indexOfKey(K key);
+    method public boolean isEmpty();
+    method public K keyAt(int index);
+    method public V? put(K key, V value);
+    method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
+    method public V? putIfAbsent(K key, V value);
+    method public V? remove(K key);
+    method public boolean remove(K key, V value);
+    method public V removeAt(int index);
+    method public V? replace(K key, V value);
+    method public boolean replace(K key, V oldValue, V newValue);
+    method public V setValueAt(int index, V value);
+    method public int size();
+    method public V valueAt(int index);
+  }
+
+  public class SparseArrayCompat<E> implements java.lang.Cloneable {
+    ctor public SparseArrayCompat();
+    ctor public SparseArrayCompat(optional int initialCapacity);
+    method public void append(int key, E value);
+    method public void clear();
+    method public androidx.collection.SparseArrayCompat<E> clone();
+    method public boolean containsKey(int key);
+    method public boolean containsValue(E value);
+    method @Deprecated public void delete(int key);
+    method public operator E? get(int key);
+    method public E get(int key, E defaultValue);
+    method public final boolean getIsEmpty();
+    method public int indexOfKey(int key);
+    method public int indexOfValue(E value);
+    method public boolean isEmpty();
+    method public int keyAt(int index);
+    method public void put(int key, E value);
+    method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
+    method public E? putIfAbsent(int key, E value);
+    method public void remove(int key);
+    method public boolean remove(int key, Object? value);
+    method public void removeAt(int index);
+    method public void removeAtRange(int index, int size);
+    method public E? replace(int key, E value);
+    method public boolean replace(int key, E oldValue, E newValue);
+    method public void setValueAt(int index, E value);
+    method public int size();
+    method public E valueAt(int index);
+    property public final boolean isEmpty;
+  }
+
+  public final class SparseArrayKt {
+    method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
+    method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+    method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+    method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
+    method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
+    method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
+    method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
+    method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
+    method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
+  }
+
+}
+
+package androidx.collection.internal {
+
+  public final class PackingHelpers_jvmKt {
+    method @kotlin.PublishedApi internal static inline float floatFromBits(int bits);
+  }
+
+}
+
diff --git a/collection/collection/api/restricted_current.ignore b/collection/collection/api/restricted_current.ignore
new file mode 100644
index 0000000..627fb9c
--- /dev/null
+++ b/collection/collection/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+AddedPackage: androidx.collection.internal:
+    Added package androidx.collection.internal
diff --git a/collection/collection/api/restricted_current.txt b/collection/collection/api/restricted_current.txt
index 2bbe99a..e9e19da 100644
--- a/collection/collection/api/restricted_current.txt
+++ b/collection/collection/api/restricted_current.txt
@@ -2187,3 +2187,11 @@
 
 }
 
+package androidx.collection.internal {
+
+  public final class PackingHelpers_jvmKt {
+    method @kotlin.PublishedApi internal static inline float floatFromBits(int bits);
+  }
+
+}
+
diff --git a/collection/collection/src/commonMain/kotlin/androidx/collection/FloatFloatPair.kt b/collection/collection/src/commonMain/kotlin/androidx/collection/FloatFloatPair.kt
index 602efb3..45d5574 100644
--- a/collection/collection/src/commonMain/kotlin/androidx/collection/FloatFloatPair.kt
+++ b/collection/collection/src/commonMain/kotlin/androidx/collection/FloatFloatPair.kt
@@ -17,6 +17,7 @@
 
 package androidx.collection
 
+import androidx.collection.internal.floatFromBits
 import kotlin.jvm.JvmField
 import kotlin.jvm.JvmInline
 
@@ -44,13 +45,13 @@
      * The first value in the pair.
      */
     public inline val first: Float
-        get() = Float.fromBits((packedValue shr 32).toInt())
+        get() = floatFromBits((packedValue shr 32).toInt())
 
     /**
      * The second value in the pair.
      */
     public inline val second: Float
-        get() = Float.fromBits((packedValue and 0xFFFFFFFF).toInt())
+        get() = floatFromBits((packedValue and 0xFFFFFFFF).toInt())
 
     /**
      * Returns the [first] component of the pair. For instance, the first component
@@ -63,7 +64,7 @@
      * ```
      */
     // NOTE: Unpack the value directly because using `first` forces an invokestatic
-    public inline operator fun component1(): Float = Float.fromBits((packedValue shr 32).toInt())
+    public inline operator fun component1(): Float = floatFromBits((packedValue shr 32).toInt())
 
     /**
      * Returns the [second] component of the pair. For instance, the second component
@@ -77,7 +78,7 @@
      */
     // NOTE: Unpack the value directly because using `second` forces an invokestatic
     public inline operator fun component2(): Float =
-        Float.fromBits((packedValue and 0xFFFFFFFF).toInt())
+        floatFromBits((packedValue and 0xFFFFFFFF).toInt())
 
     override fun toString(): String = "($first, $second)"
 }
diff --git a/collection/collection/src/commonMain/kotlin/androidx/collection/internal/PackingHelpers.kt b/collection/collection/src/commonMain/kotlin/androidx/collection/internal/PackingHelpers.kt
new file mode 100644
index 0000000..a8c03d2
--- /dev/null
+++ b/collection/collection/src/commonMain/kotlin/androidx/collection/internal/PackingHelpers.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.collection.internal
+
+// The function below is technically identical to Float.fromBits()
+// However, since it is declared as top- level functions, it does
+// not incur the cost of a static fetch through the Companion class.
+// Using this top-level function, the generated arm64 code after
+// dex2oat is exactly a single `fmov`
+
+/**
+ * Returns the [Float] value corresponding to a given bit representation.
+ */
+@PublishedApi
+internal expect fun floatFromBits(bits: Int): Float
diff --git a/collection/collection/src/jvmMain/java/androidx/collection/internal/PackingHelpers.jvm.kt b/collection/collection/src/jvmMain/java/androidx/collection/internal/PackingHelpers.jvm.kt
new file mode 100644
index 0000000..fecf527
--- /dev/null
+++ b/collection/collection/src/jvmMain/java/androidx/collection/internal/PackingHelpers.jvm.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("NOTHING_TO_INLINE")
+
+package androidx.collection.internal
+
+@PublishedApi
+internal actual inline fun floatFromBits(bits: Int): Float = java.lang.Float.intBitsToFloat(bits)
diff --git a/collection/collection/src/nativeMain/kotlin/androidx/collection/internal/PackingHelpers.native.kt b/collection/collection/src/nativeMain/kotlin/androidx/collection/internal/PackingHelpers.native.kt
new file mode 100644
index 0000000..658d706
--- /dev/null
+++ b/collection/collection/src/nativeMain/kotlin/androidx/collection/internal/PackingHelpers.native.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("NOTHING_TO_INLINE")
+
+package androidx.collection.internal
+
+// Ideally we would just reach for kotlin.fromBits(bits) and bypass the companion
+// object like we do in the JVM modules, but alas...
+@PublishedApi
+internal actual inline fun floatFromBits(bits: Int): Float = Float.fromBits(bits)
diff --git a/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/TransitionDetectorTest.kt b/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/TransitionDetectorTest.kt
index d48f918..7eb3408 100644
--- a/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/TransitionDetectorTest.kt
+++ b/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/TransitionDetectorTest.kt
@@ -43,7 +43,7 @@
     private val TransitionStub = bytecodeStub(
         filename = "Transition.kt",
         filepath = "androidx/compose/animation/core",
-        checksum = 0x313a900e,
+        checksum = 0x7997109d,
         """
             package androidx.compose.animation.core
 
@@ -62,90 +62,92 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3Apc8ln5iXUpSfmVKhl5yfW5BfnKqX
-        mJeZm1iSmZ8HFClKFeIJKUrMK84ECXiXcPFyMafl5wuxhaQWl3iXKDFoMQAA
-        iDN6X1gAAAA=
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0ueST8xLKcrPTKnQS87PLcgvTtVL
+        zMvMTSzJzM8DihSlCvGEFCXmFWeCBLxLuHi5mNPy84XYQlKLS7xLlBi0GAD5
+        +CagWAAAAA==
         """,
         """
         androidx/compose/animation/core/Transition$Segment.class:
-        H4sIAAAAAAAAAJVQW2sTQRT+zuwm2263dltvqbd6A2se3DYUBC0FLQiBVcGU
-        vORpkh3iNLuzsjMpfcxv8R/4JPggwUd/lHh2LQj6ogPznfN95zJnzvcfX74C
-        OMADQk+arCp1dp5MyuJDaVUijS6k06VhpVLJSSWN1TV/OFDTQhkXgAi7h4Nn
-        6ak8k0kuzTR5Oz5VE/f86G+JEP+pBfAJ7UNttDsieLuPhxHaCEK0sELw3Xtt
-        CQfp/0/Gj22ms9Ll2iSvlZOZdJI1UZx5/F+qoUWgGUvnumZ77GX7hEfLRRSK
-        jgiXi1DEDMtFZ7no+isUU0/siZetbx/bIvbq9B53GBC3Q/ffJwzQIQQXYxLW
-        f0eezJj7x2WmCBupNurNvBir6kSOc1a20nIi86GsdM0vxKhvjKqOc2mt4k2t
-        DvTUSDevOBQOynk1Ua90nbf9bm6cLtRQW82FL4wpXTOdxT4Eb7s+/Jt6+Yy3
-        mCUN5zV1P2P1EzsCtxnbjRjgDmP0KwEh1tj62GEMWRPYxg2+d5sqD/caexP3
-        2T7leMQ16yN4fVzqY4MRcQ2bfWzh8ghkcQVXR/At1iyuWVy3CH4CEksXNqoC
-        AAA=
+        H4sIAAAAAAAA/5VRTW/TQBB9u3bixnWpW74SvqGVKDngNqqEBFUlqIRkyYCE
+        q1xy2sSrdBt7jbybqsf8Fv4BJyQOKOLIj0KMTSQkuMDlzbw3M7tvZ7//+PIV
+        wCF2GQZCZ1WpsstoUhYfSiMjoVUhrCo1KZWMTiuhjar5biqnhdTWA2PYO0qf
+        J+fiQkS50NPo3fhcTuyL478lhvBPzYPL0D5SWtljBmfvyTBAG56PFtYYXHum
+        DMNh8v/O6LKtZFbaXOnojbQiE1aQxosLh97LaujUAAY2I/1S1WyfsuyA4fFy
+        Efi8y/3lwuchwXLRXS767hoL2YDv81etbx/bPHTq9gGdkLL6oP6/2/TQY/BW
+        Xhk2fleezoi7J2UmGTYTpeXbeTGW1akY56RsJ+VE5ENRqZqvxCDWWlYnuTBG
+        0ro6qZpqYecVlfy0nFcT+VrVfb33c21VIYfKKBp8qXVpG3cGB+C08tU+6h8g
+        vEssajjQ6n9G5xMlHPcI243o4T5h8KsBPtYpunhA6JPGcQu30cPDZsrBoybe
+        wQ7FZ1QPaGZjBCfGlRibMUJsUYrtGFdxbQRmcB03RnAN1g1uGnQNvJ/VVf1q
+        rwIAAA==
         """,
         """
         androidx/compose/animation/core/Transition.class:
-        H4sIAAAAAAAAAI1RTW8TMRB99m52023apuUr4atAeygRYtuIU6gqQSWkSAtI
-        bJVLTk7WCm52vWjtVD3mt/APOCFxQBFHfhRivFRCgkt9eOP3PG88Hv/89e07
-        gBfYY+gJnVWlyi7jaVl8Ko2MhVaFsKrUpFQyPquENsrxEIzh4DgdJOfiQsS5
-        0LP4/eRcTu3Lk/8lhva/WgifIThWWtkTBu/g6aiFAGGEBpoMvv2oDMOz5Pod
-        0SXbyby0udLxW2lFJqwgjRcXHr2POWgwsDlJl8qxQ9plR3TJarkZ8Q6PVsuI
-        tx00eWe17PnN1bLN+vyQD5j/uvHjc8DbnvP0qUzKqCbCVM4KqS1D//qN7l+Z
-        QnQZNv7qz+dUxz8tM8mwlSgt3y2KiazOxCQnZScppyIfiUo5fiW2hlrL6jQX
-        xkga11qqZlrYRUVHUVouqql8o1xe98NCW1XIkTKKjK+0Lm3dm8EROI3cLXqV
-        +wHC+8TimtPMel+x9oU2HA8Ig1oM8JCw9ScBEdYp+tgljEi7S7kddPGodnl4
-        XMd7eEJxQOct8myM4Q2xOcQWIdoOtofYwY0xmMFN3BqjYbBucNvgjkFo0PkN
-        zab+FKoCAAA=
+        H4sIAAAAAAAA/41RTW/TQBB9u3HsxE1bt3wlfEN7KBHCbcQpVJWgEpIlAxKu
+        cslpE6/Sbew18m6qHvNb+AeckDigiCM/CjE2kZDgUll6M+/tvNnZ8c9f374D
+        eIl9hr7QaVmo9CqcFvmnwshQaJULqwpNSinDs1JooyrugTEcHCfD+EJcijAT
+        ehZ+mFzIqX118r/EEPyreXAY3GOllT1haBw8G3XgwvPRRIvBsefKMDyPrz8R
+        XbITzwubKR2+k1akwgrSeH7ZoPexCtoVgIHNSb9SFTukLD2im1bLLZ93ub9a
+        +jyooMW7q2Xfaa2WARvwQz5kzpvmj88uDxqVZ0BtElZ18xI5y6W2DIPrT7u/
+        Nnm4y7D5V38xpz7OaZFKhu1Yafl+kU9keSYmGSm7cTEV2UiUquJrsRNpLcvT
+        TBgjaWftRM20sIuSjvykWJRT+VZVdb2PC21VLkfKKDK+1rqw9WwGR+C09/Vy
+        qt9A+IBYWHOg2f+K9hdKOB4SurXo4hFh508BfGxQdPCY0CftHtX26HtSuxp4
+        Wsf72KM4pPMOeTbHaETYirAdIcAOpdiNcAM3x2AGt3B7jKbBhsEdg66BZ9D7
+        DXTP2E6vAgAA
         """,
         """
         androidx/compose/animation/core/TransitionKt$animateFloat$1.class:
-        H4sIAAAAAAAAAKVVXW8bRRQ9s3ZsZ7Mljpt+JIUSGtM6dujGIbRQuwGT2mSJ
-        ayocIqE8je2ps/F6ttpdW+EtD/0J/BAKEkUgIT/zo1DvrF03VkPbhJeZO3fu
-        uffMnTO7//z7598ANlBlKHDZ8ly7dWQ23e4T1xcml3aXB7YryeMJc9fj0rfV
-        eidID/dExXF5kM7HwRieVjtu4NjSPOx3TVsGwpPcMau822jxwsm9xz3ZVGl8
-        szKy8sXqu1dP10W7K2RQ3K0XNseJf5B2QEuGxf9mEUeU4fqbmcQRY4gVbUq3
-        yRDJrOwxRDPWyp6BBHQdU5ghR3Bg+wz3z8D6tZ4R1Zgt+25HMNzNnOP8BUWt
-        eB7ksHMKvlx1vbZ5KIKGx21qA5fSDfiwJTU3qPUch3jqaXXetKRVAhcnWzhu
-        sSUDj1LYTT+OSwyXmgei2RnleMQ93hUUyHArUz3kfW46XLbN7xqHohkUTnjq
-        Kkm7oNp9BVd1XMYCw8Z5usNw85RSK6+7GNbPnj6ODwzMIqlDw4cMMydUGMdH
-        DAmrVt8t1bbKDBcmJGpgGelp3MDHDNqTPEPqNEaJYtMJJahUN62KZBXwvWmy
-        VhnmXqZ8KALe4gEniNbtR+gtMzVMMbCOMiLkP7KVtUZWi8rlBseGPjjWtaQW
-        Tle15OB4UVtjN6KJwXFSyyZS0ZS2ra1FtnUFWafDFbl05U9dt+fTkwDlrjOs
-        nkX6cRQZ5if03xKPec8JGH4+i4Lf9h05RUpvQ1iniKRiYBNf0tW9qny7Q1yj
-        W25LqCtzm9zZ457NG47YVQPDbNWWotbrNoQ38kzX7bbkQc8jO/19TwZ2V1iy
-        b/s2bY+fROnVk2MwLCmFt+Vw3xe0nC3LpuP6dAy66AO3RU+x7va8pqjYqsD8
-        cPFANHrt8lEgiKorGRZGtfaGlU4UQJ70M0U3SB9sLChBkTKiZJPIaPyaVmmK
-        oEtGLBt9DuOZUhS2aDSGXlwIMXNK+4iEiAIhNJrjudT8H1hUEA0PwmD6xBFQ
-        wS8PQ0ZwZV3ENdovh9FzqCgfKQspIFmi7O+P+Hw1ym5kcwNc/x1Lv+LmLxMl
-        MFHCGJcwcAuZ8Gwr49NdCWOAmb+g/fgcud/wybPQEcM3NOoUNgxYwHbYmvtE
-        YMgxAiucS/iW5qf1h6VH+oQ89J1QaHq2vvTSqui5pfzSZNT/+GXo2aqeX86v
-        5u/cI7usY4eY3CXOt+lSzX1ELKxZyNOIdQufYsPCZ7izD+ZT1Of7iPr4wsc9
-        HwUf114AvnRqlvwHAAA=
+        H4sIAAAAAAAA/81WX1MbVRT/3U0gyZLyJ6V/AEUssYWAXYLYKkmxkRJZCSk2
+        kRmHp5vkNixs7nZ2Nxl846EfwU/gJ2h1xjo64zA++qEcz91sKbHRFnzxIfee
+        e875nX855yR//PnLbwBWUGXIcdlwHatxZNSd1hPHEwaXVov7liOJ4wqj6nLp
+        Weq95ae7MlG0He6nszEwhqelQ8e3LWkcdFqGJX3hSm4bJd6qNXjurOxxW9aV
+        Gc8ohlQ2X3p77+mKaLaE9PPVSm7t1PDX0vLpyTD5z1HEEGWY/vdIYhhkGMxb
+        ZG6NITI3v8sQnTPnd5OIQ9cxgCFi+PuWx3DvHFG/VjMKddCSHedQMNydu0D+
+        ORVa/iLIbuUUfLbkuE3jQPg1l1tUBi6l4/NuScqOX27bNsWpp1W+aUmvOC73
+        lvC0xKb0XTJh1b0YrjBcqe+L+mFoY4e7vCVIkeHWXOmAd7hhc9k0HtYORN3P
+        neFUlJFmTpX7Gq7ruIoJhpWLVIfhZh9X86+zGJbPbz6Gd5MYwagODe8xDJ3p
+        whjeZ4ib5Uq1UF7fYLjU06JJzCKdwA18wKA9yTKk+kUUz9ftoAVV1yWUk4wC
+        DieIWmQYe2lyW/i8wX1OEK3VidAsM3Uk1AEGdqiICAmPLEU9I6pBPldOjof1
+        k2NdG9WC67q6Rk+OJ7UldiMaJ1rLxFPRlLapLUU29d+/H9TiUYVdplTzXDry
+        25bT9mhAlJMKw+J5BiGGewzjPdPQEI952/YZvjtPP79pq/RprDchzD4tU0zi
+        M9xnyLx9ZDF8zhALe4Va4JXk9iG9M31XZcVpu3XxQNTazY0jXxCAUmQY6HC7
+        TUviaWW7sKP3WNK3AjN6pjLzkirqCzPZmV6t/7Cl9ExJz85mF7N3Vone0Gn3
+        rTsNodrWqXN7l7sWr9miqg6GkZIlRbndqgk35CQqVlNyv+0SnX7Ulr7VEqbs
+        WJ5F4tO1UHi1dhiSppTCXbe55wl6jmzIuu149OVRs+87DVpH3UIVLeVgvF/V
+        GCZCX7tdTz0Opv4exxkpsjRhA9TV9JOGCTVyNDZRomkM6TTplSYNanwMZqIv
+        kHweDNqXdCa7XFwKMGNqOyASIHKE0OiOLaTGf8akgmjYCpTpR4CACn61qxLC
+        FXUZUyQvBdpj2FY8mjakgNECWX8njOd+aD2ZWTjB9E+Y+QE3n/W4QI+L5KmL
+        JG5hLsht/jS7a4EOMPQrtG9eYOFHfPg8jKdMZ4rE01jHAypOV3ECD4MSraEQ
+        xhrBTnBv4Cu6/xdti0cUySqleJu+XGMPERNLJrImlvGRSf9/PjZxB3f3wDx8
+        gk/3MOBh1UPOQ97DlEfFrhB+mPBF+nwR6G3+BSprltw9CQAA
         """,
         """
         androidx/compose/animation/core/TransitionKt.class:
-        H4sIAAAAAAAAAMVVT1MjRRR/PZkknSHAMAsI2d24stldYGEnZDHqJovLIsho
-        iJZBLhysJmmyA5MeamZCsRcLvfgFvOzN8uDRg6ctD1aKLS9+Jsvy9ZCEQKzC
-        eDFV6fev3++91/36zR9//fobACzDJwQWmKh5rl07Matu48j1ucmE3WCB7QrU
-        eNzc9pjwbSl/GsSBENAP2DEzHSbq5md7B7yK2giB5Lkb33BcFhD4Zrb074EL
-        pUM3cGxhHhw3zP2mqEqlb260uaVC6SJkJfBsUb/WY26DwJ/FypPS1WQLK4Nk
-        VtyuFFauC1ZcHAAxU+H1BhfBZeQvhR1IcdA6i4sI0+MVnj4CyfLv9WflNUVg
-        N7i5Fspsz+EFAndLrlc3D3iw5zEbwZkQbsDOA5XdoNx0HNwVKwYvbH+FgkYg
-        3ZOULQLuCeaYlpAZ+3bVj0OSwET1Ba8etv0/Zx5rcNxI4MFs/5X0lz23k4QR
-        GNVgGHQCI0H3+CpHvErBIBB12B53KIwTMALm1Xmww5wmf/6ygrlzCpPqsx8A
-        CIxl7Mx+5nJzEgudMrKeK4aFQZqWwJ3ruhDD9NdGYLw3aqbG91nTwejf/89v
-        xuq/GdlHhUEmxKUDzSzF4R0C1CpXtlfLa+sEng5QYR9YIQl3IZOAGbh3uQf/
-        oZg4PMC+CR1XOwEozBG43X/vXzVzy91LGOuc0hYPWI0FDO9LaRxHcF4SuUSx
-        fQ4lo6D+xJZcFrnaEoHfW6c5rXWqKXo8JFNKh4R/Xeny4aaRrpUqqUBvnaaU
-        LJlRaetUV+apoRrKppKN5DJU09VU2tCMji4maTaejZ79GFMoDddEjlJF1xBi
-        KHdfT6ZmjBvG2KaCtiQdNigdMVRKZ0dDT9Lx3Dz7jr55TVqnZ98qcS1Kz17l
-        skQWkyPy6ZCK7N/2cfQ29fJ/mHfolu5grZ8EHM2u6IBuvzySk2iys6E7L8pI
-        0KAKpPjmffm2CQxfwD86xDtT19waqkdLtuDlZmOPe9tytsns3SpzdphnS7mt
-        TFTsumBB00P+5hfnE9ESx7Zvo3n1YvgRyFy1dvO6tG0YR071cIsdtQMkLSG4
-        t+Yw3+do1ipu06vyDVvaptuQO33hYAkUUEH+FJiGKMRQeobSEcpRpOl5Y+g1
-        jD00buC6YEzgumi8hWskrxpTP4d+q7jG8Opuwig8Dz/xUeQjiJcKsdMo3Qpj
-        pMGA27hTcuP4V0JuEnURWAux4vBRG40iXcf/tIpCQr6Eq6uegLfhDvIy4Z/Q
-        OYY0P6GqX78C7Re434LZ0oQaRSlmzG9dW0gENnBVQRlJhCWlQrwhTEl+FoZg
-        Ar8LU0gf95T5uKfMPDxsl5nvlpnvlplvlxmBj1HS0DoT7p2GzbDwD8FCuov6
-        BcRd3IWIBY8sMHGFrIX3lLMw2jJu8OFdyO+C7mNrwns+vO/DLR8MHz7w4Umo
-        oT4UfBgP+Ukfij489WHlb+6OIxeBCQAA
+        H4sIAAAAAAAA/8VWz1PbVhD+nizbsjFgFKDgJG5KnAQIRMZQt40dGkKhqDFO
+        pqZcOHQe9sMRyBIjyUxy6dBe+g/0klunhx576CnTQ4ch00v/pk6nK2EbgztD
+        3EsP2h9v3367+96+tf/8+7ffASzhOcMct2qObdRealW7cWi7QuOW0eCeYVu0
+        4ghty+GWa/j6Uy8KxpDc50dcM7lV157t7osqrYYYEmduYt20ucfw7XTp3YEL
+        pQPbMw1L2z9qaHtNq+ovutp6S1oolM5DVjzHsOpXesysM/xVrDwsXU62sNxP
+        ZsWtSmH5qmDF+T4QMxVRbwjLu4j8lWV4vtpvncV5gunyCk6fgPzy7/Rm5TQt
+        z2gIbTXQ+a4pCgy3S7ZT1/aFt+twg8C5ZdkePwtUtr1y0zRpV6TovTDcZQVx
+        hnRXUoblCcfipqZbfsauUXWjSDCMVV+I6kHL/zl3eEPQRoZ7071X0lv2zHYC
+        QxiOYxBJhiGvc3yVQ1FVoDKETb4rTAWjDKrHnbrwtrnZFE9eVSh3oWBcfvwj
+        wDCSMTJ7mYvNyXRyyvj1XDLM9dO0DLeu6kIK01sbw2h31ExN7PGmSdF/+J/f
+        jN57M34fFfqZEBcONLMQxQcMil6ubK2UV9cYHvVRYQ9YIYHbyMQwhTsXe/Bf
+        ioniHvVN4LjSDqBghuFm771/3cwtdS5hpH1Km8LjNe5xui+pcRSiecl8EvMJ
+        9RU78AWJjC8NX8qSVFtg+OPkOBc/OY5LyWjAJqQ2C76k1JGDTUMdqyKlvOTJ
+        cUrKsilZOTlOSrOKKqvShpQN5TJKPCmn0mpcba9FfJ6NZsOnP0UkRQloLKco
+        UjJOEAO5u8lEakq9po5sSGRLKIOqogypsqJMDweerO25cfq98vYNOzk+/U6K
+        xsPK6etclvnF5FhQZ8Vv4taZdHf20n8YeuSWbmOtvfQEmW2rDbr16tAfR+Pt
+        DZ2hUSZGBtkiTg/f9R84Q67/8FE8Zph9d78onjBEW84Mg+eWBweky6t2jRIZ
+        LhmWKDcbu8LZ8keqf152lZvb3DF8vbUYqxh1i3tNh+TrX54NYt06MlyDzCvn
+        M5chc9naOYkL2wZp0lUPNvlhK0BCtyzhrJrcdQWZ4xW76VTFuuHbJluQ2z3h
+        sAAJst/TxCcRRoS0ddIOSQ8TT8+qA28wcl+9RnROHSM6r75HNJSX1YlfAr/P
+        iUaoWa5jGBvBP4swySHCSwXYadJuBDHSUHGTdvrSKH1SII3TWgh6gBXFFy00
+        hfhT+iZlUmLBq7tEkzG8j1sk+wn/TM4R4vkxWf7mNeK/4u4Jpktjcpi0iDq7
+        eWUhIZSIypCGYkFJqQBvgFLyf40GMEY/RxPEF7vKXOwqM4/7rTLznTLznTLz
+        rTJD2CRNpbUVrOIz8p4KfCZRDg5gDc+I75D3HOHP7yCk44EOTUcWCzpyWNQp
+        8oe0wSXMj3aQdOlR4GMXn7i44UJ18dBFIVhRXBRdjAbyuItHLpZdfPoPx8wC
+        mQAKAAA=
         """
     )
 
diff --git a/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetectorTest.kt b/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetectorTest.kt
index c73c283..e852ff7 100644
--- a/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetectorTest.kt
+++ b/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetectorTest.kt
@@ -44,7 +44,7 @@
     private val AnimatableColorStub = bytecodeStub(
         filename = "SingleValueAnimation.kt",
         filepath = "androidx/compose/animation",
-        checksum = 0x285b4455,
+        checksum = 0x98c0a447,
         """
             package androidx.compose.animation
 
@@ -55,28 +55,28 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAHWLuwrCQBBFR3zBIBZbiIgQsFCwWBt/QCzTqdhvkiEO7CPs
-        A/x8V9QqWNx74XIOAAwBYJAz/i7gEVfKNt5x85S1M50LJJVloyI7KxZXtq2m
-        u9KJTr+3jHjA4r+VH09i9uFVpSkLW1z2BJ9sZEMCL2TIVOQzt8N1j0ssW6+6
-        B9dBTM9Ouzc4x1GkEMXklruMG9jDC9/F7r/gAAAA
+        H4sIAAAAAAAA/3XLvQvCQAwF8IiiGEThBhERBBfBoS6Cszh2s+KetqE9uI9y
+        TcE/3xN1KgZehsf7AcAQAAYxU/gennBNrgxel8+k8LbxLSfktCXR3qllpl1l
+        +EGm48uvTQWPuP2vYhNYzT57yg1HcMZVD4TOibas8MaWbc4hFbXIHDVt7SUT
+        kjfc46YHO51UgZpaF62aXL3xUeIcR8KtqPE9/lR2cIAXLlZThPEAAAA=
         """,
         """
         androidx/compose/animation/SingleValueAnimationKt.class:
-        H4sIAAAAAAAAAJVTXU8TQRQ9s223Zam0VFEoigooHwLbEh8wJUSCMSkWTESb
-        GB7MtF3rtNsZMjvb8Ej8J/oLfJNoYgi++aOMdwuExBKFTfbOuXfPnXPvzN1f
-        v7/9APAYSwxFLhtaica+W1edPRV4Lpeiw41Q0t0Rsul7Ve6H3vpZ8IVJgjFk
-        W7zLXZ/Lpvuy1vLqFI0x5E5ovOZ7iyvvVoq+v87gzm7OVf6hUlfac88TSwzN
-        q2Ws9nND4TY13/sg6oG7oXylS5W/Cy6tkdJURemm2/JMTXMhA9KQyvREAndb
-        me3Q94k1f/lakhhgmPx/PUkMMqRqan9RdPZ8hpkLW+5vI41rGHKQRobBXhVS
-        mDWG6mx/d/2RcqWtjC+k2+p2XCGNpyX33Wfeex76ZoM6NjqsG6W3uG57ujRX
-        TWMYOQcOrjOkIynB/d4wMLBNhuGz/bY8wxvUPp2U1enGaLJYZBJEa0fAovi+
-        iFCBUKPI8OboIOccHTjWqHXyZiMnFcvPEMgP5eI5q2D1bKzAlu1sPE/+z0N2
-        dECGHX+246lE1j7+aA1S1piTSB1/miiwaPNlBuf8NhgWrjZ505e5A0YN4tZF
-        P8dS2zDEN1SDlDMVIb3tsFPz9OuTWnIVVY9OUIvIPw0O7Iim5CbUhMdfhdKI
-        jleWXREI+rx+Po7U144Kdd17LqK0sVNqtY+IIizEET1EQwI2Ypgh7wkhi9bM
-        dzhvJw6RZQn2FTe+RDeEWbI2JQBJzJFN93AGI7hJ63yPk8SjU1aq5y/07EMs
-        0vo0OhISG91FrIyxMvJkMV7GbdwpYwJ3d8EC3MP9XSQDTAaYCjAd4EGAkQCJ
-        APYfAm5eAJQEAAA=
+        H4sIAAAAAAAA/5VTXU8TQRQ9s223Za20VFEoigooHwLTEh8wJUSCMSkWTMQ0
+        MTyYaTvWabczZHa24ZH4T/QX+CbRxBB880cZZ1sIiSUKD3vn3Dvnzv3cX7+/
+        /QDwBJSgyGRDK9E4oHXV2VcBp0yKDjNCSborZNPnVeaHfOPM+NIkQQiyLdZl
+        1GeySV/VWrxurTGCXJ/Gaj5fWn23WvT9DQI6tzVf+UeUutKcnjuWCJpX81gb
+        5IaCNjXb/yDqAd1UvtKlyt8Jl9ZtpOmK0k3a4qammZCBjSGV6QUJ6I4yO6Hv
+        W9bC5XNJYohg6v/5JHGNIFVTB0uis+8TzF5Y8mAZaVzHsIc0MgTumpDCrBNU
+        5warG7SUK21lfCFpq9uhQhquJfPpc/6ehb7ZtBUbHdaN0ttMt7kuzVfTGEHO
+        g4cbBOkolGB+bxkIyBbByNl729ywhi3fdsrpdGN2s0gkhiIBy21HwLGXByJC
+        BYsaRYLt48Ocd3zoOWNO/8tGSiqWn7EgP5yL55yC05OxAllxs/G81X8ekePD
+        k89uPJXIuicfnaSXSJ18miyQ6NEVAu98FASLV1u7mcsMgEQl3b7oz1huG4L4
+        pmrYyJmKkHwn7NS4ftPPJVdR9ah9WkT6qXFoVzQlM6G2eOJ1KI3o8LLsikDY
+        643zXbR17apQ1/kLEbmNn1KrA0QU4SCOfuPHkYCLGOas9tQix56Z7/DeTh4h
+        SxLkK25+iSaDeStd6wAksWBluoczGMUtez7ucZJYPGWlevpST85i2Z7PopbY
+        YGN7iJUxXka+jAncKeMuJsu4h/t7IAEeYGoPyQDTAWYCPAzwKMBogEQA9w+x
+        P7r8kQQAAA==
         """
     )
 
@@ -173,7 +173,8 @@
             Stubs.Color,
             Stubs.Composable,
             Stubs.Remember,
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
             )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -338,7 +339,8 @@
             Stubs.Color,
             Stubs.Composable,
             Stubs.Remember,
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .run()
             .expectClean()
@@ -452,7 +454,8 @@
             Stubs.Color,
             Stubs.Composable,
             Stubs.Remember,
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
             )
             .run()
             .expectClean()
diff --git a/compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/EasingTest.kt b/compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/EasingTest.kt
index cbc7126..1b9ff11 100644
--- a/compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/EasingTest.kt
+++ b/compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/EasingTest.kt
@@ -16,8 +16,10 @@
 
 package androidx.compose.animation.core
 
+import androidx.compose.ui.util.floatFromBits
 import com.google.common.truth.Truth.assertThat
 import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertTrue
 import org.junit.Assert.assertNotEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -61,4 +63,29 @@
         assertNotEquals(curve1.hashCode(), curve5.hashCode())
         assertNotEquals(curve1.hashCode(), curve6.hashCode())
     }
+
+    @Test
+    fun canSolveCubicForSmallFractions() {
+        val curve = CubicBezierEasing(0.3f, 0.0f, 0.7f, 1.0f)
+
+        val testValues = intArrayOf(
+            0x3e800000, // 0.25f
+            0x3e000000, // 0.125f
+            0x3d800000, // 0.0625f
+            0x3a800000, // 0.0009765625f
+            0x36000000, // 0.0000019073486328125f
+            0x34800000, // 2.384185791015625e-7f
+            // Values from here are below the epsilon we use in our computations
+            0x34000000, // 1.1920928955078125e-7f
+            0x34210fb0, // 1.50000005305628292263e-7f
+            0x33800000, // 5.9604644775390625e-8f
+            0x33000000, // 2.98023223876953125e-8f
+            0x00000000, // 0.0f
+        )
+
+        for (i in testValues) {
+            val t = curve.transform(floatFromBits(i))
+            assertTrue(t in 0.0f..1.0f)
+        }
+    }
 }
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationSpec.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationSpec.kt
index 5c4a9d5..a84bb06 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationSpec.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimationSpec.kt
@@ -26,8 +26,8 @@
 import androidx.compose.runtime.Stable
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.abs
-import kotlin.math.roundToInt
 
 object AnimationConstants {
     /**
@@ -446,7 +446,7 @@
      *  @return an instance of [E] so a custom [Easing] can be added by the [using] method
      */
     infix fun T.atFraction(fraction: Float): E {
-        return at((durationMillis * fraction).roundToInt())
+        return at((durationMillis * fraction).fastRoundToInt())
     }
 
     /**
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Bezier.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Bezier.kt
index bc16918..f949c726 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Bezier.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Bezier.kt
@@ -18,17 +18,18 @@
 
 import androidx.collection.FloatFloatPair
 import androidx.compose.ui.graphics.PathSegment
+import androidx.compose.ui.util.fastCbrt
+import androidx.compose.ui.util.fastCoerceIn
 import kotlin.math.abs
 import kotlin.math.acos
-import kotlin.math.cbrt
 import kotlin.math.cos
 import kotlin.math.max
 import kotlin.math.min
 import kotlin.math.sqrt
 
 private const val Tau = Math.PI * 2.0
-private const val Epsilon = 1e-7
-private const val FloatEpsilon = 1e-7f
+private const val Epsilon = 1.5e-7
+private const val FloatEpsilon = 1.5e-7f
 
 /**
  * Evaluate the specified [segment] at position [t] and returns the X
@@ -138,9 +139,9 @@
     p2: Float,
     t: Float
 ): Float {
-    val by = 2.0 * (p1 - p0)
-    val ay = p2 - 2.0 * p1 + p0
-    return ((ay * t + by) * t + p0).toFloat()
+    val by = 2.0f * (p1 - p0)
+    val ay = p2 - 2.0f * p1 + p0
+    return (ay * t + by) * t + p0
 }
 
 private fun evaluateCubic(
@@ -150,10 +151,10 @@
     p3: Float,
     t: Float
 ): Float {
-    val a = p3 + 3.0 * (p1 - p2) - p0
-    val b = 3.0 * (p2 - 2.0 * p1 + p0)
-    val c = 3.0 * (p1 - p0)
-    return (((a * t + b) * t + c) * t + p0).toFloat()
+    val a = p3 + 3.0f * (p1 - p2) - p0
+    val b = 3.0f * (p2 - 2.0f * p1 + p0)
+    val c = 3.0f * (p1 - p0)
+    return ((a * t + b) * t + c) * t + p0
 }
 
 /**
@@ -167,10 +168,10 @@
     p2: Float,
     t: Float
 ): Float {
-    val a = 1.0 / 3.0 + (p1 - p2)
-    val b = (p2 - 2.0 * p1)
+    val a = 1.0f / 3.0f + (p1 - p2)
+    val b = (p2 - 2.0f * p1)
     val c = p1
-    return 3.0f * (((a * t + b) * t + c) * t).toFloat()
+    return 3.0f * ((a * t + b) * t + c) * t
 }
 
 /**
@@ -271,10 +272,10 @@
     // The math used to find the roots is explained in "Solving the Cubic Equation":
     // http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm
 
-    var a = 3.0 * p0 - 6.0 * p1 + 3.0 * p2
-    var b = -3.0 * p0 + 3.0 * p1
+    var a = 3.0 * (p0 - 2.0 * p1 + p2)
+    var b = 3.0 * (p1 - p0)
     var c = p0.toDouble()
-    val d = -p0 + 3.0 * p1 - 3.0 * p2 + p3
+    val d = -p0 + 3.0 * (p1 - p2) + p3
 
     // Not a cubic
     if (d.closeTo(0.0)) {
@@ -300,42 +301,40 @@
     b /= d
     c /= d
 
-    val o = (3.0 * b - a * a) / 3.0
-    val o3 = o / 3.0
-    val q = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 27.0
-    val q2 = q / 2.0
+    val o3 = (3.0 * b - a * a) / 9.0
+    val q2 = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0
     val discriminant = q2 * q2 + o3 * o3 * o3
+    val a3 = a / 3.0
 
     if (discriminant < 0.0) {
-        val mp3 = -o / 3.0
-        val mp33 = mp3 * mp3 * mp3
+        val mp33 = -(o3 * o3 * o3)
         val r = sqrt(mp33)
-        val t = -q / (2.0 * r)
-        val cosPhi = min(1.0, max(-1.0, t))
+        val t = -q2 / r
+        val cosPhi = t.fastCoerceIn(-1.0, 1.0)
         val phi = acos(cosPhi)
-        val t1 = 2.0 * cbrt(r)
+        val t1 = 2.0f * fastCbrt(r.toFloat())
 
-        var root = clampValidRootInUnitRange((t1 * cos(phi / 3.0) - a / 3.0).toFloat())
+        var root = clampValidRootInUnitRange((t1 * cos(phi / 3.0) - a3).toFloat())
         if (!root.isNaN()) return root
 
-        root = clampValidRootInUnitRange((t1 * cos((phi + Tau) / 3.0) - a / 3.0).toFloat())
+        root = clampValidRootInUnitRange((t1 * cos((phi + Tau) / 3.0) - a3).toFloat())
         if (!root.isNaN()) return root
 
-        return clampValidRootInUnitRange((t1 * cos((phi + 2.0 * Tau) / 3.0) - a / 3.0).toFloat())
+        return clampValidRootInUnitRange((t1 * cos((phi + 2.0 * Tau) / 3.0) - a3).toFloat())
     } else if (discriminant == 0.0) { // TODO: closeTo(0.0)?
-        val u1 = if (q2 < 0.0) cbrt(-q2) else -cbrt(q2)
+        val u1 = -fastCbrt(q2.toFloat())
 
-        val root = clampValidRootInUnitRange((2.0 * u1 - a / 3.0).toFloat())
+        val root = clampValidRootInUnitRange(2.0f * u1 - a3.toFloat())
         if (!root.isNaN()) return root
 
-        return clampValidRootInUnitRange((-u1 - a / 3.0).toFloat())
+        return clampValidRootInUnitRange(-u1 - a3.toFloat())
     }
 
     val sd = sqrt(discriminant)
-    val u1 = cbrt(-q2 + sd)
-    val v1 = cbrt(q2 + sd)
+    val u1 = fastCbrt((-q2 + sd).toFloat())
+    val v1 = fastCbrt((q2 + sd).toFloat())
 
-    return clampValidRootInUnitRange((u1 - v1 - a / 3.0).toFloat())
+    return clampValidRootInUnitRange((u1 - v1 - a3).toFloat())
 }
 
 /**
@@ -423,14 +422,14 @@
             // Quadratic derivative of a cubic function
             // We do the computation inline to avoid using arrays of other data
             // structures to return the result
-            val d0 = 3 * (points[2] - points[0])
-            val d1 = 3 * (points[4] - points[2])
-            val d2 = 3 * (points[6] - points[4])
+            val d0 = 3.0f * (points[2] - points[0])
+            val d1 = 3.0f * (points[4] - points[2])
+            val d2 = 3.0f * (points[6] - points[4])
             val count = findQuadraticRoots(d0, d1, d2, roots, index)
 
             // Compute the second derivative as a line
-            val dd0 = 2 * (d1 - d0)
-            val dd1 = 2 * (d2 - d1)
+            val dd0 = 2.0f * (d1 - d0)
+            val dd1 = 2.0f * (d2 - d1)
             count + findLineRoot(dd0, dd1, roots, index + count)
         }
 
@@ -489,8 +488,7 @@
  * range are considered to be in the [0..1] range and clamped appropriately. Returns 0 if
  * no value was written, 1 otherwise.
  */
-@Suppress("NOTHING_TO_INLINE")
-private inline fun writeValidRootInUnitRange(r: Float, roots: FloatArray, index: Int): Int {
+private fun writeValidRootInUnitRange(r: Float, roots: FloatArray, index: Int): Int {
     val v = clampValidRootInUnitRange(r)
     roots[index] = v
     return if (v.isNaN()) 0 else 1
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Easing.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Easing.kt
index b1081ad..fbcabe4 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Easing.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Easing.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
+import androidx.compose.ui.util.fastCoerceIn
 
 /**
  * Easing is a way to adjust an animation’s fraction. Easing allows transitioning
@@ -110,8 +111,16 @@
         }
     }
 
+    /**
+     * Transforms the specified [fraction] in the range 0..1 by this cubic Bézier curve.
+     * To solve the curve, [fraction] is used as the x coordinate along the curve, and
+     * the corresponding y coordinate on the curve is returned. If no solution exists,
+     * this method throws an [IllegalArgumentException].
+     *
+     * @throws IllegalArgumentException If the cubic Bézier curve cannot be solved
+     */
     override fun transform(fraction: Float): Float {
-        if (fraction > 0f && fraction < 1f) {
+        return if (fraction > 0f && fraction < 1f) {
             val t = findFirstCubicRoot(
                 0.0f - fraction,
                 a - fraction,
@@ -121,13 +130,15 @@
 
             // No root, the cubic curve has no solution
             if (t.isNaN()) {
-                return fraction
+                throw IllegalArgumentException(
+                    "The cubic curve with parameters ($a, $b, $c, $d) has no solution at $fraction"
+                )
             }
 
             // Clamp to clean up numerical imprecision at the extremes
-            return evaluateCubic(b, d, t).coerceAtLeast(0.0f).coerceAtMost(1.0f)
+            evaluateCubic(b, d, t).fastCoerceIn(0f, 1f)
         } else {
-            return fraction
+            fraction
         }
     }
 
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/FloatAnimationSpec.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/FloatAnimationSpec.kt
index d001fc6..7d4f70c 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/FloatAnimationSpec.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/FloatAnimationSpec.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.animation.core.AnimationConstants.DefaultDurationMillis
 import androidx.compose.animation.core.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.util.fastCoerceIn
 
 /**
  * [FloatAnimationSpec] interface is similar to [VectorizedAnimationSpec], except it deals
@@ -212,7 +213,7 @@
         val playTimeMillis = playTimeNanos / MillisToNanos
         val clampedPlayTime = clampPlayTime(playTimeMillis)
         val rawFraction = if (duration == 0) 1f else clampedPlayTime / duration.toFloat()
-        val fraction = easing.transform(rawFraction.coerceIn(0f, 1f))
+        val fraction = easing.transform(rawFraction.fastCoerceIn(0f, 1f))
         return lerp(initialValue, targetValue, fraction)
     }
 
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt
index b3a5747..6455afd 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt
@@ -24,7 +24,7 @@
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * [TwoWayConverter] class contains the definition on how to convert from an arbitrary type [T]
@@ -169,7 +169,7 @@
 private val IntOffsetToVector: TwoWayConverter<IntOffset, AnimationVector2D> =
     TwoWayConverter(
         convertToVector = { AnimationVector2D(it.x.toFloat(), it.y.toFloat()) },
-        convertFromVector = { IntOffset(it.v1.roundToInt(), it.v2.roundToInt()) }
+        convertFromVector = { IntOffset(it.v1.fastRoundToInt(), it.v2.fastRoundToInt()) }
     )
 
 /**
@@ -178,7 +178,7 @@
 private val IntSizeToVector: TwoWayConverter<IntSize, AnimationVector2D> =
     TwoWayConverter(
         { AnimationVector2D(it.width.toFloat(), it.height.toFloat()) },
-        { IntSize(it.v1.roundToInt(), it.v2.roundToInt()) }
+        { IntSize(it.v1.fastRoundToInt(), it.v2.fastRoundToInt()) }
     )
 
 /**
diff --git a/compose/animation/animation-graphics/src/commonMain/kotlin/androidx/compose/animation/graphics/vector/Animator.kt b/compose/animation/animation-graphics/src/commonMain/kotlin/androidx/compose/animation/graphics/vector/Animator.kt
index 56f2de5..89a0661 100644
--- a/compose/animation/animation-graphics/src/commonMain/kotlin/androidx/compose/animation/graphics/vector/Animator.kt
+++ b/compose/animation/animation-graphics/src/commonMain/kotlin/androidx/compose/animation/graphics/vector/Animator.kt
@@ -36,6 +36,7 @@
 import androidx.compose.ui.graphics.vector.PathNode
 import androidx.compose.ui.graphics.vector.VectorConfig
 import androidx.compose.ui.graphics.vector.VectorProperty
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.util.fastMaxBy
@@ -422,7 +423,7 @@
         val innerFraction = easing.transform(
             ((fraction - animatorKeyframes[index].fraction) /
                 (animatorKeyframes[index + 1].fraction - animatorKeyframes[index].fraction))
-                .coerceIn(0f, 1f)
+                .fastCoerceIn(0f, 1f)
         )
         return lerp(
             animatorKeyframes[index].value,
diff --git a/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/AnimatedContentDetectorTest.kt b/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/AnimatedContentDetectorTest.kt
index 3cedb40..6149723 100644
--- a/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/AnimatedContentDetectorTest.kt
+++ b/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/AnimatedContentDetectorTest.kt
@@ -43,7 +43,7 @@
     private val AnimatedContentStub = bytecodeStub(
         filename = "AnimatedContent.kt",
         filepath = "androidx/compose/animation",
-        checksum = 0xb4ed4385,
+        checksum = 0x36ddd76f,
         """
             package androidx.compose.animation
 
@@ -73,97 +73,97 @@
                 content: @Composable AnimatedContentScope.(T) -> Unit
             ) {}
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijg0ueSSsxLKcrPTKnQS87PLcgvTtVL
-        zMvMTSzJzM8TEnQEM1NTnPPzSlLzSrxLuHi5mNPy84XYQlKLgVwlBi0GAC4u
-        H9hYAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0ueSSsxLKcrPTKnQS87PLcgvTtVL
+        zMvMTSzJzM8TEnQEM1NTnPPzSlLzSrxLuHi5mNPy84XYQlKLgVwlBi0GADRx
+        8BlYAAAA
         """,
         """
         androidx/compose/animation/AnimatedContentKt$AnimatedContent$1.class:
-        H4sIAAAAAAAA/6VVS3MbRRD+ZiXrsRZ+QeIXGJKIRLITr2zCI5FjIoRNFoSg
-        kMtVlE+j1doeaXfGtbtShZv/CBcOnElRRShSRbk48qOo9KyEX3EcRA6a7unX
-        193bPfr7nz/+BHAXXzKsc9kKlGg9thzlH6jQtbgUPo+EklYl5txWVcnIldFX
-        Uf6cJL+SBmP4udZRkSek1e75liBNILln1bjfbPHyad1uVzo6cmhtDriVtdp/
-        T2Ar4DIUWtNw1IFbvsz1tMuuCvzyeplh7uV5ppFkWLg81zRSDKk1IUW0zpAo
-        FLcZkgW7uJ1DBqaJEYySINoXIcPDIeq6qLGUbUrInuq4DO3CazSpOFSXGG7U
-        VLBntd2oGXBB1XMpVcT7nairqN71PLIy87rMvKRbBlNnO3fcWVtGAYUQTpjG
-        WwxXnH3X6QxifMsD7rtkyHCrUGvzHrc8Lvesb5pt14nKpyQNHWSvrLt8FdMm
-        rmCGYWmIotKY0x8oa2IebzNcOjavaCbDzQuSLb4oYrj3v1HSeC+HcUyYMHCd
-        wThYYZi6CCKz5njxMGpLqixj1xtblXp1I4cCxrIkLDJM/ruAX7sRb/GIk6Ph
-        9xL0ADB9ZPQBBtbRTIKUj4XmSsS1CHn56HDMPDo0jRnjhEwcHc4ZJXY9mSHe
-        WDRKiUfmXz+ljExSe60yjK5xqeQPvuqGtCp3hpxBtsVwe5j9SeM+w/T5JWq5
-        u7zrRQw/XrpAJ+1/1WP1mvrVsn3B8NBcr+EBfeJz6S93KPNkVbVc/fmVw71t
-        Hgje9NwtfTCM14R0612/6QYDyfx3XRkJ37VlT4SCRJWT5WXIn9ce7+AZs5wt
-        pRtUPR6GLl3HN6TjqZBWkAZoX7UYsg2xJ3nUDQjRbKhu4LibQsPPDgC2XwBH
-        iYZxhKaM/i8wq6eTJiyppw9ZkjwkLk8WjGhqMfkUuSfxTFbozPWleCP2mdSL
-        gUTs8Rl5GETHlqbe/B2zzzD//VO88wtJDNJpH3pDyUtHudq3HETR3BQWSF8d
-        2E0S/Zx+ada/TFQI6N1Bag8GQNnFpSNc+w03zmKAop5gZI8xslTT+6TP4OZx
-        ldOxDTD6DAZle+tXLD6JBSPYoNMks77BDDbjFpWxji9iuAQexfRT2ETvk+US
-        ed3eQcLGHRvLNiyUbKxg1cYHuLsDFuJDfLSDkRAfh/gkxL0QCyHGnwPaJ41m
+        H4sIAAAAAAAA/6VVW28bRRT+Zu34sjG5QZsbBNqa1k7arBPKpXUaakxCF4xB
+        OIqE8jReb5Kxd2ei3bVV3vJHeOGBZyokiqiEIh75Uahn1ia3pimmDztz5ty+
+        c86cM/v3P3/8CeAuvmRY57IVKNF6bDnKP1Cha3EpfB4JJa1KTLmtqpKRK6Ov
+        ovw5Tn4lDcbwc62jIk9Iq93zLUGSQHLPqnG/2eLl07LdrnS059DaHFAra7X/
+        HsBWwGUotKThqAO3fJnpaZNdFfjl9TLD3MvjTCPJsHB5rGmkGFJrQoponSFR
+        KG4zJAt2cTuHDEwTIxglRrQvQoaHQ+R1UWEp2pSQPdVxGdqF1yhScagqMdyo
+        qWDPartRM+CCsudSqoj3K1FXUb3reaRl5nWaeUmnDKbOVu64sraMAnIhnDCN
+        txiuOPuu0xn4+JYH3HdJkeFWodbmPW55XO5Z3zTbrhOVT3Ea2sleWVf5KqZN
+        XMEMw9IQSaUxpy8oa2IebzNc2javKCbDzQuCLb7IYrj3v1HSeC+HcUyYMHCd
+        wThYYZi6CCKz5nhxM2pNyixj1xtblXp1I4cCxrLELDJM/juAX7sRb/GIk6Hh
+        9xL0ADC9ZPUCBtbRRIKEj4WmSkS1CHn56HDMPDo0jRnjZJs4OpwzSux6MkO0
+        sWiUEo/Mv35KGZmktlplGF3jUskffNUNaVTuDNmDbIvh9jDzk8Z9hunzQ9Ry
+        d3nXixh+vHSATsr/qsfqNeWrZfuC5qG+XsMDuuJz4S93KPJkVbVcff3K4d42
+        DwRveu6WXhjGa0K69a7fdIMBZ/67royE79qyJ0JBrMrJ8DLkz0uPZ/CMWs6W
+        0g2qHg9Dl47jG9LxVEgjSA20r1oM2YbYkzzqBoRoNlQ3cNxNoeFnBwDbL4Cj
+        RM04Ql1G/wvM6u6kDkvSR2NJnIdE5UmD0Z5aTD5F7knckxVac30u3ohtJvVg
+        IBFbfEYWBu1jS1Nv/o7ZZ5j//ine+YU4Bsm0Db2hZKW9XO1rDrxoagoLJK8O
+        9CZp/5y+NOsfJioE9O4gtAcDoOzi0hGu/YYbZzFAXk8wsscYWcrpfZJncPM4
+        y+lYBxh9BoOivfUrFp/EjBFs0GqSWl9hBptxicpYxxcxXAKP4v1T2LTfJ80l
+        srq9g4SNOzaWbVgo2VjBqo0PcHcHLMSH+GgHIyE+DvFJiHshFkKMPwc4Eluy
         /wcAAA==
         """,
         """
         androidx/compose/animation/AnimatedContentKt$AnimatedContent$2.class:
         H4sIAAAAAAAA/6VUW08TQRT+Zru9Um1B5aaiIkILyEJVHmxDJBXCxoqJNE0M
-        T9PuAkN3Z01n2+Abf8QXf4HEBxJNDPHRH2U8s1RjUDGGZHvm2+9c5ty2X799
-        /AzgIZYZVrh0OoFwDqxW4L8OlGtxKXweikBaqxFynWogQ1eGz8KpM8xUKQnG
-        8LTWDkJPSGu/51uCNB3JPavG/abDy7/qdrqypSMra72Plir1epmelTLD+N+j
-        JGEyTJwfKYkEQ6IipAhXGGKFYoPBLNjFRhYpZDKIY4CIcE8ohie1i5VN2SaE
-        7AVtl2G6UNvnPW55XO5aL5r7bissF3+nGFIFKrRIPwZDhAxDfzSqtLyoBJ11
-        OgMD14i0N7fqq5vVtSxGcDlN5CjD4I/OPndD7vCQ67h+L0aTZVqktAADa2sQ
-        I+WB0GiRkLPEMHNyaGaMVDx/cjhubLBJM3VymGelRN7QrxuZL+8SZiqWN7V5
-        iWGgwmUg3/hBV1F7WZ1h/n96mESBYeRsIx13h3c96sXbwnkTqXe4VELDf63T
-        BfWlsv2HYdIGzWKOBnYm/YU2ZW5WA8fVwwxa3GvwjuBNz61rwZCrCeludv2m
-        2+kz6S2xK3nY7RDO2lK6narHlXJpJ3NrsuUFSshdGuhe4DBktoJup+WuC+05
-        9rIrQ+G7DaEEhVqVMgij7igs0kLEadL0MWJMb4iet94ApIlZIDRFFozOxKx5
-        jOxRtBcWyewpi0uRzyByyJOl9lgmjUGnMfdeS7pD22nrfOQ5fKrte2o0hCuk
-        X4rwIN199eftI5EtMPAJxqtjDH/A2FFExFEimelfBYziAUkTRcz3A8XoX0qf
-        9/GIzsdkOU5e17cRs3HDxk0bE7hl4zbu2JjE3W0wRcXe20ZcYVphRmFIIaeQ
-        /w4vHqod9AQAAA==
+        T9PuAkN3Z01n2+Abf8QXf4HEBxJNDPHRH2U8s1RjUDGGZOecb79zmZlzzu7X
+        bx8/A3iIZYYVLp1OIJwDqxX4rwPlWlwKn4cikNZqhFynGsjQleGzcOoMM1VK
+        gjE8rbWD0BPS2u/5liBLR3LPqnG/6fDyr7adrmzpzMpa76OlSr1epmelzDD+
+        9yxJmAwT52dKIsGQqAgpwhWGWKHYYDALdrGRRQqZDOIYICLcE4rhSe1i16bT
+        JoTsBW2XYbpQ2+c9bnlc7lovmvtuKywXf6cYUgW6aJEWgyFChqE/OlVaXnQF
+        fep0BgauEWlvbtVXN6trWYzgcprIUYbBH5V97obc4SHXef1ejDrLtEhrAQbW
+        1iBGxgOh0SIhZ4lh5uTQzBipeP7kcNzYYJNm6uQwz0qJvKFfNzJf3iXMVCxv
+        avcSw0CFy0C+8YOuovKyOsP8/9QwiQLDyNlCOu4O73pUi7eF8zpS73CphIb/
+        GqcL2ktl+w/NpAmaxRw17MzxF9p0crMaOK5uZtDiXoN3BG96bl0LhlxNSHez
+        6zfdTp9Jb4ldycNuh3DWltLtVD2ulEszmVuTLS9QQu5SQ/cChyGzFXQ7LXdd
+        6Mixl10ZCt9tCCUo1aqUQRhVR2GRBiJOnaaPEWN6QnS/adEAEbNAaIo8GOnE
+        rHmM7FE0FxbJ7CmLS1HMIHLIk6eOWCaLQdqYe68l7aH9tHc+ihw+tfYjNRrC
+        FbIvRXiQ9r76c/eRyBcY+ATj1TGGP2DsKCLiKJHM9LcCRvGApIki5vuJYvSX
+        0vo+HpF+TJ7jFHV9GzEbN2zctDGBWzZu446NSdzdBlN02XvbiCtMK8woDCnk
+        FPLfAe45AxX0BAAA
         """,
         """
         androidx/compose/animation/AnimatedContentKt$AnimatedContent$3.class:
-        H4sIAAAAAAAA/6VVW28bRRT+Zu34sjG5QZsbBGhNaydt1knLpbUbakxCF4xB
-        OIqE8jReb5Kxd2ei3bVV3vLI7+CBZyokiqiEIh75Uahn1iZN0hAwffDMmXOZ
-        75wz31n/+ddvvwO4i88ZNrhsB0q0H1uO8g9V6FpcCp9HQkmrGktuu6Zk5Mro
-        iyh/TpO/kwZj+LHeVZEnpNXp+5YgSyC5Z9W532rz8mnbXk86+ubQ2hpKa5X6
-        f09gO+AyFNrSdNShW74s9HTIngr88kaZYeGf80wjybB0ea5ppBhSFSFFtMGQ
-        KBR3GJIFu7iTQwamiTGMkyI6ECHDwxHquqixlG1KyL7qugydwis0qThSlxiu
-        11Wwb3XcqBVwQdVzKVXEB51oqKjR8zzyMvO6zLykUwYzZzt30llbRgFdIZww
-        jTcYrjgHrtMd3vE1D7jvkiPDzUK9w/vc8rjct75qdVwnKp/SNPUl+2Xd5auY
-        NXEFcwwrIxSVxoJ+oKyJRbzJcClt/qWZDDcuSLb4sorh3v9GSeOdHCYxZcLA
-        NQbjcI1h5iKITMXxYjJqT6osYzea29VGbTOHAiaypCwyTP89gF+6EW/ziFOg
-        4fcT9AFgesnoBQysq4UEGR8LLZVIahPy6vHRhHl8ZBpzxott6vhowSixa8kM
-        ycayUUo8Mv/4IWVkkjpqnWG8wqWS3/mqF9Ko3B6Rg2yb4dYo85PGfYbZ80PU
-        dvd4z4sYvr+IYZfP+iva18v2BTwhClfwgF7zXKarXUoyWVNtV7+0cri3wwPB
-        W567rReGybqQbqPnt9xgqFn8picj4bu27ItQkKr6Yk4Z8uetJ+N2xi1nS+kG
-        NY+HoUvHyU3peCqkaSOuHKg2Q7Yp9iWPegEhmk3VCxx3S2j4+SHAzkvgKBHv
-        xohQ9NeAeU1EIlNSEw1Z0jwkKU8ejPbUcvIpck9i+lVpzQ20eC2OmdYzgEQc
-        8QlFGLRPrMy8/ivmn2Hx26d46yfSGGTTMfS5xFx8y9WB5/AWLc1giey1od80
-        7Z/SL80Gh6kqAb09TO3BECi7vHKMd3/B9bMYwOwpjOwJRpZqeo/sGdw4qXI2
-        9gHGn8GgbG/+jOUnsWIMm7Sa5DZwmMNW3KIyNvBZDJfAo3j/GDbt98lzhaJu
-        7SJh47aNVRsWSjbWsG7jDu7ugoV4Hx/sYizEhyE+CnEvxFKIyefQs6Ef6gcA
+        H4sIAAAAAAAA/6VVW3PbVBD+juz4opjcoM0NArSmtZM2ctJyae2GGpNQgTEM
+        zmSGydOxfJIcWzrKSLKnvOWR38EDz3SYoQydYTI88qOY7pFNmqQhYPqgs3v2
+        9u2udqU///rtdwB38TnDBlftwJftx5bje4d+KCyupMcj6SurGnOiXfNVJFT0
+        RZQ/J8nfSYMx/Fjv+pErldXpe5YkTaC4a9W512rz8mndXk85OnJobQ25tUr9
+        vyewHXAVSq1pOv6hKF/metplzw+88kaZYeGf80wjybB0ea5ppBhSFalktMGQ
+        KBR3GJIFu7iTQwamiTGMkyA6kCHDwxHquqixlG1Kqr7fFQydwis0qThSlxiu
+        1/1g3+qIqBVwSdVzpfyIDzrR8KNGz3XJyszrMvOKbhnMnO3cSWdtFQUUQjph
+        Gm8wXHEOhNMdxviaB9wTZMhws1Dv8D63XK72ra9aHeFE5VOSpg6yX9ZdvopZ
+        E1cwx7AyQlFpLOgXlDWxiDcZLh2bf2kmw40Lki2+LGK4979R0ngnh0lMmTBw
+        jcE4XGOYuQgiU3HceBi1JVWWsRvN7WqjtplDARNZEhYZpv9ewC9FxNs84uRo
+        eP0EfQCYPrL6AAPraiZBysdScyXi2oS8enw0YR4fmcac8YJMHR8tGCV2LZkh
+        3lg2SolH5h8/pIxMUnutM4xXuPLVd57fC2lVbo84g2yb4dYo+5PGfYbZ80vU
+        Fnu850YM3180YZfv+ivq18v2BXNCI1zBA3qb5zJd7VKSyZrfFvpN+w53d3gg
+        ecsV2/pgmKxLJRo9ryWCoWTxm56KpCds1ZehJFH1xZ4y5M9rT9btjFnOVkoE
+        NZeHoaDr5KZyXD+kbaNZOfDbDNmm3Fc86gWEaDb9XuCILanh54cAOy+Bo0Rz
+        N0YDRb8GzOtBpGFK0kMbSJKHxOXJghFNLSefIvckHr8qnbmBFK/FPtN6B5CI
+        PT4hD4PoxMrM679i/hkWv32Kt34iiUE67UOfS8zFUa4OLIdRNDeDJdLXhnbT
+        RD+lJ80Gl6kqAb09TO3BECi7vHKMd3/B9bMYwOwpjOwJRpZqeo/0Gdw4qXI2
+        tgHGn8GgbG/+jOUnsWAMm3SaZDYwmMNW3KIyNvBZDJfAo5h+DJvofbJcIa9b
+        u0jYuG1j1YaFko01rNu4g7u7YCHexwe7GAvxYYiPQtwLsRRi8jmnoznY6gcA
         AA==
         """,
         """
         androidx/compose/animation/AnimatedContentKt$AnimatedContent$4.class:
         H4sIAAAAAAAA/6VUW08TQRT+Zru9Um1B5eYdEVpAFiryYBsiqRA2VkykaWJ4
-        mnYXGLo7Y7rbBt949Hf4CyQ+kGhiiI/+KOOZpRqDqDEk2zPffucyM+c726/f
-        Pn4GsIRlhhUunY4SzoHVUv5rFbgWl8LnoVDSWo2Q61SVDF0ZPgsnzzCTS0kw
-        hqe1tgo9Ia39nm8J8nQk96wa95sOL//q2+nKlq4cWOt9tFip18v0rJQZxv9c
-        JQmT4dbfKyWRYEhUhBThCkOsUGwwmAW72MgihUwGcQwQEe6JgOFJ7WLXptMm
-        hOyptsswVajt8x63PC53rRfNfbcVlou/UwypAl20SD8GQ4QMQ+cGVVpedAV9
-        6nQGBq4RaW9u1Vc3q2tZjOBymshRhsEfnX3uhtzhIdd1/V6MlGXapLQBA2tr
-        ECPngdBogZCzyDB9cmhmjFQ8f3I4bmywCTN1cphnpUTe0K8bmS/vEmYqljd1
-        eIlhoMKlkm981Q2ovazOMPc/PUyiwDBytpGOu8O7HvXi7TlN/MfkXNBfKtvn
-        6EbDMoNZ0ubMSefbdEizqhxX66Za3GvwjuBNz61rw5CrCeludv2m2+kz6S2x
-        K3nY7RDO2lK6narHg8Cl8cutyZanAiF3Sbs95TBktlS303LXhc4ce9mVofDd
-        hggElVqVUoVRWwMskPZxEpW+O4zpYdDSarGRJmae0CRFMFoTM+YxskfRCFhk
-        s6csLkU5g8ghT5E6Y5k8Bq3G7HttaQ8dp6PHo8zhU28/U6MhXCH/YoQHae+r
-        P3cfiWKBgU8wXh1j+APGjiIijhLZTH8rYBQPyZooYq5fKEZ/SHp9gEe0PqbI
-        ccq6vo2YjRs2btq4hds27uCujQnc2wYL6LL3txEPMBVgOsBQgFyA/Hcf0VY3
-        3wQAAA==
+        mnYXGLo7Y7rbBt949Hf4CyQ+kGhiiI/+KOOZpRqDqDEkO+d8+53LzJxzdr9+
+        +/gZwBKWGVa4dDpKOAdWS/mvVeBaXAqfh0JJazVCrlNVMnRl+CycPMNMLiXB
+        GJ7W2ir0hLT2e74lyNKR3LNq3G86vPyrbacrWzpzYK330WKlXi/Ts1JmGP9z
+        liRMhlt/z5REgiFREVKEKwyxQrHBYBbsYiOLFDIZxDFARLgnAoYntYtdm06b
+        ELKn2i7DVKG2z3vc8rjctV40991WWC7+TjGkCnTRIi0GQ4QMQ+c6VVpedAV9
+        6nQGBq4RaW9u1Vc3q2tZjOBymshRhsEflX3uhtzhIdd5/V6MOsu0SGsBBtbW
+        IEbGA6HRAiFnkWH65NDMGKl4/uRw3NhgE2bq5DDPSom8oV83Ml/eJcxULG9q
+        9xLDQIVLJd/4qhtQeVmdYe5/aphEgWHkbCEdd4d3ParF23OK+I/JuaC9VLbP
+        6RsNywxmqTdnTjrfpkOaVeW4um+qxb0G7wje9Ny6Fgy5mpDuZtdvup0+k94S
+        u5KH3Q7hrC2l26l6PAhcGr/cmmx5KhByl3q3pxyGzJbqdlruutCRYy+7MhS+
+        2xCBoFSrUqowKmuABep9nJpK3x3G9DDo1tKiWSFmntAkeTDSiRnzGNmjaAQs
+        ktlTFpeimEHkkCdPHbFMFoO0MfteS9pD+2nv8Shy+NTaj9RoCFfIvhjhQdr7
+        6s/dRyJfYOATjFfHGP6AsaOIiKNEMtPfChjFQ5ImipjrJ4rRD0nrB3hE+jF5
+        jlPU9W3EbNywcdPGLdy2cQd3bUzg3jZYQJe9v414gKkA0wGGAuQC5L8D/xWd
+        4d8EAAA=
         """,
         """
         androidx/compose/animation/AnimatedContentKt.class:
@@ -180,75 +180,75 @@
         05SaDzo1FsQNBjVfKJZmCrNzDA8ucalPypeL4CbeCqEfA8ev3wmUg0hdFX82
         iLevDDrrgh4M4Q7uRtCGQBgKhhnqJ1XAa2jAc6c04CPd4/++eoG+2u5we113
         itQjdQatFQvDD//CJ/5HCnk8iOyVC2HcLYSJEMbxzlUBTQTx3pUBTbiA3g/h
-        PiZlZY7Kypxi6N4/4yXd4RXucPqUSm3bRy81JoUqBRjYpjQUcu4Y0sqQVRlj
-        7One7mR4bzesRJWwovrCSp9y7F+6PBUl4Q2Pe5OvvmfkTCoZNuBX93ajSjYQ
-        9SWVBSWbUJWoPxnT/JqSCbgymGl79UtAUdXsbfKFkv1aTOteUGguooY1VW3X
-        /Ko66NMouo9lIpm27EC0I3nDXdsl5YLi2izT6eaJNrItBKWOdidfHEcypDbW
-        ZLTXiUUeLl1Cee4lWW/eNzr6U3xmkzmnPzGc2RlaWhT9/uxDmNshl6CofSyl
-        527Cnv2Ag3dPgRQ5/CbpEzjIt8LYpfsTJWqav7dJTwv/rFWhTboWDVMv1Gur
-        ul2SLz25rVXm1WVuG3LsTYaKxrrJnbpN9vUnjfdh3tw2hEHumcOnIEOq2XvA
-        7lhYBzXG8uYS3/I2iORNU7dnq1wIndzholW3y/q8IX0JL+Vyy3YYo5L0y3Ij
-        mZC/nqSf0oh784khrf0luoe1GMkRLU5yVOsl+assTSyTDNCV6YOGz8keaiyi
-        ccJNmqD5JPmldY0sxbV6cB0+fOFmCOJLL4dK+ivp99Mg5HaAJhkN4Q28SbZE
-        uExbBUin4n7/i58Q/g239ugxHve3NUZDNFoaGh4ZfYmRBtgVl6XS2eHC7iG2
-        QIQAdNAbOII4opQ94p7CqHcKK94pxM7jr9HSQ/4xpJFx+ccO+McO+MeO8b/X
-        wj/uP5X7WCt3j+27De7Bxih3yP2D07nHiXsvcY/TX5KyxwnU1zQ/QJH9Lvw+
-        elQ19Lin73v6GzdrCd+SrhCqacr44Qp8eTzIYyaPjzCbx8eYy2Men6yACSwg
-        v4KYQJvApwIPBdICmsCiwJJAQeCRwDWBxwKfuQE9Ak8EigKqwKhA4m9XPfx7
+        PiZlZY7Kypxi6N4/4yXd4RXucPqUSm3bRy81JkVICjCwTWko5NwxpJUhqzLG
+        2NO93cnw3m5YiSphRfWFlT7l2L90eSpKwhse9yZffc/ImVQybMCv7u1GlWwg
+        6ksqC0o2oSpRfzKm+TUlE3BlMNP26peAoqrZ2+QLJfu1mNa9oNBcRA1rqtqu
+        +VV10KdRdB/LRDJt2YFoR/KGu7ZLygXFtVmm080TbWRbCEod7U6+OI5kSG2s
+        yWivE4s8XLqE8txLst68b3T0p/jMJnNOf2I4szO0tCj6/dmHMLdDLkFR+1hK
+        z92EPfsBB++eAily+E3SJ3CQb4WxS/cnStQ0f2+Tnhb+WatCm3QtGqZeqNdW
+        dbskX3pyW6vMq8vcNuTYmwwVjXWTO3Wb7OtPGu/DvLltCIPcM4dPQYZUs/eA
+        3bGwDmqM5c0lvuVtEMmbpm7PVrkQOrnDRatul/V5Q/oSXsrllu0wRiXpl+VG
+        MiF/PUk/pRH35hNDWvtLdA9rMZIjWpzkqNZL8ldZmlgmGaAr0wcNn5M91FhE
+        44SbNEHzSfJL6xpZimv14Dp8+MLNEMSXXg6V9FfS76dByO0ATTIawht4k2yJ
+        cJm2CpBOxf3+Fz8h/Btu7dFjPO5va4yGaLQ0NDwy+hIjDbArLkuls8OF3UNs
+        gQgB6KA3cARxRCl7xD2FUe8UVrxTiJ3HX6Olh/xjSCPj8o8d8I8d8I8d43+v
+        hX/cfyr3sVbuHtt3G9yDjVHukPsHp3OPE/de4h6nvyRljxOor2l+gCL7Xfh9
+        9Khq6HFP3/f0N27WEr4lXSFU05TxwxX48niQx0weH2E2j48xl8c8PlkBE1hA
+        fgUxgTaBTwUeCqQFNIFFgSWBgsAjgWsCjwU+cwN6BJ4IFAVUgVGBxN8a7RIf
         yw8AAA==
         """,
         """
         androidx/compose/animation/AnimatedContentScope.class:
-        H4sIAAAAAAAA/5VRu04CQRQ9d5BFVxTEFz5rtXDF2GlM1MSEBDVRQ2M17E50
-        gJ0h7EAo+Rb/wMrEwhBLP8p4d7Wyszk5jzu5j/n8ensHcIQtQiBN1Lc6GgWh
-        jXs2UWzoWDptTXCWMRVdWOOUcXeh7akCiFBuy6EMutI8BjettgpdATmCd6KN
-        dqeE3M5us4g8PB9TKBCm3JNOCLXGP3sdExYaHeu62gRXyslIOsmeiIc5Hp9S
-        mE4BBOqwP9KpOmAW1Qjbk7Hvi6rwRZnZZFydjA/FAZ3nP549URZp1SGlbyt/
-        eu93HM98YSNFKDW0UdeDuKX697LVZafSsKHsNmVfp/rX9O/soB+qS52KtduB
-        cTpWTZ1oTs+MsS5bMkENgk/yO3J6IcYqqyDTQH7vFdMvTATWGL3M9LDOWPwp
-        wAz8LN/IcBWb2U8SZjkrPiBXx1wd83WUUGaKhToqWHwAJVjCMucJ/AQrCbxv
-        L9u6lAYCAAA=
+        H4sIAAAAAAAA/5VRu04CQRQ9d5BFV1TEF/iq1cIVY6cxURMTEtREDA3VsDvR
+        AXbGsIOx5Fv8AysTC0Ms/Sjj3ZXKzubkPO7kPubr+/0DwBG2CIE00cDq6DkI
+        bfxoE8WGjqXT1gRnGVPRhTVOGdcM7aMqgAilrnySQV+a++Cm01WhKyBH8E60
+        0e6UkNvZbRWRh+djCgXClHvQCaHW+GevY8Jio2ddX5vgSjkZSSfZE/FTjsen
+        FGZSAIF67D/rVB0wi2qE7fHI90VF+KLEbDyqjEeH4oDO858vniiJtOqQ0rfl
+        P733e45nvrCRIiw0tFHXw7ijBney02en3LCh7LfkQKd6YvpNOxyE6lKnono7
+        NE7HqqUTzemZMdZlSyaoQfBJJiOnF2KssAoyDeT33jD9ykSgyuhlpod1xuJv
+        AWbgZ/lGhmvYzH6SMMtZsY1cHXN1zNexgBJTLNZRxlIblGAZK5wn8BOsJvB+
+        APKoOCQGAgAA
         """,
         """
         androidx/compose/animation/AnimatedContentTransitionScope.class:
-        H4sIAAAAAAAA/51Ru04bQRQ9d4zXzsaAMZCYJKQGChYQDTJCAqRIlhyQAnJD
-        Nd4dwdjeGbQzRpT+Fv6ACilFZFHmoyLuLFQpaY7O447uY/7++/0HwD7WCQfS
-        ZIXV2X2S2vzWOpVIo3PptTXJcclUdmqNV8ZfFtI4HZKL1N6qGojQHMo7mYyl
-        uU7OB0OV+hoqhOhQG+2PCJWNzX4DVUQx5lAjzPkb7Qid3ru7dghLvZH1Y22S
-        n8rLTHrJnsjvKrwSBagHAIFG7N/roHaYZbuE77NpHIu2iEWT2Wzank33xA6d
-        VJ8fItEUoWqPwtvWf1NsjzxPf2ozRVjsaaPOJvlAFZdyMGan1bOpHPdloYN+
-        M+MLOylS9UMHsfZrYrzOVV87zemxMdaX6zrsQvBx3kYOt2Jss0pKDVS3nlB/
-        ZCKwxhiVZg1fGBuvBfiAuMy/lvgZ38rfJXzkrHGFShfzXSx0sYgmUyx10cLy
-        FchhBaucO8QOnxyiF5mdAVoaAgAA
+        H4sIAAAAAAAA/51Ru04bQRQ9d4zXsDFgHB4mCakTChasNAiEBEhIlhyQAnJD
+        Nd4dwdjeGbQzRi79LfxBKqQUkZWSj0LcWahS0hydxx3dxzw9//kL4Ae2CPvS
+        ZIXV2SRJbX5nnUqk0bn02prkuGQqO7XGK+OvCmmcDsllau9UDURoDOS9TEbS
+        3CQX/YFKfQ0VQnSojfZHhMq37706qohizKFGmPO32hEOuu/uekBY6Q6tH2mT
+        /FReZtJL9kR+X+GVKMBCABBoyP5EB7XLLNsjfJ1N41i0RCwazGbT1mzaFrt0
+        Uv33EImGCFVtCm+b/02xM/Q8/anNFGG5q406H+d9VVzJ/oidZtemctSThQ76
+        zYwv7bhI1ZkOYvPX2Hidq552mtNjY6wv13XYg+DjvI0cbsXYYpWUGqhuP2L+
+        NxOBTcaoNGv4xFh/LcAC4jL/XOIGvpS/S/jAWf0alQ4WO1jqYBkNpljpoImP
+        1yCHVaxx7hA7rDtEL0Tug+oaAgAA
         """,
         """
         androidx/compose/animation/ContentTransform.class:
-        H4sIAAAAAAAA/5VRy24aMRQ918BApzQQ2qbQ17pJlAyg7FpVIkiRkGgrtYgN
-        K8O4rYGxo7GJWPIt/YOsKnURoSzzUVXuTPiBbI7Ow9Y9vr77/+8GwBneEY6l
-        iVOr43U0s8mldSqSRifSa2uivjVeGT9KpXE/bZqUQYT6XF7JaCnNr+jbdK5m
-        vowCIfikjfafCYUPh+MqSghCFFEmFP1v7Qgnw0fM+UjYHy6sX2oTfVFextJL
-        9kRyVeDalEElAxBowf5aZ6rNLO4Q3m83YSiaIhR1ZttNc7vpijadl27/BKIu
-        slNdyu42enkDFe/mny489+3bWBFqQ23U11UyVelITpfsNIZ2JpdjmepM78zw
-        h12lM3WhM9H6vjJeJ2qsnea0Z4z1+QMdOhC8jl3lbDuMTVZRroHS0V9UrpkI
-        tBiD3KzgNWP14QCeIMzzNzm+wtv8BwlPOatOUBjg2QB7A9RQZ4r9ARp4PgE5
-        vMBLzh1ChwOH4B4M81bb/gEAAA==
+        H4sIAAAAAAAA/5VRy04bMRQ910kmYUibBy0N0HbNQzCA2BUhBaRKkQJIgLJh
+        5WQMOMnYaOwglvkW/oAVEgsUsexHVb0z5Ae6OToPW/f4+s/f1zcAB/hB2JIm
+        Tq2OH6OBTe6tU5E0OpFeWxOdWOOV8VepNO7GpkkZRKgP5YOMxtLcRuf9oRr4
+        MgqE4FAb7Y8IhfWNXhUlBCGKKBOK/k47wnb3P+b8IjS6I+vH2kSnystYesme
+        SB4KXJsyWMgABBqx/6gztcss3iP8nE3DULREKOrMZtPWbLovdum49P4UiLrI
+        Tu1TdrfZzhuoeD5/Z+S574mNFaHW1UadTZK+Sq9kf8xOs2sHctyTqc703Awv
+        7SQdqN86EysXE+N1onraaU7bxlifP9BhD4LXMa+cbYexxSrKNVDafEHlmYnA
+        CmOQmxWsMlY/DmABYZ6v5fgN3/MfJCxyVr1GoYNPHXzuoIY6UzQ6aGLpGuTw
+        BV85dwgdlh2Cf9GA1Gv+AQAA
         """,
         """
         androidx/compose/animation/Transition.class:
-        H4sIAAAAAAAA/41SXU8TQRQ9s7vdbtdCtwUUEL9QZFvUBeKDQYJBEpImVRPa
-        NCY8De2mDrSzZmdKeOyTP8RfoInGxAfT8OiPMt5dNkiERF/uPffMmTP33t2f
-        v77/APAUjxiWuOzGkeieBJ1o8D5SYcClGHAtIhm0Yi6VSGAejMHfbG40Dvkx
-        D/pc9oI3B4dhRz/fukwxeH9zeVgM9qaQQm8xzPiXL1XbJPBbzRSYfrVdhI2C
-        ixxcOtA87oWaoXL5YhFFTBRgYJLB0u+EYlhu/NdU1GiBXFuZ97RfvWqWnF+l
-        rkiq/kjzm1Q8fkGjmOlZuXEU6b6QwatQ8y7XnDhjcGzSllkSnCSAgR0RfyKS
-        apVQd42hOR5Nusas4Y5HruElwbFnx6Oa5YxHHls3Vo2XExXbM+eNZ+PR6Ufb
-        8Ky9hax8e/phkiiPLjrzlpPz7EXLyXtWYr1OrzVZ8mhlO5097O5EUodSPzmi
-        CQpN0ZNcD+OQtrYTdSmVGkKGr4eDgzBu8YN+mGw76vB+m8ciqTPSbUbDuBPu
-        iqSY2xtKLQZhWyhBp9tSRjpds8IafZJcOrWRfCHKD6kycAMmYRt5wsvEbFE2
-        KLu1b7hWW/mK0udU51O0SQkUUKV4/UwFD+VkmYQuujrEVjCVeQbJrinnal9Q
-        +nSlXfFMkNmdmUwTnjlvbCNrzP5nU/Z5UzYxF5syM2SiluYlrFDeJcUsvT23
-        D7OO+Tpu1rGAWwRxu447uLsPpnAPi/v016GscF/hgUJRIa9QUZhSmFGY+A05
-        DzSHyAMAAA==
+        H4sIAAAAAAAA/41SXU8TQRQ9s7vdtmuhSwEFxC8U2RZ1gfhgkGCQhKRJ1YQ2
+        jQlPQ7vBgXbW7EwJj33yh/gLNNGY+GAaHv1RxjvLBomQ6Mu95545c+beu/vz
+        1/cfAJ7iEcMil90kFt2TsBP338cqCrkUfa5FLMNWwqUSBubBGIKN5nrjkB/z
+        sMflQfhm/zDq6OeblykG/28uD4fB3RBS6E2G6eDypWqbBEGrmQI7qLZLcFH0
+        kINHB5onB5FmqFy+WEIJY0VYGGdw9DuhGJYa/zUVNVok11bmPRVUr5olF1Sp
+        K5KqP9L8BhWPX9Aodno20TiKdU/I8FWkeZdrTpzVP7Zpy8yEoglgYEfEnwhT
+        rRDqrjI0R8Nxz5qxvNHQs3wTCu7MaFhzCqOhz9asFevlWMX17Tnr2Wh4+tG1
+        fGd3Pivfnn4YJ8qni4U5p5Dz3QWnkPcdY71GrzWZebSylc4edbdjqSOpnxzR
+        BMWmOJBcD5KItrYddymVG0JGrwf9/Shp8f1eZLYdd3ivzRNh6oz0mvEg6UQ7
+        whSzuwOpRT9qCyXodEvKWKdrVlilT5JLp7bMF6L8kCoLN2ATdpEnvETMJmWL
+        slf7hmu15a8of051AUWXlLQ9VCleP1PBx4RZJqGLrgViK5jMPEOza8q52heU
+        P11pVzoTZHZnJlOEp88bW88ac//ZlHvelEvMxabsDNmopXkRy5R3SDFDb8/u
+        wa5jro6bdczjFkHcruMO7u6BKdzDwh79dZhQuK/wQKGkkFeoKEwqTCuM/QaR
+        /XoCyAMAAA==
         """
     )
 
diff --git a/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt b/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt
index d6d0b38..8454999 100644
--- a/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt
+++ b/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/CrossfadeDetectorTest.kt
@@ -43,7 +43,7 @@
     private val CrossfadeStub = bytecodeStub(
         filename = "Transition.kt",
         filepath = "androidx/compose/animation",
-        checksum = 0x33cac1e3,
+        checksum = 0x15a87088,
         """
             package androidx.compose.animation
 
@@ -57,27 +57,27 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcUllZiXUpSfmVKhl5yfW5BfnKqX
-        mJeZm1iSmZ8nxBNSlJhXnAlie5dw8XIxp+XnC7GFpBaXeJcoMWgxAACekN3e
-        UwAAAA==
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uKSSsxLKcrPTKnQS87PLcgvTtVL
+        zMvMTSzJzM8T4gkpSswrzgSxvUu4eLmY0/LzhdhCUotLvEuUGLQYAEjDUx5T
+        AAAA
         """,
         """
         androidx/compose/animation/TransitionKt.class:
-        H4sIAAAAAAAAAIVSW08TQRT+ZnvZdgFZyr0oIhcBUbcQfLHExJAQGisYW3nh
-        abpd6vQya3amDY/9Lf4D34wPpvHRH2U8s1RBasIme86Zb77znTNn5uevb98B
-        7OMpwyaX9SgU9UvPDzufQhV4XIoO1yKUXjXiUgkTvtE2GIPb5D3utblseKe1
-        ZuATmmDIHkahUhe8HjC82Crf5hTLrVC3hfSavY530ZW+EVTe0TDaLW6fMZwe
-        VF+OZr7aqlbvSj94doPzQQrKihU3yiMni7pSi07gHcZrXmsHRYa1chg1vGag
-        axEXJMylDDW/KnIS6pNuu00s2w+lDqTOwGFYvtGRIDiSvO2VpI4oX/jKxjjD
-        rP8x8FtDgXc84p2AiDTv/w3oGqkYkQYdYBz3MOlgAi7DmOZRI9AVaotGnBsV
-        YFi5a8gMU38obwPN61xzwqxOL0EvgRmTYmAtE1iEXwoTFSiq7zJUBv0ZZ9B3
-        LNdyrEzCsRas+B/08/suGavAVpOZQd+19tJuIm8dW3vzbjI/nUvmKDa2wAqp
-        H5/TViZ9bBvv2kZ6j1FtsKo51LC5mx1PXD/A5y3NkDwMzRubLAsZnHQ7tSCq
-        mks02aHP22c8EmY9BLMV0ZBcdyOKl95fXX1J9oQStP36+pYZ1m/v/r2vf2hO
-        JexGfnAkjPriMOdsRA+7sJCE+YiGFNK0WqdVkXCLvL2TG/uKqS9m1NggmyZi
-        Gg4eUzx3RUEO07GETfgM7W/GbBtbQ36G/Db9WSuuk423n8R2DTvkDwmdpepz
-        50iUMF/CAlkslpDHUgn38eAcTGEZD8+RUUgprCg8UsgpOAqryoDp38bsatcp
-        BAAA
+        H4sIAAAAAAAA/4VSW08TQRT+Zlq67QKylHvxglwERNxC8MUSE9OE0FjB2MoL
+        T9PtUqeXWbM7bXjsb/Ef+GZ8MI2P/ijjmW0VBBMe5syZ73znmzPnzM9f374D
+        OMAuw6ZQ9TCQ9UvXCzqfgsh3hZIdoWWg3GooVCSN+0ZbYAxOU/SE2xaq4Z7W
+        mr5HaIIhUwyDKLoQdZ/hxVb5JqdQbgW6LZXb7HXci67yjGDkHo28vcL2GcPp
+        YfXl7cxXW9XqXemHu9c4H5SkrFhxo3zrZWFXadnx3WJ8FrW2X2BYKwdhw236
+        uhYKScJCqUCL4SUngT7pttvEsrxAaV/pNGyGh9cqkgSHSrTdktIh5UsvsjDB
+        MOd99L3WSOCdCEXHJyL1+38NukIqRqRBD5jAPUzZmITDMK5F2PB1hcqiFmdv
+        CzCs3NVkhuk/lLe+FnWhBWG800vQT2DGZIwBA2sZh1PwUhovT159j6Ey6M/a
+        g77NHW7zdMLmizxeg37uwCHD82w1mR70Hb6fchI5fsz3F5xkbiabzJJvbJ7l
+        x358TvF06tgyu2MZ6X0W31o1LxtVeL3syatf+LylGZLFwHy0qbJU/km3U/PD
+        qpmkyQ480T4ToTTnEZipyIYSuhuSv/x+OP+S6slIUvj11agZ1m9G/w7tH5pd
+        Cbqh5x9Jo740yjm7pYc9cCQx7OgSxpCi0wadCoRz2q2d7PhXTH8xrcYTsiki
+        pmBjk/z5IQVZzMQSFuGzFN+K2Ra2R/w07U/N6Hh8TyYO78R2Hc9oLxI6R7fP
+        nyNRwkIJiyWqJlfCMu6X8AAPz8EiPMLKOdIRxiI8jrAaIRvBjrAWGTD1G1Xc
+        nh8uBAAA
         """
     )
 
diff --git a/compose/animation/animation/api/current.txt b/compose/animation/animation/api/current.txt
index 2e7140c..f8817a9 100644
--- a/compose/animation/animation/api/current.txt
+++ b/compose/animation/animation/api/current.txt
@@ -19,8 +19,6 @@
   public sealed interface AnimatedContentTransitionScope<S> extends androidx.compose.animation.core.Transition.Segment<S> {
     method public androidx.compose.ui.Alignment getContentAlignment();
     method public default androidx.compose.animation.ExitTransition getKeepUntilTransitionsFinished(androidx.compose.animation.ExitTransition.Companion);
-    method @SuppressCompatibility @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.EnterTransition scaleInToFitContainer(optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale);
-    method @SuppressCompatibility @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.ExitTransition scaleOutToFitContainer(optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale);
     method public androidx.compose.animation.EnterTransition slideIntoContainer(int towards, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialOffset);
     method public androidx.compose.animation.ExitTransition slideOutOfContainer(int towards, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetOffset);
     method public infix androidx.compose.animation.ContentTransform using(androidx.compose.animation.ContentTransform, androidx.compose.animation.SizeTransform? sizeTransform);
diff --git a/compose/animation/animation/api/restricted_current.txt b/compose/animation/animation/api/restricted_current.txt
index 2e7140c..f8817a9 100644
--- a/compose/animation/animation/api/restricted_current.txt
+++ b/compose/animation/animation/api/restricted_current.txt
@@ -19,8 +19,6 @@
   public sealed interface AnimatedContentTransitionScope<S> extends androidx.compose.animation.core.Transition.Segment<S> {
     method public androidx.compose.ui.Alignment getContentAlignment();
     method public default androidx.compose.animation.ExitTransition getKeepUntilTransitionsFinished(androidx.compose.animation.ExitTransition.Companion);
-    method @SuppressCompatibility @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.EnterTransition scaleInToFitContainer(optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale);
-    method @SuppressCompatibility @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.ExitTransition scaleOutToFitContainer(optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale);
     method public androidx.compose.animation.EnterTransition slideIntoContainer(int towards, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialOffset);
     method public androidx.compose.animation.ExitTransition slideOutOfContainer(int towards, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetOffset);
     method public infix androidx.compose.animation.ContentTransform using(androidx.compose.animation.ContentTransform, androidx.compose.animation.SizeTransform? sizeTransform);
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/ContainerTransform.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/ContainerTransform.kt
deleted file mode 100644
index cf03291..0000000
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/ContainerTransform.kt
+++ /dev/null
@@ -1,246 +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.compose.animation.demos.layoutanimation
-
-import androidx.compose.animation.AnimatedContent
-import androidx.compose.animation.ExperimentalAnimationApi
-import androidx.compose.animation.core.animateDpAsState
-import androidx.compose.animation.core.animateIntAsState
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
-import androidx.compose.animation.togetherWith
-import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Icon
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.RadioButton
-import androidx.compose.material.Text
-import androidx.compose.material.TextField
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
-import androidx.compose.material.icons.filled.AccountCircle
-import androidx.compose.material.icons.filled.Add
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.vector.rememberVectorPainter
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-
-@OptIn(ExperimentalAnimationApi::class)
-@Preview
-@Composable
-fun LocalContainerTransformDemo() {
-    Box(Modifier.fillMaxSize()) {
-        LazyColumn {
-            items(20) {
-                Box(
-                    Modifier
-                        .fillMaxWidth()
-                        .height(150.dp)
-                        .padding(15.dp)
-                        .background(MaterialTheme.colors.primary)
-                )
-            }
-        }
-    }
-    var selectedAlignment by remember { mutableStateOf(Alignment.Center) }
-    var contentScale by remember { mutableStateOf(ContentScale.FillWidth) }
-    Column(
-        Modifier.padding(top = 100.dp)
-    ) {
-        Column(
-            Modifier
-                .background(Color.LightGray, RoundedCornerShape(10.dp)),
-        ) {
-            Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
-                RadioButton(
-                    selected = selectedAlignment == Alignment.TopStart,
-                    onClick = { selectedAlignment = Alignment.TopStart }
-                )
-                Text("TopStart", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = selectedAlignment == Alignment.TopCenter,
-                    onClick = { selectedAlignment = Alignment.TopCenter }
-                )
-                Text("TopCenter", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = selectedAlignment == Alignment.TopEnd,
-                    onClick = { selectedAlignment = Alignment.TopEnd }
-                )
-                Text("TopEnd", Modifier.padding(5.dp))
-            }
-            Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
-                RadioButton(
-                    selected = selectedAlignment == Alignment.CenterStart,
-                    onClick = { selectedAlignment = Alignment.CenterStart }
-                )
-                Text("CenterStart", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = selectedAlignment == Alignment.Center,
-                    onClick = { selectedAlignment = Alignment.Center }
-                )
-                Text("Center", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = selectedAlignment == Alignment.CenterEnd,
-                    onClick = { selectedAlignment = Alignment.CenterEnd }
-                )
-                Text("CenterEnd", Modifier.padding(5.dp))
-            }
-            Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
-                RadioButton(
-                    selected = selectedAlignment == Alignment.BottomStart,
-                    onClick = { selectedAlignment = Alignment.BottomStart }
-                )
-                Text("BottomStart", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = selectedAlignment == Alignment.BottomCenter,
-                    onClick = { selectedAlignment = Alignment.BottomCenter }
-                )
-                Text("BottomCenter", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = selectedAlignment == Alignment.BottomEnd,
-                    onClick = { selectedAlignment = Alignment.BottomEnd }
-                )
-                Text("BottomEnd", Modifier.padding(5.dp))
-            }
-        }
-        Column(
-            Modifier
-                .background(Color.Gray, RoundedCornerShape(10.dp)),
-        ) {
-            Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
-                RadioButton(
-                    selected = contentScale == ContentScale.FillWidth,
-                    onClick = { contentScale = ContentScale.FillWidth }
-                )
-                Text("FillWidth", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = contentScale == ContentScale.FillHeight,
-                    onClick = { contentScale = ContentScale.FillHeight }
-                )
-                Text("FillHeight", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = contentScale == ContentScale.FillBounds,
-                    onClick = { contentScale = ContentScale.FillBounds }
-                )
-                Text("FillBounds", Modifier.padding(5.dp))
-            }
-            Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
-                RadioButton(
-                    selected = contentScale == ContentScale.Crop,
-                    onClick = { contentScale = ContentScale.Crop }
-                )
-                Text("Crop", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = contentScale == ContentScale.Fit,
-                    onClick = { contentScale = ContentScale.Fit }
-                )
-                Text("Fit", Modifier.padding(5.dp))
-                RadioButton(
-                    selected = contentScale == ContentScale.Inside,
-                    onClick = { contentScale = ContentScale.Inside }
-                )
-                Text("Inside", Modifier.padding(5.dp))
-            }
-        }
-    }
-    Box(Modifier.fillMaxSize()) {
-        var target by remember { mutableStateOf(ContainerState.FAB) }
-        // Corner radius
-        val cr by animateIntAsState(if (target == ContainerState.FAB) 50 else 0)
-        val padding by animateDpAsState(if (target == ContainerState.FAB) 10.dp else 0.dp)
-        AnimatedContent(
-            target,
-            label = "",
-            transitionSpec = {
-                fadeIn(tween(200, delayMillis = 100)) +
-                    scaleInToFitContainer(selectedAlignment, contentScale) togetherWith
-                    fadeOut(tween(100)) + scaleOutToFitContainer(selectedAlignment, contentScale)
-            },
-            modifier = Modifier
-                .align(Alignment.BottomEnd)
-                .padding(padding)
-                .clip(RoundedCornerShape(cr))
-                .background(Color.White)
-        ) {
-            if (it == ContainerState.FAB) {
-                Icon(
-                    rememberVectorPainter(image = Icons.Default.Add),
-                    null,
-                    modifier = Modifier
-                        .clickable {
-                            target = ContainerState.FullScreen
-                        }
-                        .padding(20.dp))
-            } else {
-                Column(Modifier.fillMaxSize()) {
-                    Icon(
-                        rememberVectorPainter(image = Icons.AutoMirrored.Filled.ArrowBack),
-                        null,
-                        modifier = Modifier
-                            .clickable {
-                                target = ContainerState.FAB
-                            }
-                            .padding(20.dp))
-                    Spacer(Modifier.height(60.dp))
-                    Text("Page Title", fontSize = 20.sp, modifier = Modifier.padding(20.dp))
-                    Spacer(
-                        Modifier
-                            .fillMaxWidth()
-                            .height(2.dp)
-                            .background(Color.LightGray)
-                    )
-                    Row(
-                        Modifier
-                            .fillMaxWidth()
-                            .padding(20.dp)
-                    ) {
-                        Icon(rememberVectorPainter(image = Icons.Default.AccountCircle), null)
-                        Spacer(Modifier.width(20.dp))
-                        TextField(value = "Account Name", onValueChange = {})
-                    }
-                }
-            }
-        }
-    }
-}
-
-private enum class ContainerState {
-    FAB,
-    FullScreen
-}
diff --git a/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/AnimatedContentSamples.kt b/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/AnimatedContentSamples.kt
index c9c4f15..b9eeaff 100644
--- a/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/AnimatedContentSamples.kt
+++ b/compose/animation/animation/samples/src/main/java/androidx/compose/animation/samples/AnimatedContentSamples.kt
@@ -22,7 +22,6 @@
 import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection
 import androidx.compose.animation.ContentTransform
 import androidx.compose.animation.ExitTransition
-import androidx.compose.animation.ExperimentalAnimationApi
 import androidx.compose.animation.SizeTransform
 import androidx.compose.animation.core.animateDp
 import androidx.compose.animation.core.keyframes
@@ -55,7 +54,6 @@
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
@@ -309,30 +307,6 @@
     }
 }
 
-@OptIn(ExperimentalAnimationApi::class)
-@Suppress("UNUSED_VARIABLE")
-@Sampled
-@Composable
-fun ScaleInToFitContainerSample() {
-    // enum class CartState { Expanded, Collapsed }
-    // This is an example of scaling both the incoming content and outgoing content to fit in the
-    // animating container size while animating alpha.
-    val transitionSpec: AnimatedContentTransitionScope<CartState>.() -> ContentTransform = {
-        // Fade in while scaling the content.
-        fadeIn() + scaleInToFitContainer() togetherWith
-            // Fade out outgoing content while scaling it. It is important
-            // to combine `scaleOutToFitContainer` with another ExitTransition that defines
-            // a timeframe for the exit (such as fade/shrink/slide/Hold).
-            fadeOut() + scaleOutToFitContainer(
-                // Default alignment is the content alignment defined in AnimatedContent
-                Alignment.Center,
-                // Content will be scaled based on the height of the content. Default content
-                // scale is ContentScale.FillWidth.
-                ContentScale.FillHeight
-            )
-    }
-}
-
 private enum class CartState {
     Expanded,
     Collapsed
diff --git a/compose/animation/animation/src/androidInstrumentedTest/kotlin/androidx/compose/animation/AnimatedContentTest.kt b/compose/animation/animation/src/androidInstrumentedTest/kotlin/androidx/compose/animation/AnimatedContentTest.kt
index 0568edf..56d0163 100644
--- a/compose/animation/animation/src/androidInstrumentedTest/kotlin/androidx/compose/animation/AnimatedContentTest.kt
+++ b/compose/animation/animation/src/androidInstrumentedTest/kotlin/androidx/compose/animation/AnimatedContentTest.kt
@@ -51,19 +51,13 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.LookaheadScope
 import androidx.compose.ui.layout.SubcomposeLayout
-import androidx.compose.ui.layout.boundsInRoot
-import androidx.compose.ui.layout.layout
 import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.layout.onPlaced
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
@@ -72,7 +66,6 @@
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.round
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
@@ -789,334 +782,6 @@
     }
 
     @Test
-    fun testScaleToFitDefault() {
-        var target by mutableStateOf(1)
-        var box1Coords: LayoutCoordinates? = null
-        var box2Coords: LayoutCoordinates? = null
-        var box1Disposed = true
-        var box2Disposed = true
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                AnimatedContent(
-                    targetState = target,
-                    transitionSpec = {
-                        if (1 isTransitioningTo 2) {
-                            fadeIn(tween(300)) + scaleInToFitContainer() togetherWith
-                                scaleOutToFitContainer()
-                        } else {
-                            fadeIn() + scaleInToFitContainer() togetherWith
-                                fadeOut(tween(150))
-                        } using SizeTransform { initialSize, targetSize ->
-                            keyframes {
-                                durationMillis = 300
-                                initialSize at 100 using LinearEasing
-                                targetSize at 200 using LinearEasing
-                            }
-                        }
-                    }) {
-                    if (it == 1) {
-                        Box(
-                            Modifier
-                                .onPlaced {
-                                    box1Coords = it
-                                }
-                                .size(200.dp, 400.dp)) {
-                            DisposableEffect(key1 = Unit) {
-                                box1Disposed = false
-                                onDispose {
-                                    box1Disposed = true
-                                }
-                            }
-                        }
-                    } else {
-                        Box(
-                            Modifier
-                                .onPlaced { box2Coords = it }
-                                .size(100.dp, 50.dp)) {
-
-                            DisposableEffect(key1 = Unit) {
-                                box2Disposed = false
-                                onDispose {
-                                    box2Disposed = true
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        rule.waitForIdle()
-        rule.mainClock.autoAdvance = false
-        assertEquals(IntSize(200, 400), box1Coords?.size)
-        assertNull(box2Coords)
-
-        assertFalse(box1Disposed)
-        assertTrue(box2Disposed)
-
-        rule.runOnIdle {
-            // Start transition from 1 -> 2, size 200,400 -> 100,50
-            target = 2
-        }
-        rule.mainClock.advanceTimeByFrame()
-        rule.waitForIdle()
-
-        // Box1 doesn't have any other ExitTransition than scale, so it'll be disposed
-        // after a couple of frames
-        assertFalse(box1Disposed)
-        assertFalse(box2Disposed)
-
-        repeat(20) {
-            rule.mainClock.advanceTimeByFrame()
-
-            val playTime = 16 * it
-            val bounds2 = box2Coords?.boundsInRoot()
-            if (playTime <= 100) {
-                assertEquals(Rect(0f, 0f, 200f, 100f), bounds2)
-            } else if (playTime <= 200) {
-                val fraction = (playTime - 100) / 100f
-                val width = 200 * (1 - fraction) + 100 * fraction
-                // Since we are testing default behavior, the scaling is based on width.
-                val height = width / 100f * 50
-                assertEquals(Offset.Zero, bounds2?.topLeft)
-                assertEquals(width, bounds2?.width)
-                assertEquals(height, bounds2?.height)
-            } else {
-                assertEquals(Rect(0f, 0f, 100f, 50f), bounds2)
-            }
-        }
-
-        rule.runOnIdle {
-            // Start transition from false -> true, size 100, 50 -> 200,400
-            target = 1
-        }
-        rule.mainClock.advanceTimeByFrame()
-        rule.waitForIdle()
-
-        assertFalse(box1Disposed)
-        assertFalse(box2Disposed)
-
-        repeat(20) {
-            rule.mainClock.advanceTimeByFrame()
-            val playTime = 16 * it
-            val bounds = box1Coords?.boundsInRoot()
-            if (playTime <= 100) {
-                assertEquals(100f, bounds?.width)
-                assertFalse(box2Disposed)
-            } else if (playTime <= 150) {
-                val fraction = (playTime - 100) / 100f
-                val width = 100 * (1 - fraction) + 200 * fraction
-                // Since we are testing default behavior, the scaling is based on width.
-                assertEquals(Offset.Zero, bounds?.topLeft)
-                assertEquals(width, bounds?.width)
-            } else {
-                rule.waitForIdle()
-                assertThat(box2Disposed)
-            }
-        }
-    }
-
-    @Test
-    fun testScaleToFitCenterAlignment() {
-        var target by mutableStateOf(true)
-        var box1Coords: LayoutCoordinates? = null
-        var box2Coords: LayoutCoordinates? = null
-        var layoutDirection: LayoutDirection? = null
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                layoutDirection = LocalLayoutDirection.current
-                AnimatedContent(
-                    targetState = target,
-                    transitionSpec = {
-                        fadeIn() + scaleInToFitContainer(Alignment.Center) togetherWith
-                            fadeOut(tween(100)) using
-                            SizeTransform { _, _ ->
-                                tween(100, easing = LinearEasing)
-                            }
-                    }) {
-                    if (target) {
-                        Box(
-                            Modifier
-                                .onPlaced {
-                                    box1Coords = it
-                                }
-                                .size(200.dp, 400.dp))
-                    } else {
-                        Box(
-                            Modifier
-                                .onPlaced { box2Coords = it }
-                                .size(100.dp, 50.dp))
-                    }
-                }
-            }
-        }
-
-        rule.waitForIdle()
-        assertEquals(IntSize(200, 400), box1Coords?.size)
-        assertNull(box2Coords)
-
-        rule.runOnIdle {
-            // Start transition from true -> false, size 200,400 -> 100,50
-            target = false
-        }
-        rule.mainClock.advanceTimeByFrame()
-        repeat(10) {
-            rule.mainClock.advanceTimeByFrame()
-            val playTime = 16 * it
-            val bounds = box2Coords?.boundsInRoot()
-            assertNotNull(bounds)
-            val fraction = (playTime / 100f).coerceAtMost(1f)
-            val width = 200 * (1 - fraction) + 100 * fraction
-            val containerHeight = 400 * (1 - fraction) + 50 * fraction
-            // Since we are testing default behavior, the scaling is based on width.
-            val height = width / 100f * 50
-            assertEquals(width, bounds!!.width, 0.01f)
-            assertEquals(height, bounds.height, 0.01f)
-            val offset = Alignment.Center.align(
-                IntSize(width.roundToInt(), height.roundToInt()),
-                IntSize(width.roundToInt(), containerHeight.roundToInt()), layoutDirection!!
-            )
-            assertEquals(offset, bounds.topLeft.round())
-        }
-    }
-
-    @Test
-    fun testScaleToFitBottomCenterAlignment() {
-        var target by mutableStateOf(true)
-        var box1Coords: LayoutCoordinates? = null
-        var box2Coords: LayoutCoordinates? = null
-        var layoutDirection: LayoutDirection? = null
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                layoutDirection = LocalLayoutDirection.current
-                AnimatedContent(
-                    targetState = target,
-                    transitionSpec = {
-                        fadeIn() + scaleInToFitContainer(
-                            Alignment.BottomCenter
-                        ) togetherWith
-                            fadeOut(tween(100)) using
-                            SizeTransform { _, _ ->
-                                tween(100, easing = LinearEasing)
-                            }
-                    }) {
-                    if (target) {
-                        Box(
-                            Modifier
-                                .onPlaced {
-                                    box1Coords = it
-                                }
-                                .size(200.dp, 400.dp))
-                    } else {
-                        Box(
-                            Modifier
-                                .onPlaced { box2Coords = it }
-                                .size(100.dp, 50.dp))
-                    }
-                }
-            }
-        }
-
-        rule.waitForIdle()
-        rule.mainClock.autoAdvance = false
-        assertEquals(IntSize(200, 400), box1Coords?.size)
-        assertNull(box2Coords)
-
-        rule.runOnIdle {
-            // Start transition from true -> false, size 200,400 -> 100,50
-            target = false
-        }
-        rule.mainClock.advanceTimeByFrame()
-        repeat(10) {
-            rule.mainClock.advanceTimeByFrame()
-            val playTime = 16 * it
-            val bounds = box2Coords?.boundsInRoot()
-            assertNotNull(bounds)
-            val fraction = (playTime / 100f).coerceAtMost(1f)
-            val width = 200 * (1 - fraction) + 100 * fraction
-            val containerHeight = 400 * (1 - fraction) + 50 * fraction
-            // Since we are testing default behavior, the scaling is based on width.
-            val height = width / 100f * 50
-            assertEquals(width, bounds!!.width, 0.01f)
-            assertEquals(height, bounds.height, 0.01f)
-            val offset = Alignment.BottomCenter.align(
-                IntSize(width.roundToInt(), height.roundToInt()),
-                IntSize(width.roundToInt(), containerHeight.roundToInt()), layoutDirection!!
-            )
-            assertEquals(offset, bounds.topLeft.round())
-        }
-    }
-
-    @Test
-    fun testScaleToFitInsideBottomEndAlignment() {
-        var target by mutableStateOf(true)
-        var box1Coords: LayoutCoordinates? = null
-        var box2Coords: LayoutCoordinates? = null
-        var layoutDirection: LayoutDirection? = null
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                layoutDirection = LocalLayoutDirection.current
-                AnimatedContent(
-                    targetState = target,
-                    transitionSpec = {
-                        fadeIn() + scaleInToFitContainer(
-                            Alignment.BottomEnd, ContentScale.Inside
-                        ) togetherWith
-                            fadeOut(tween(100)) using
-                            SizeTransform { _, _ ->
-                                tween(100, easing = LinearEasing)
-                            }
-                    }) {
-                    if (target) {
-                        Box(
-                            Modifier
-                                .onPlaced {
-                                    box1Coords = it
-                                }
-                                .size(200.dp, 400.dp))
-                    } else {
-                        Box(
-                            Modifier
-                                .onPlaced { box2Coords = it }
-                                .size(100.dp, 50.dp))
-                    }
-                }
-            }
-        }
-
-        rule.waitForIdle()
-        rule.mainClock.autoAdvance = false
-        assertEquals(IntSize(200, 400), box1Coords?.size)
-        assertNull(box2Coords)
-
-        rule.runOnIdle {
-            // Start transition from true -> false, size 200,400 -> 100,50
-            target = false
-        }
-        rule.mainClock.advanceTimeByFrame()
-        repeat(10) {
-            rule.mainClock.advanceTimeByFrame()
-            val playTime = 16 * it
-            val bounds = box2Coords?.boundsInRoot()
-            assertNotNull(bounds)
-            val fraction = (playTime / 100f).coerceAtMost(1f)
-            val width = 100f
-            val containerWidth = 200 * (1 - fraction) + 100 * fraction
-            val containerHeight = 400 * (1 - fraction) + 50 * fraction
-            // Since we are testing default behavior, the scaling is based on width.
-            val height = 50f
-            assertEquals(width, bounds!!.width, 0.01f)
-            assertEquals(height, bounds.height, 0.01f)
-            val offset = Alignment.BottomEnd.align(
-                IntSize(width.roundToInt(), height.roundToInt()),
-                IntSize(containerWidth.roundToInt(), containerHeight.roundToInt()),
-                layoutDirection!!
-            )
-            assertEquals(offset, bounds.topLeft.round())
-        }
-    }
-
-    @Test
     fun testRightEnterExitTransitionIsChosenDuringInterruption() {
         var flag by mutableStateOf(false)
         var fixedPosition: Offset? = null
@@ -1187,72 +852,6 @@
         rule.waitForIdle()
     }
 
-    @Test
-    fun testScaleToFitWithFitHeight() {
-        var target by mutableStateOf(true)
-        var box1Coords: LayoutCoordinates? = null
-        var box2Coords: LayoutCoordinates? = null
-        var layoutDirection: LayoutDirection? = null
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                layoutDirection = LocalLayoutDirection.current
-                AnimatedContent(
-                    targetState = target,
-                    transitionSpec = {
-                        fadeIn() + scaleInToFitContainer(
-                            Alignment.Center, ContentScale.FillHeight
-                        ) togetherWith fadeOut(tween(100)) using
-                            SizeTransform { _, _ ->
-                                tween(100, easing = LinearEasing)
-                            }
-                    }) {
-                    if (target) {
-                        Box(
-                            Modifier
-                                .onPlaced {
-                                    box1Coords = it
-                                }
-                                .size(200.dp, 400.dp))
-                    } else {
-                        Box(
-                            Modifier
-                                .onPlaced { box2Coords = it }
-                                .size(100.dp, 250.dp))
-                    }
-                }
-            }
-        }
-
-        rule.waitForIdle()
-        rule.mainClock.autoAdvance = false
-        assertEquals(IntSize(200, 400), box1Coords?.size)
-        assertNull(box2Coords)
-
-        rule.runOnIdle {
-            // Start transition from true -> false, size 200,400 -> 100,250
-            target = false
-        }
-        rule.mainClock.advanceTimeByFrame()
-        repeat(10) {
-            rule.mainClock.advanceTimeByFrame()
-            val playTime = 16 * it
-            val bounds = box2Coords?.boundsInRoot()
-            assertNotNull(bounds)
-            val fraction = (playTime / 100f).coerceAtMost(1f)
-            val height = 400 * (1 - fraction) + 250 * fraction
-            val containerWidth = 200 * (1 - fraction) + 100 * fraction
-            // Since we are testing default behavior, the scaling is based on width.
-            val width = height / 250f * 100
-            assertEquals(width, bounds!!.width, 0.01f)
-            assertEquals(height, bounds.height, 0.01f)
-            val offset = Alignment.Center.align(
-                IntSize(width.roundToInt(), height.roundToInt()),
-                IntSize(containerWidth.roundToInt(), height.roundToInt()), layoutDirection!!
-            )
-            assertEquals(offset, bounds.topLeft.round())
-        }
-    }
-
     @OptIn(ExperimentalAnimationApi::class)
     @Test
     fun testExitHoldDefersUntilAllFinished() {
@@ -1327,51 +926,6 @@
         assertTrue(box2EnterFinished)
     }
 
-    /**
-     * This test checks that scaleInToFitContainer and scaleOutToFitContainer handle empty
-     * content correctly.
-     */
-    @Test
-    fun testAnimateToEmptyComposable() {
-        var isEmpty by mutableStateOf(false)
-        var targetSize: IntSize? = null
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                AnimatedContent(targetState = isEmpty,
-                    transitionSpec = {
-                        scaleInToFitContainer() togetherWith scaleOutToFitContainer()
-                    },
-                    modifier = Modifier.layout { measurable, constraints ->
-                        measurable.measure(constraints).run {
-                            if (isLookingAhead) {
-                                targetSize = IntSize(width, height)
-                            }
-                            layout(width, height) {
-                                place(0, 0)
-                            }
-                        }
-                    }
-                ) {
-                    if (!it) {
-                        Box(Modifier.size(200.dp))
-                    }
-                }
-            }
-        }
-        rule.runOnIdle {
-            assertEquals(IntSize(200, 200), targetSize)
-            isEmpty = true
-        }
-
-        rule.runOnIdle {
-            assertEquals(IntSize.Zero, targetSize)
-            isEmpty = !isEmpty
-        }
-        rule.runOnIdle {
-            assertEquals(IntSize(200, 200), targetSize)
-        }
-    }
-
     @OptIn(InternalAnimationApi::class)
     private val Transition<*>.playTimeMillis get() = (playTimeNanos / 1_000_000L).toInt()
 }
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
index eab0d26..896308a 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
@@ -1,3 +1,4 @@
+
 /*
  * Copyright 2021 The Android Open Source Project
  *
@@ -13,10 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:OptIn(InternalAnimationApi::class, ExperimentalAnimationApi::class)
-
+@file:OptIn(InternalAnimationApi::class)
 package androidx.compose.animation
-
 import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion.Down
 import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion.End
 import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion.Left
@@ -37,7 +36,6 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.key
@@ -45,44 +43,30 @@
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.runtime.setValue
-import androidx.compose.runtime.snapshots.SnapshotStateList
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clipToBounds
-import androidx.compose.ui.graphics.TransformOrigin
-import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.IntrinsicMeasurable
 import androidx.compose.ui.layout.IntrinsicMeasureScope
 import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.LookaheadScope
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.ParentDataModifier
 import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.layout.ScaleFactor
 import androidx.compose.ui.layout.layout
-import androidx.compose.ui.node.LayoutModifierNode
-import androidx.compose.ui.node.ModifierNodeElement
-import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.toSize
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachIndexed
 import androidx.compose.ui.util.fastMaxOfOrNull
-import kotlin.math.roundToInt
-import kotlinx.coroutines.CoroutineScope
-
 /**
  * [AnimatedContent] is a container that automatically animates its content when [targetState]
  * changes. Its [content] for different target states is defined in a mapping between a target
@@ -161,7 +145,6 @@
         content = content
     )
 }
-
 /**
  * [ContentTransform] defines how the target content (i.e. content associated with target state)
  * enters [AnimatedContent] and how the initial content disappears.
@@ -212,7 +195,6 @@
      * content with the same index, the target content will be placed on top.
      */
     var targetContentZIndex by mutableFloatStateOf(targetContentZIndex)
-
     /**
      * [sizeTransform] manages the expanding and shrinking of the container if there is any size
      * change as new content enters the [AnimatedContent] and old content leaves.
@@ -223,7 +205,6 @@
     var sizeTransform: SizeTransform? = sizeTransform
         internal set
 }
-
 /**
  * This creates a [SizeTransform] with the provided [clip] and [sizeAnimationSpec]. By default,
  * [clip] will be true. This means during the size animation, the content will be clipped to the
@@ -241,7 +222,6 @@
             )
         }
 ): SizeTransform = SizeTransformImpl(clip, sizeAnimationSpec)
-
 /**
  * [SizeTransform] defines how to transform from one size to another when the size of the content
  * changes. When [clip] is true, the content will be clipped to the animation size.
@@ -255,14 +235,12 @@
      * Whether the content should be clipped using the animated size.
      */
     val clip: Boolean
-
     /**
      * This allows [FiniteAnimationSpec] to be defined based on the [initialSize] before the size
      * animation and the [targetSize] of the animation.
      */
     fun createAnimationSpec(initialSize: IntSize, targetSize: IntSize): FiniteAnimationSpec<IntSize>
 }
-
 /**
  * Private implementation of SizeTransform interface.
  */
@@ -276,7 +254,6 @@
         targetSize: IntSize
     ): FiniteAnimationSpec<IntSize> = sizeAnimationSpec(initialSize, targetSize)
 }
-
 /**
  * This creates a [ContentTransform] using the provided [EnterTransition] and [exit], where the
  * enter and exit transition will be running simultaneously.
@@ -285,14 +262,12 @@
  * @sample androidx.compose.animation.samples.AnimatedContentTransitionSpecSample
  */
 infix fun EnterTransition.togetherWith(exit: ExitTransition) = ContentTransform(this, exit)
-
 @ExperimentalAnimationApi
 @Deprecated(
     "Infix fun EnterTransition.with(ExitTransition) has been renamed to" +
         " togetherWith", ReplaceWith("togetherWith(exit)")
 )
 infix fun EnterTransition.with(exit: ExitTransition) = ContentTransform(this, exit)
-
 /**
  * [AnimatedContentTransitionScope] provides functions that are convenient and only applicable in the
  * context of [AnimatedContent], such as [slideIntoContainer] and [slideOutOfContainer].
@@ -304,7 +279,6 @@
      * @sample androidx.compose.animation.samples.AnimatedContentTransitionSpecSample
      */
     infix fun ContentTransform.using(sizeTransform: SizeTransform?): ContentTransform
-
     /**
      * [SlideDirection] defines the direction of the slide in/out for [slideIntoContainer] and
      * [slideOutOfContainer]. The supported directions are: [Left], [Right], [Up] and [Down].
@@ -320,7 +294,6 @@
             val Start = SlideDirection(4)
             val End = SlideDirection(5)
         }
-
         override fun toString(): String {
             return when (this) {
                 Left -> "Left"
@@ -333,7 +306,6 @@
             }
         }
     }
-
     /**
      * This defines a horizontal/vertical slide-in that is specific to [AnimatedContent] from the
      * edge of the container. The offset amount is dynamically calculated based on the current
@@ -363,7 +335,6 @@
         ),
         initialOffset: (offsetForFullSlide: Int) -> Int = { it }
     ): EnterTransition
-
     /**
      * This defines a horizontal/vertical exit transition to completely slide out of the
      * [AnimatedContent] container. The offset amount is dynamically calculated based on the current
@@ -392,7 +363,6 @@
         ),
         targetOffset: (offsetForFullSlide: Int) -> Int = { it }
     ): ExitTransition
-
     /**
      * [KeepUntilTransitionsFinished] defers the disposal of the exiting content till both enter and
      * exit transitions have finished. It can be combined with other [ExitTransition]s using
@@ -408,81 +378,28 @@
      */
     val ExitTransition.Companion.KeepUntilTransitionsFinished: ExitTransition
         get() = KeepUntilTransitionsFinished
-
     /**
      * This returns the [Alignment] specified on [AnimatedContent].
      */
     val contentAlignment: Alignment
-
-    /**
-     * [scaleInToFitContainer] defines an [EnterTransition] that scales the incoming content
-     * based on the (potentially animating) container (i.e. [AnimatedContent]) size. [contentScale]
-     * defines the scaling function. By default, the incoming content will be scaled based on its
-     * width (i.e. [ContentScale.FillWidth]), so that the content fills the container's width.
-     * [alignment] can be used to specify the alignment of the scaled content
-     * within the container of AnimatedContent.
-     *
-     * [scaleInToFitContainer] will measure the content using the final (i.e. lookahead)
-     * constraints, in order to obtain the final layout and apply scaling to that final layout
-     * while the container is resizing.
-     *
-     * @sample androidx.compose.animation.samples.ScaleInToFitContainerSample
-     */
-    @ExperimentalAnimationApi
-    fun scaleInToFitContainer(
-        alignment: Alignment = contentAlignment,
-        contentScale: ContentScale = ContentScale.FillWidth
-    ): EnterTransition
-
-    /**
-     * [scaleOutToFitContainer] defines an [ExitTransition] that scales the outgoing content
-     * based on the (potentially animating) container (i.e. [AnimatedContent]) size.
-     * [contentScale] defines the scaling function. By default, the outgoing content will be scaled
-     * using [ContentScale.FillWidth], so that it fits the container's width.
-     * [alignment] can be used to specify the alignment of the scaled content
-     * within the container of AnimatedContent.
-     *
-     * [scaleOutToFitContainer] will measure the content using the constraints cached
-     * at the beginning of the exit animation so that the content does not get re-laid out during
-     * the exit animation, and instead only scaling will be applied as the container resizes.
-     *
-     * **IMPORTANT**: [scaleOutToFitContainer] does NOT keep the exiting content from being
-     * disposed. Therefore it relies on other ExitTransitions such as [fadeOut] to define a
-     * timeframe for when should be active.
-     *
-     * @sample androidx.compose.animation.samples.ScaleInToFitContainerSample
-     */
-    @ExperimentalAnimationApi
-    fun scaleOutToFitContainer(
-        alignment: Alignment = contentAlignment,
-        contentScale: ContentScale = ContentScale.FillWidth,
-    ): ExitTransition
 }
-
-internal class AnimatedContentRootScope<S> internal constructor(
+internal class AnimatedContentTransitionScopeImpl<S> internal constructor(
     internal val transition: Transition<S>,
-    lookaheadScope: LookaheadScope,
-    internal val coroutineScope: CoroutineScope,
     override var contentAlignment: Alignment,
     internal var layoutDirection: LayoutDirection
-) : AnimatedContentTransitionScope<S>, LookaheadScope by lookaheadScope {
-    lateinit var rootCoords: LayoutCoordinates
-    lateinit var rootLookaheadCoords: LayoutCoordinates
-
+) : AnimatedContentTransitionScope<S> {
     /**
      * Initial state of a Transition Segment. This is the state that transition starts from.
      */
     override val initialState: S
         @Suppress("UnknownNullness")
         get() = transition.segment.initialState
-
     /**
      * Target state of a Transition Segment. This is the state that transition will end on.
      */
     override val targetState: S
         @Suppress("UnknownNullness")
         get() = transition.segment.targetState
-
     /**
      * Customizes the [SizeTransform] of a given [ContentTransform]. For example:
      *
@@ -491,7 +408,6 @@
     override infix fun ContentTransform.using(sizeTransform: SizeTransform?) = this.apply {
         this.sizeTransform = sizeTransform
     }
-
     /**
      * This defines a horizontal/vertical slide-in that is specific to [AnimatedContent] from the
      * edge of the container. The offset amount is dynamically calculated based on the current
@@ -528,24 +444,19 @@
                     currentSize.width - calculateOffset(IntSize(it, it), currentSize).x
                 )
             }
-
             towards.isRight -> slideInHorizontally(animationSpec) {
                 initialOffset.invoke(-calculateOffset(IntSize(it, it), currentSize).x - it)
             }
-
             towards == Up -> slideInVertically(animationSpec) {
                 initialOffset.invoke(
                     currentSize.height - calculateOffset(IntSize(it, it), currentSize).y
                 )
             }
-
             towards == Down -> slideInVertically(animationSpec) {
                 initialOffset.invoke(-calculateOffset(IntSize(it, it), currentSize).y - it)
             }
-
             else -> EnterTransition.None
         }
-
     private val AnimatedContentTransitionScope.SlideDirection.isLeft: Boolean
         get() {
             return this == Left || this == Start && layoutDirection == LayoutDirection.Ltr ||
@@ -556,11 +467,9 @@
             return this == Right || this == Start && layoutDirection == LayoutDirection.Rtl ||
                 this == End && layoutDirection == LayoutDirection.Ltr
         }
-
     private fun calculateOffset(fullSize: IntSize, currentSize: IntSize): IntOffset {
         return contentAlignment.align(fullSize, currentSize, LayoutDirection.Ltr)
     }
-
     /**
      * This defines a horizontal/vertical exit transition to completely slide out of the
      * [AnimatedContent] container. The offset amount is dynamically calculated based on the current
@@ -596,69 +505,32 @@
                 val targetSize = targetSizeMap[transition.targetState]?.value ?: IntSize.Zero
                 targetOffset.invoke(-calculateOffset(IntSize(it, it), targetSize).x - it)
             }
-
             towards.isRight -> slideOutHorizontally(animationSpec) {
                 val targetSize = targetSizeMap[transition.targetState]?.value ?: IntSize.Zero
                 targetOffset.invoke(
                     -calculateOffset(IntSize(it, it), targetSize).x + targetSize.width
                 )
             }
-
             towards == Up -> slideOutVertically(animationSpec) {
                 val targetSize = targetSizeMap[transition.targetState]?.value ?: IntSize.Zero
                 targetOffset.invoke(-calculateOffset(IntSize(it, it), targetSize).y - it)
             }
-
             towards == Down -> slideOutVertically(animationSpec) {
                 val targetSize = targetSizeMap[transition.targetState]?.value ?: IntSize.Zero
                 targetOffset.invoke(
                     -calculateOffset(IntSize(it, it), targetSize).y + targetSize.height
                 )
             }
-
             else -> ExitTransition.None
         }
     }
-
-    @ExperimentalAnimationApi
-    override fun scaleInToFitContainer(
-        alignment: Alignment,
-        contentScale: ContentScale
-    ): EnterTransition = EnterTransition(
-        ScaleToFitTransitionKey, ScaleToFitInLookaheadElement(
-            this@AnimatedContentRootScope,
-            contentScale,
-            alignment
-        )
-    )
-
-    @ExperimentalAnimationApi
-    override fun scaleOutToFitContainer(
-        alignment: Alignment,
-        contentScale: ContentScale
-    ): ExitTransition = ExitTransition(
-        ScaleToFitTransitionKey,
-        ScaleToFitInLookaheadElement(
-            this@AnimatedContentRootScope,
-            contentScale,
-            alignment
-        )
-    )
-
     internal var measuredSize: IntSize by mutableStateOf(IntSize.Zero)
-    internal val targetSizeMap = mutableMapOf<S, MutableState<IntSize>>()
+    internal val targetSizeMap = mutableMapOf<S, State<IntSize>>()
     internal var animatedSize: State<IntSize>? = null
-
     // Current size of the container. If there's any size animation, the current size will be
     // read from the animation value, otherwise we'll use the current
-    internal val currentSize: IntSize
+    private val currentSize: IntSize
         get() = animatedSize?.value ?: measuredSize
-
-    internal val targetSize: IntSize
-        get() = requireNotNull(targetSizeMap[targetState]) {
-            "Error: Target size for AnimatedContent has not been set."
-        }.value
-
     @Suppress("ComposableModifierFactory", "ModifierFactoryExtensionFunction")
     @Composable
     internal fun createSizeAnimationModifier(
@@ -668,47 +540,67 @@
         val sizeTransform = rememberUpdatedState(contentTransform.sizeTransform)
         if (transition.currentState == transition.targetState) {
             shouldAnimateSize = false
-        } else if (sizeTransform.value != null) {
-            shouldAnimateSize = true
+        } else {
+            // TODO: CurrentSize is only relevant to enter/exit transition, not so much for sizeAnim
+            if (sizeTransform.value != null) {
+                shouldAnimateSize = true
+            }
         }
-
         return if (shouldAnimateSize) {
-            val sizeAnimation =
-                transition.createDeferredAnimation(IntSize.VectorConverter, "sizeTransform")
+            val sizeAnimation = transition.createDeferredAnimation(IntSize.VectorConverter)
             remember(sizeAnimation) {
                 (if (sizeTransform.value?.clip == false) Modifier else Modifier.clipToBounds())
-                    .then(
-                        SizeModifierInLookaheadElement(
-                            this, sizeAnimation, sizeTransform
-                        )
-                    )
+                    .then(SizeModifier(sizeAnimation, sizeTransform))
             }
         } else {
             animatedSize = null
             Modifier
         }
     }
-
     // This helps track the target measurable without affecting the placement order. Target
     // measurable needs to be measured first but placed last.
-    internal data class ChildData<T>(var targetState: T) : ParentDataModifier {
+    internal data class ChildData(var isTarget: Boolean) : ParentDataModifier {
         override fun Density.modifyParentData(parentData: Any?): Any {
             return this@ChildData
         }
     }
+    private inner class SizeModifier(
+        val sizeAnimation: Transition<S>.DeferredAnimation<IntSize, AnimationVector2D>,
+        val sizeTransform: State<SizeTransform?>,
+    ) : LayoutModifierWithPassThroughIntrinsics() {
+        override fun MeasureScope.measure(
+            measurable: Measurable,
+            constraints: Constraints
+        ): MeasureResult {
+            val placeable = measurable.measure(constraints)
+            val size = sizeAnimation.animate(
+                transitionSpec = {
+                    val initial = targetSizeMap[initialState]?.value ?: IntSize.Zero
+                    val target = targetSizeMap[targetState]?.value ?: IntSize.Zero
+                    sizeTransform.value?.createAnimationSpec(initial, target) ?: spring()
+                }
+            ) {
+                targetSizeMap[it]?.value ?: IntSize.Zero
+            }
+            animatedSize = size
+            val offset = contentAlignment.align(
+                IntSize(placeable.width, placeable.height), size.value, LayoutDirection.Ltr
+            )
+            return layout(size.value.width, size.value.height) {
+                placeable.place(offset)
+            }
+        }
+    }
 }
-
 /**
  * Receiver scope for content lambda for AnimatedContent. In this scope,
  * [transition][AnimatedVisibilityScope.transition] can be used to observe the state of the
  * transition, or to add more enter/exit transition for the content.
  */
 sealed interface AnimatedContentScope : AnimatedVisibilityScope
-
 private class AnimatedContentScopeImpl internal constructor(
     animatedVisibilityScope: AnimatedVisibilityScope
 ) : AnimatedContentScope, AnimatedVisibilityScope by animatedVisibilityScope
-
 /**
  * [AnimatedContent] is a container that automatically animates its content when
  * [Transition.targetState] changes. Its [content] for different target states is defined in a
@@ -772,268 +664,145 @@
     content: @Composable() AnimatedContentScope.(targetState: S) -> Unit
 ) {
     val layoutDirection = LocalLayoutDirection.current
-    val coroutineScope = rememberCoroutineScope()
-    LookaheadScope {
-        val rootScope = remember(this@AnimatedContent) {
-            AnimatedContentRootScope(
-                this@AnimatedContent, this@LookaheadScope,
-                coroutineScope, contentAlignment, layoutDirection
-            )
-        }
-        val currentlyVisible = remember(this) { mutableStateListOf(currentState) }
-        val contentMap = remember(this) { mutableMapOf<S, @Composable() () -> Unit>() }
-        val constraintsMap = remember { mutableMapOf<S, Constraints>() }
-
-        // This is needed for tooling because it could change currentState directly,
-        // as opposed to changing target only. When that happens we need to clear all the
-        // visible content and only display the content for the new current state and target state.
-        if (!currentlyVisible.contains(currentState)) {
+    val rootScope = remember(this) {
+        AnimatedContentTransitionScopeImpl(this, contentAlignment, layoutDirection)
+    }
+    // TODO: remove screen as soon as they are animated out
+    val currentlyVisible = remember(this) { mutableStateListOf(currentState) }
+    val contentMap = remember(this) { mutableMapOf<S, @Composable() () -> Unit>() }
+    // This is needed for tooling because it could change currentState directly,
+    // as opposed to changing target only. When that happens we need to clear all the
+    // visible content and only display the content for the new current state and target state.
+    if (!currentlyVisible.contains(currentState)) {
+        currentlyVisible.clear()
+        currentlyVisible.add(currentState)
+    }
+    if (currentState == targetState) {
+        if (currentlyVisible.size != 1 || currentlyVisible[0] != currentState) {
             currentlyVisible.clear()
             currentlyVisible.add(currentState)
         }
-
-        if (currentState == targetState) {
-            if (currentlyVisible.size != 1 || currentlyVisible[0] != currentState) {
-                currentlyVisible.clear()
-                currentlyVisible.add(currentState)
-            }
-            if (contentMap.size != 1 || contentMap.containsKey(currentState)) {
-                contentMap.clear()
-            }
-            val targetConstraints = constraintsMap[targetState]
-            constraintsMap.clear()
-            targetConstraints?.let { constraintsMap[targetState] = it }
-            // TODO: Do we want to support changing contentAlignment amid animation?
-            rootScope.contentAlignment = contentAlignment
-            rootScope.layoutDirection = layoutDirection
-        } else if (!currentlyVisible.contains(targetState)) {
-            // Currently visible list always keeps the targetState at the end of the list, unless
-            // it's already in the list in the case of interruption. This makes the composable
-            // associated with the targetState get placed last, so the target composable will be
-            // displayed on top of content associated with other states, unless zIndex is specified.
-            // Replace the target with the same key if any.
-            val id = currentlyVisible.indexOfFirst { contentKey(it) == contentKey(targetState) }
-            if (id == -1) {
-                currentlyVisible.add(targetState)
-            } else {
-                currentlyVisible[id] = targetState
-            }
-        }
-        if (!contentMap.containsKey(targetState) || !contentMap.containsKey(currentState)) {
+        if (contentMap.size != 1 || contentMap.containsKey(currentState)) {
             contentMap.clear()
-            currentlyVisible.fastForEach { stateForContent ->
-                contentMap[stateForContent] = {
-                    // Only update content transform when enter/exit _direction_ changes.
-                    val contentTransform = remember(stateForContent == targetState) {
-                        rootScope.transitionSpec()
-                    }
-                    PopulateContentFor(
-                        stateForContent, rootScope, contentTransform, currentlyVisible, content
-                    )
-                }
-            }
         }
-        val contentTransform = remember(rootScope, segment) { transitionSpec(rootScope) }
-        val sizeModifier = rootScope.createSizeAnimationModifier(contentTransform)
-        Layout(
-            modifier = modifier
-                .layout { measurable, constraints ->
-                    val placeable = measurable.measure(constraints)
-                    layout(placeable.width, placeable.height) {
-                        coordinates?.let {
-                            if (isLookingAhead) {
-                                rootScope.rootLookaheadCoords = it
-                            } else {
-                                rootScope.rootCoords = it
+        // TODO: Do we want to support changing contentAlignment amid animation?
+        rootScope.contentAlignment = contentAlignment
+        rootScope.layoutDirection = layoutDirection
+    }
+    // Currently visible list always keeps the targetState at the end of the list, unless it's
+    // already in the list in the case of interruption. This makes the composable associated with
+    // the targetState get placed last, so the target composable will be displayed on top of
+    // content associated with other states, unless zIndex is specified.
+    if (currentState != targetState && !currentlyVisible.contains(targetState)) {
+        // Replace the target with the same key if any
+        val id = currentlyVisible.indexOfFirst { contentKey(it) == contentKey(targetState) }
+        if (id == -1) {
+            currentlyVisible.add(targetState)
+        } else {
+            currentlyVisible[id] = targetState
+        }
+    }
+    if (!contentMap.containsKey(targetState) || !contentMap.containsKey(currentState)) {
+        contentMap.clear()
+        currentlyVisible.fastForEach { stateForContent ->
+            contentMap[stateForContent] = {
+                val specOnEnter = remember { transitionSpec(rootScope) }
+                // NOTE: enter and exit for this AnimatedVisibility will be using different spec,
+                // naturally.
+                val exit =
+                    remember(segment.targetState == stateForContent) {
+                        if (segment.targetState == stateForContent) {
+                            ExitTransition.None
+                        } else {
+                            rootScope.transitionSpec().initialContentExit
+                        }
+                    }
+                val childData = remember {
+                    AnimatedContentTransitionScopeImpl.ChildData(stateForContent == targetState)
+                }
+                // TODO: Will need a custom impl of this to: 1) get the signal for when
+                // the animation is finished, 2) get the target size properly
+                AnimatedEnterExitImpl(
+                    this,
+                    { it == stateForContent },
+                    enter = specOnEnter.targetContentEnter,
+                    exit = exit,
+                    modifier = Modifier
+                        .layout { measurable, constraints ->
+                            val placeable = measurable.measure(constraints)
+                            layout(placeable.width, placeable.height) {
+                                placeable.place(0, 0, zIndex = specOnEnter.targetContentZIndex)
                             }
                         }
-                        placeable.place(0, 0)
+                        .then(childData.apply { isTarget = stateForContent == targetState }),
+                    shouldDisposeBlock = { currentState, targetState ->
+                        currentState == EnterExitState.PostExit &&
+                            targetState == EnterExitState.PostExit &&
+                            !exit.data.hold
+                    }
+                ) {
+                    // TODO: Should Transition.AnimatedVisibility have an end listener?
+                    DisposableEffect(this) {
+                        onDispose {
+                            currentlyVisible.remove(stateForContent)
+                            rootScope.targetSizeMap.remove(stateForContent)
+                        }
+                    }
+                    rootScope.targetSizeMap[stateForContent] =
+                        (this as AnimatedVisibilityScopeImpl).targetSize
+                    with(remember { AnimatedContentScopeImpl(this) }) {
+                        content(stateForContent)
                     }
                 }
-                .then(sizeModifier),
-            content = {
-                currentlyVisible.fastForEach {
-                    key(contentKey(it)) { contentMap[it]?.invoke() }
-                }
-            },
-            measurePolicy = remember {
-                AnimatedContentMeasurePolicy(
-                    rootScope, constraintsMap
-                )
             }
-        )
-    }
-}
-
-/**
- * Creates content for a specific state based on the current Transition, enter/exit and the content
- * lookup lambda.
- */
-@Composable
-private inline fun <S> Transition<S>.PopulateContentFor(
-    stateForContent: S,
-    rootScope: AnimatedContentRootScope<S>,
-    contentTransform: ContentTransform,
-    currentlyVisible: SnapshotStateList<S>,
-    crossinline content: @Composable() AnimatedContentScope.(targetState: S) -> Unit
-) {
-    var activeEnter by remember { mutableStateOf(contentTransform.targetContentEnter) }
-    var activeExit by remember { mutableStateOf(ExitTransition.None) }
-    val targetZIndex = remember { contentTransform.targetContentZIndex }
-
-    val isEntering = targetState == stateForContent
-    if (targetState == currentState) {
-        // Transition finished, reset active enter & exit.
-        activeEnter = EnterTransition.None
-        activeExit = ExitTransition.None
-    } else if (isEntering) {
-        // If the previous enter transition never finishes when multiple
-        // interruptions happen, avoid adding new enter transitions for simplicity.
-        if (activeEnter == EnterTransition.None)
-            activeEnter += contentTransform.targetContentEnter
-    } else {
-        // If the previous exit transition never finishes when multiple
-        // interruptions happen, avoid adding new enter transitions for simplicity.
-        if (activeExit == ExitTransition.None) {
-            activeExit += contentTransform.initialContentExit
         }
     }
-
-    val childData = remember { AnimatedContentRootScope.ChildData(stateForContent) }
-    AnimatedEnterExitImpl(
-        this,
-        { it == stateForContent },
-        enter = activeEnter,
-        exit = activeExit,
-        modifier = Modifier
-            .layout { measurable, constraints ->
-                val placeable = measurable.measure(constraints)
-                layout(placeable.width, placeable.height) {
-                    placeable.place(0, 0, zIndex = targetZIndex)
+    val contentTransform = remember(rootScope, segment) { transitionSpec(rootScope) }
+    val sizeModifier = rootScope.createSizeAnimationModifier(contentTransform)
+    Layout(
+        modifier = modifier.then(sizeModifier),
+        content = {
+            currentlyVisible.fastForEach {
+                key(contentKey(it)) {
+                    contentMap[it]?.invoke()
                 }
             }
-            .then(childData)
-            .then(
-                if (isEntering) {
-                    activeEnter[ScaleToFitTransitionKey]
-                        ?: activeExit[ScaleToFitTransitionKey] ?: Modifier
-                } else {
-                    activeExit[ScaleToFitTransitionKey]
-                        ?: activeEnter[ScaleToFitTransitionKey] ?: Modifier
-                }
-            ),
-        shouldDisposeBlock = { currentState, targetState ->
-            currentState == EnterExitState.PostExit &&
-                targetState == EnterExitState.PostExit && !activeExit.data.hold
         },
-        onLookaheadMeasured = {
-            if (isEntering) rootScope.targetSizeMap.getOrPut(targetState) {
-                mutableStateOf(it)
-            }.value = it
-        }
-    ) {
-        // TODO: Should Transition.AnimatedVisibility have an end listener?
-        DisposableEffect(this) {
-            onDispose {
-                currentlyVisible.remove(stateForContent)
-                rootScope.targetSizeMap.remove(stateForContent)
-            }
-        }
-        with(remember { AnimatedContentScopeImpl(this) }) {
-            content(stateForContent)
-        }
-    }
+        measurePolicy = remember { AnimatedContentMeasurePolicy(rootScope) }
+    )
 }
-
-/**
- * This measure policy returns the target content size in the lookahead pass, and the max width
- * and height needed for all contents to fit during the main measure pass.
- *
- * The measure policy will measure all children with lookahead constraints. For outgoing content,
- * we will use the constraints recorded before the content started to exit. This enables the
- * outgoing content to not change constraints on its way out.
- */
-@Suppress("UNCHECKED_CAST")
-private class AnimatedContentMeasurePolicy<S>(
-    val rootScope: AnimatedContentRootScope<S>,
-    val constraintsMap: MutableMap<S, Constraints>
-) : MeasurePolicy {
+private class AnimatedContentMeasurePolicy(val rootScope: AnimatedContentTransitionScopeImpl<*>) :
+    MeasurePolicy {
     override fun MeasureScope.measure(
         measurables: List<Measurable>,
         constraints: Constraints
     ): MeasureResult {
         val placeables = arrayOfNulls<Placeable>(measurables.size)
         // Measure the target composable first (but place it on top unless zIndex is specified)
-        val targetState = rootScope.targetState
         measurables.fastForEachIndexed { index, measurable ->
-            if ((measurable.parentData as? AnimatedContentRootScope.ChildData<*>)
-                    ?.targetState == targetState
+            if ((measurable.parentData as? AnimatedContentTransitionScopeImpl.ChildData)
+                    ?.isTarget == true
             ) {
-                // Record lookahead constraints and always use it to measure target content.
-                val lookaheadConstraints = if (isLookingAhead) {
-                    constraintsMap[targetState] = constraints
-                    constraints
-                } else {
-                    requireNotNull(constraintsMap[targetState]) {
-                        "Lookahead pass was never done for target content."
-                    }
-                }
-                placeables[index] = measurable.measure(lookaheadConstraints)
+                placeables[index] = measurable.measure(constraints)
             }
         }
-        // If no content is defined for target state, set the target size to zero
-        rootScope.targetSizeMap.getOrPut(targetState) { mutableStateOf(IntSize.Zero) }
-
-        val initialState = rootScope.initialState
         // Measure the non-target composables after target, since these have no impact on
         // container size in the size animation.
         measurables.fastForEachIndexed { index, measurable ->
-            val stateForContent =
-                (measurable.parentData as? AnimatedContentRootScope.ChildData<*>)
-                    ?.targetState
             if (placeables[index] == null) {
-                val lookaheadConstraints =
-                    constraintsMap[stateForContent] ?: if (isLookingAhead) {
-                        constraintsMap[stateForContent as S] = constraints
-                        constraints
-                    } else {
-                        requireNotNull(constraintsMap[stateForContent as S]) {
-                            "Error: Lookahead pass never happened for state: $stateForContent"
-                        }
-                    }
-                placeables[index] = measurable.measure(lookaheadConstraints).also {
-                    // If the initial state size isn't in the map, add it. This could be possible
-                    // when the initial state is specified to be different than target state upon
-                    // entering composition.
-                    if (stateForContent == initialState &&
-                        isLookingAhead &&
-                        !rootScope.targetSizeMap.containsKey(initialState)
-                    ) {
-                        rootScope.targetSizeMap[initialState] =
-                            mutableStateOf(IntSize(it.width, it.height))
-                    }
-                }
+                placeables[index] = measurable.measure(constraints)
             }
         }
-        val lookaheadSize = rootScope.targetSizeMap[targetState]!!.value
-        val measuredWidth = if (isLookingAhead) {
-            lookaheadSize.width
-        } else {
-            placeables.maxByOrNull { it?.width ?: 0 }?.width ?: 0
-        }
-        val measuredHeight = if (isLookingAhead) {
-            lookaheadSize.height
-        } else {
-            placeables.maxByOrNull { it?.height ?: 0 }?.height ?: 0
-        }
-        rootScope.measuredSize = IntSize(measuredWidth, measuredHeight)
+        val maxWidth: Int = placeables.maxByOrNull { it?.width ?: 0 }?.width ?: 0
+        val maxHeight = placeables.maxByOrNull { it?.height ?: 0 }?.height ?: 0
+        rootScope.measuredSize = IntSize(maxWidth, maxHeight)
         // Position the children.
-        return layout(measuredWidth, measuredHeight) {
+        return layout(maxWidth, maxHeight) {
             placeables.forEach { placeable ->
                 placeable?.let {
                     val offset = rootScope.contentAlignment.align(
                         IntSize(it.width, it.height),
-                        IntSize(measuredWidth, measuredHeight),
+                        IntSize(maxWidth, maxHeight),
                         LayoutDirection.Ltr
                     )
                     it.place(offset.x, offset.y)
@@ -1041,178 +810,20 @@
             }
         }
     }
-
     override fun IntrinsicMeasureScope.minIntrinsicWidth(
         measurables: List<IntrinsicMeasurable>,
         height: Int
     ) = measurables.fastMaxOfOrNull { it.minIntrinsicWidth(height) } ?: 0
-
     override fun IntrinsicMeasureScope.minIntrinsicHeight(
         measurables: List<IntrinsicMeasurable>,
         width: Int
     ) = measurables.fastMaxOfOrNull { it.minIntrinsicHeight(width) } ?: 0
-
     override fun IntrinsicMeasureScope.maxIntrinsicWidth(
         measurables: List<IntrinsicMeasurable>,
         height: Int
     ) = measurables.fastMaxOfOrNull { it.maxIntrinsicWidth(height) } ?: 0
-
     override fun IntrinsicMeasureScope.maxIntrinsicHeight(
         measurables: List<IntrinsicMeasurable>,
         width: Int
     ) = measurables.fastMaxOfOrNull { it.maxIntrinsicHeight(width) } ?: 0
 }
-
-private class SizeModifierInLookaheadNode<S>(
-    var rootScope: AnimatedContentRootScope<S>,
-    var sizeAnimation: Transition<S>.DeferredAnimation<IntSize, AnimationVector2D>,
-    var sizeTransform: State<SizeTransform?>,
-) : LayoutModifierNodeWithPassThroughIntrinsics() {
-
-    override fun MeasureScope.measure(
-        measurable: Measurable,
-        constraints: Constraints,
-    ): MeasureResult {
-        val placeable = measurable.measure(constraints)
-        val size = if (isLookingAhead) {
-            val targetSize = IntSize(placeable.width, placeable.height)
-            // lookahead pass
-            rootScope.animatedSize = sizeAnimation.animate(
-                transitionSpec = {
-                    val initial = rootScope.targetSizeMap[initialState]?.value ?: IntSize.Zero
-                    val target = rootScope.targetSizeMap[targetState]?.value ?: IntSize.Zero
-                    sizeTransform.value?.createAnimationSpec(initial, target) ?: spring()
-                }
-            ) {
-                rootScope.targetSizeMap[it]?.value ?: IntSize.Zero
-            }
-            targetSize
-        } else {
-            rootScope.animatedSize!!.value
-        }
-        val offset = rootScope.contentAlignment.align(
-            IntSize(placeable.width, placeable.height), size, LayoutDirection.Ltr
-        )
-        return layout(size.width, size.height) {
-            placeable.place(offset)
-        }
-    }
-}
-
-private data class SizeModifierInLookaheadElement<S>(
-    val rootScope: AnimatedContentRootScope<S>,
-    val sizeAnimation: Transition<S>.DeferredAnimation<IntSize, AnimationVector2D>,
-    val sizeTransform: State<SizeTransform?>,
-) : ModifierNodeElement<SizeModifierInLookaheadNode<S>>() {
-    override fun create(): SizeModifierInLookaheadNode<S> {
-        return SizeModifierInLookaheadNode(rootScope, sizeAnimation, sizeTransform)
-    }
-
-    override fun update(node: SizeModifierInLookaheadNode<S>) {
-        node.rootScope = rootScope
-        node.sizeTransform = sizeTransform
-        node.sizeAnimation = sizeAnimation
-    }
-
-    override fun InspectorInfo.inspectableProperties() {
-        name = "sizeTransform"
-        properties["sizeTransform"] = sizeTransform
-        properties["sizeAnimation"] = sizeAnimation
-    }
-}
-
-private data class ScaleToFitInLookaheadElement(
-    val rootScope: AnimatedContentRootScope<*>,
-    val contentScale: ContentScale,
-    val alignment: Alignment
-) : ModifierNodeElement<ScaleToFitInLookaheadNode>() {
-    override fun create(): ScaleToFitInLookaheadNode =
-        ScaleToFitInLookaheadNode(rootScope, contentScale, alignment)
-
-    override fun update(node: ScaleToFitInLookaheadNode) {
-        node.rootScope = rootScope
-        node.contentScale = contentScale
-        node.alignment = alignment
-    }
-
-    override fun InspectorInfo.inspectableProperties() {
-        name = "scaleToFit"
-        properties["rootScope"] = rootScope
-        properties["scale"] = contentScale
-        properties["alignment"] = alignment
-    }
-}
-
-/**
- * Creates a Modifier Node to: 1) measure the layout with lookahead constraints, 2) scale the
- * resulting (potentially unfitting) layout based on the resizing container using the given
- * [contentScale] lambda.
- *
- * This node is designed to work in a lookahead scope, therefore it anticipates lookahead pass
- * before actual measure pass.
- */
-private class ScaleToFitInLookaheadNode(
-    var rootScope: AnimatedContentRootScope<*>,
-    var contentScale: ContentScale,
-    var alignment: Alignment
-) : Modifier.Node(), LayoutModifierNode {
-    private var lookaheadConstraints: Constraints = Constraints()
-        set(value) {
-            lookaheadPassOccurred = true
-            field = value
-        }
-        get() {
-            require(lookaheadPassOccurred) {
-                "Error: Attempting to read lookahead constraints before lookahead pass."
-            }
-            return field
-        }
-    private var lookaheadPassOccurred = false
-
-    override fun onDetach() {
-        super.onDetach()
-        lookaheadPassOccurred = false
-    }
-
-    override fun MeasureScope.measure(
-        measurable: Measurable,
-        constraints: Constraints
-    ): MeasureResult {
-        if (isLookingAhead) lookaheadConstraints = constraints
-        // Measure with lookahead constraints.
-        val placeable = measurable.measure(lookaheadConstraints)
-        val contentSize = IntSize(placeable.width, placeable.height)
-        val sizeToReport = if (isLookingAhead) {
-            // report size of the target content, as that's what the content will be scaled to.
-            rootScope.targetSize
-        } else {
-            // report current animated size && scale based on that and full size
-            rootScope.currentSize
-        }
-        val resolvedScale =
-            if (contentSize.width == 0 || contentSize.height == 0) {
-                ScaleFactor(1f, 1f)
-            } else
-                contentScale.computeScaleFactor(contentSize.toSize(), sizeToReport.toSize())
-        return layout(sizeToReport.width, sizeToReport.height) {
-            val (x, y) = alignment.align(
-                IntSize(
-                    (contentSize.width * resolvedScale.scaleX).roundToInt(),
-                    (contentSize.height * resolvedScale.scaleY).roundToInt()
-                ),
-                sizeToReport,
-                layoutDirection
-            )
-            placeable.placeWithLayer(x, y) {
-                scaleX = resolvedScale.scaleX
-                scaleY = resolvedScale.scaleY
-                transformOrigin = TransformOrigin(0f, 0f)
-            }
-        }
-    }
-}
-
-/**
- * Fixed key to read customization out of EnterTransition and ExitTransition.
- */
-private val ScaleToFitTransitionKey = Any()
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt
index b11c7c0..1d3c909 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt
@@ -21,6 +21,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.colorspace.ColorSpace
 import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.compose.ui.util.fastCoerceIn
 
 /**
  * A lambda that takes a [ColorSpace] and returns a converter that can both convert a [Color] to
@@ -36,10 +37,10 @@
             },
             convertFromVector = { vector ->
                 Color(
-                    vector.v2.coerceIn(0f, 1f), // L (red)
-                    vector.v3.coerceIn(-0.5f, 0.5f), // a (blue)
-                    vector.v4.coerceIn(-0.5f, 0.5f), // b (green)
-                    vector.v1.coerceIn(0f, 1f), // alpha
+                    vector.v2.fastCoerceIn(0f, 1f), // L (red)
+                    vector.v3.fastCoerceIn(-0.5f, 0.5f), // a (blue)
+                    vector.v4.fastCoerceIn(-0.5f, 0.5f), // b (green)
+                    vector.v1.fastCoerceIn(0f, 1f), // alpha
                     ColorSpaces.Oklab
                 ).convert(colorSpace)
             }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
index 190bd74..bbb3dc3 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/androidUnitTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposerParamSignatureTests.kt
@@ -1814,4 +1814,35 @@
     ) {
         assertFalse(it.contains("INVOKESTATIC kotlin/jvm/internal/Reflection.property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;"))
     }
+
+    @Test
+    fun testComposableAdaptedFunctionReference() = validateBytecode(
+        """
+            class ScrollState {
+                fun test(index: Int, default: Int = 0): Int = 0
+                fun testExact(index: Int): Int = 0
+            }
+            fun scrollState(): ScrollState = TODO()
+
+            @Composable fun rememberFooInline() = fooInline(scrollState()::test)
+            @Composable fun rememberFoo() = foo(scrollState()::test)
+            @Composable fun rememberFooExactInline() = fooInline(scrollState()::testExact)
+            @Composable fun rememberFooExact() = foo(scrollState()::testExact)
+
+            @Composable
+            inline fun fooInline(block: (Int) -> Int) = block(0)
+
+            @Composable
+            fun foo(block: (Int) -> Int) = block(0)
+        """,
+        validate = {
+            // Validate that function references in inline calls are actually getting inlined
+            assertFalse(
+                it.contains("""INVOKESPECIAL Test_0Kt${'$'}rememberFooInline$1$1.<init> (Ljava/lang/Object;)V""")
+            )
+            assertFalse(
+                it.contains("""INVOKESPECIAL Test_0Kt${'$'}rememberFooExactInline$1$1.<init> (Ljava/lang/Object;)V""")
+            )
+        }
+    )
 }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
index fd5eb21..55b2040 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
@@ -30,6 +30,7 @@
 abstract class AbstractIrTransformTest(useFir: Boolean) : AbstractCodegenTest(useFir) {
     override fun CompilerConfiguration.updateConfiguration() {
         put(ComposeConfiguration.SOURCE_INFORMATION_ENABLED_KEY, true)
+        put(ComposeConfiguration.STRONG_SKIPPING_ENABLED_KEY, true)
     }
 
     @JvmField
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposeModuleMetricsTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposeModuleMetricsTests.kt
index d2c9ea1..afb7b31 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposeModuleMetricsTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ComposeModuleMetricsTests.kt
@@ -16,9 +16,15 @@
 
 package androidx.compose.compiler.plugins.kotlin
 
+import org.jetbrains.kotlin.config.CompilerConfiguration
 import org.junit.Test
 
 class ComposeModuleMetricsTests(useFir: Boolean) : AbstractMetricsTransformTest(useFir) {
+    override fun CompilerConfiguration.updateConfiguration() {
+        // Tests in this file are about testing the output, so we want non-skippable composables
+        put(ComposeConfiguration.STRONG_SKIPPING_ENABLED_KEY, false)
+    }
+
     @Test
     fun testStableAndUnstableClassesTxt() = assertClasses(
         """
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
index 3c11d14..31468ef 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
@@ -2376,4 +2376,37 @@
             }
         """.trimIndent()
     )
+
+    @Test
+    fun testGroupsInLoops() = verifyGoldenComposeIrTransform(
+        """
+            import androidx.compose.runtime.*
+
+            @Composable
+            private fun KeyContent1(items: List<Int>) {
+                items.forEach { item ->
+                    if (item > -1) {
+                        key(item) {
+                            remember {
+                                item
+                            }
+                        }
+                    }
+                }
+            }
+
+            @Composable
+            private fun KeyContent2(items: List<Int>) {
+                for (item in items) {
+                    if (item > -1) {
+                        key(item) {
+                            remember {
+                                item
+                            }
+                        }
+                    }
+                }
+            }
+        """
+    )
 }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt
index b8dceda..4164c6d 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt
@@ -652,4 +652,28 @@
             }
         """
     )
+
+    @Test
+    fun testAdaptedFunctionRef() = verifyGoldenComposeIrTransform(
+        """
+            import androidx.compose.runtime.Composable
+
+            class ScrollState {
+                fun test(index: Int, default: Int = 0): Int = 0
+                fun testExact(index: Int): Int = 0
+            }
+            fun scrollState(): ScrollState = TODO()
+
+            @Composable fun rememberFooInline() = fooInline(scrollState()::test)
+            @Composable fun rememberFoo() = foo(scrollState()::test)
+            @Composable fun rememberFooExactInline() = fooInline(scrollState()::testExact)
+            @Composable fun rememberFooExact() = foo(scrollState()::testExact)
+
+            @Composable
+            inline fun fooInline(block: (Int) -> Int) = block(0)
+
+            @Composable
+            fun foo(block: (Int) -> Int) = block(0)
+        """,
+    )
 }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
index 87e04978..9aec5bf 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
@@ -749,6 +749,42 @@
             }
         """,
     )
+
+    @Test
+    fun testMemoizationWStableCapture() = verifyGoldenComposeIrTransform(
+        source = """
+            import androidx.compose.runtime.*
+
+            @Composable fun Test(param: String, unstable: List<*>) {
+                Wrapper {
+                    println(param)
+                }
+            }
+        """,
+        extra = """
+                import androidx.compose.runtime.*
+
+                @Composable fun Wrapper(block: () -> Unit) {}
+            """,
+    )
+
+    @Test
+    fun testMemoizationWUnstableCapture() = verifyGoldenComposeIrTransform(
+        source = """
+            import androidx.compose.runtime.*
+
+            @Composable fun Test(param: String, unstable: List<*>) {
+                Wrapper {
+                    println(unstable)
+                }
+            }
+        """,
+        extra = """
+                import androidx.compose.runtime.*
+
+                @Composable fun Wrapper(block: () -> Unit) {}
+            """,
+    )
 }
 
 class RememberIntrinsicTransformTestsStrongSkipping(
@@ -795,4 +831,17 @@
                 @Composable fun Wrapper(block: () -> Unit) {}
             """,
     )
+
+    @Test
+    fun testRememberWithUnstableParam() = verifyGoldenComposeIrTransform(
+        source = """
+            import androidx.compose.runtime.*
+
+            @Composable fun Test(param: String, unstable: List<*>) {
+                remember(unstable) {
+                    unstable[0]
+                }
+            }
+        """,
+    )
 }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/StaticExpressionDetectionTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/StaticExpressionDetectionTests.kt
index 0740f85..4913143 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/StaticExpressionDetectionTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/StaticExpressionDetectionTests.kt
@@ -26,7 +26,7 @@
 
 class StaticExpressionDetectionTests(useFir: Boolean) : AbstractIrTransformTest(useFir) {
     @Test
-    fun testUnstableTypesAreNeverStatic() = assertUnstable(
+    fun testUnstableTypesAreNeverStatic() = assertUncertain(
         expression = "Any()"
     )
 
@@ -49,7 +49,7 @@
     )
 
     @Test
-    fun testComputedValReferencesAreNotStatic() = assertStableAndNotStatic(
+    fun testComputedValReferencesAreNotStatic() = assertUncertain(
         expression = "computedProperty",
         extraSrc = """
             val computedProperty get() = 42
@@ -57,7 +57,7 @@
     )
 
     @Test
-    fun testVarReferencesAreNotStatic() = assertStableAndNotStatic(
+    fun testVarReferencesAreNotStatic() = assertUncertain(
         expression = "mutableProperty",
         extraSrc = """
             var mutableProperty = 42
@@ -215,7 +215,7 @@
         )
     }
 
-    private fun assertStableAndNotStatic(
+    private fun assertUncertain(
         expression: String,
         @Language("kotlin")
         extraSrc: String = ""
@@ -228,19 +228,6 @@
         )
     }
 
-    private fun assertUnstable(
-        expression: String,
-        @Language("kotlin")
-        extraSrc: String = ""
-    ) {
-        assertParameterChangeBitsForExpression(
-            message = "Expression `$expression` did not compile with the correct %changed flags",
-            expression = expression,
-            extraSrc = extraSrc,
-            expectedEncodedChangedParameter = ChangedParameterEncoding.Unstable
-        )
-    }
-
     private fun assertParameterChangeBitsForExpression(
         message: String,
         expression: String,
@@ -321,16 +308,14 @@
     }
 
     private enum class ChangedParameterEncoding(val bits: Int) {
-        Uncertain(0b000),
-        Same(0b001),
-        Different(0b010),
-        Static(0b011),
-        Unstable(0b100),
-
+        Uncertain(0b00),
+        Same(0b01),
+        Different(0b10),
+        Static(0b11),
         ;
 
         companion object {
-            const val Mask = 0b111
+            const val Mask = 0b11
         }
     }
 }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
index 44c3e39..f4a354e 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
@@ -1576,4 +1576,42 @@
             """
         )
     }
+
+    @Test
+    fun testErrorInAnonymousFunctionPropertyInitializer() {
+        assumeTrue(!useFir)
+        check(
+            """
+                  import androidx.compose.runtime.Composable
+                  @Composable fun ComposableFunction() {}
+                  fun getMyClass(): Any {
+                      class MyClass {
+                          val property = <!COMPOSABLE_EXPECTED!>fun() {
+                              <!COMPOSABLE_INVOCATION!>ComposableFunction<!>()  // invocation
+                          }<!>
+                      }
+                      return MyClass()
+                  }
+            """
+        )
+    }
+
+    @Test
+    fun testErrorInAnonymousFunctionPropertyInitializerForK2() {
+        assumeTrue(useFir)
+        check(
+            """
+                  import androidx.compose.runtime.Composable
+                  @Composable fun ComposableFunction() {}
+                  fun getMyClass(): Any {
+                      class MyClass {
+                          val property = <!COMPOSABLE_EXPECTED!>fun()<!> {
+                              <!COMPOSABLE_INVOCATION!>ComposableFunction<!>()  // invocation
+                          }
+                      }
+                      return MyClass()
+                  }
+            """
+        )
+    }
 }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/K2CompilerFacade.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/K2CompilerFacade.kt
index 6c095ec..ff32894 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/K2CompilerFacade.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/facade/K2CompilerFacade.kt
@@ -216,6 +216,7 @@
                 configuration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES),
                 EvaluatedConstTracker.create(),
                 configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
+                configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
                 allowNonCachedDeclarations = false
             ),
             IrGenerationExtension.getInstances(project),
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = false\135.txt"
index 83c98ae..14e2237c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = false\135.txt"
@@ -25,13 +25,24 @@
 fun A(y: Int, x: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)P(1)<B(x)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
   }
-  used(y)
-  B(x, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    B(x, %composer, 0b1110 and %dirty shr 0b0011)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, x, %composer, updateChangedFlags(%changed or 0b0001))
@@ -41,12 +52,20 @@
 fun B(x: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  used(x)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(x)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     B(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = true\135.txt"
index 83c98ae..14e2237c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCallWithUnstableFinalClassInSameModule\133useFir = true\135.txt"
@@ -25,13 +25,24 @@
 fun A(y: Int, x: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)P(1)<B(x)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
   }
-  used(y)
-  B(x, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    B(x, %composer, 0b1110 and %dirty shr 0b0011)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, x, %composer, updateChangedFlags(%changed or 0b0001))
@@ -41,12 +52,20 @@
 fun B(x: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  used(x)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(x)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     B(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = false\135.txt"
index f9294a6..0aff2f9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = false\135.txt"
@@ -25,13 +25,24 @@
 fun A(y: Int, x: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)P(1)<B(x)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
   }
-  used(y)
-  B(x, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    B(x, %composer, 0b1110 and %dirty shr 0b0011)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, x, %composer, updateChangedFlags(%changed or 0b0001))
@@ -41,12 +52,20 @@
 fun B(x: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  used(x)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(x)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     B(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = true\135.txt"
index f9294a6..0aff2f9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testComposableCall\133useFir = true\135.txt"
@@ -25,13 +25,24 @@
 fun A(y: Int, x: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)P(1)<B(x)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
   }
-  used(y)
-  B(x, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    B(x, %composer, 0b1110 and %dirty shr 0b0011)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, x, %composer, updateChangedFlags(%changed or 0b0001))
@@ -41,12 +52,20 @@
 fun B(x: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  used(x)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(x)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     B(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = false\135.txt"
index 1fab519..5610086 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = false\135.txt"
@@ -18,13 +18,21 @@
 fun A(y: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<A(Wrap...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  used(y)
-  A(Wrapper(Foo()), %composer, Wrapper.%stable)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    A(Wrapper(Foo()), %composer, Wrapper.%stable)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = true\135.txt"
index 1fab519..5610086 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testEmptyClassAcrossModules\133useFir = true\135.txt"
@@ -18,13 +18,21 @@
 fun A(y: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<A(Wrap...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  used(y)
-  A(Wrapper(Foo()), %composer, Wrapper.%stable)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    A(Wrapper(Foo()), %composer, Wrapper.%stable)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = false\135.txt"
index 5ee1039..c41e4eb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = false\135.txt"
@@ -27,10 +27,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B)<A(Wrap...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(value)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(value)
+    } else {
+      %composer.changedInstance(value)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -51,16 +56,26 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(X)P(1)*<itemCo...>:Test.kt")
   val %dirty = %changed
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %dirty, -1, <>)
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
   }
-  val <iterator> = items.iterator()
-  while (<iterator>.hasNext()) {
-    val item = <iterator>.next()
-    itemContent(item, %composer, 0b01110000 and %dirty)
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(itemContent)) 0b00100000 else 0b00010000
   }
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    val <iterator> = items.iterator()
+    while (<iterator>.hasNext()) {
+      val item = <iterator>.next()
+      itemContent(item, %composer, 0b01110000 and %dirty)
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     X(items, itemContent, %composer, updateChangedFlags(%changed or 0b0001))
@@ -70,12 +85,20 @@
 fun C(items: List<String>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(C)<X(item...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
   }
-  X(items, ComposableSingletons%TestKt.lambda-1, %composer, 0b00111000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    X(items, ComposableSingletons%TestKt.lambda-1, %composer, 0b00110000 or 0b1110 and %dirty)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     C(items, %composer, updateChangedFlags(%changed or 0b0001))
@@ -85,10 +108,10 @@
   val lambda-1: Function3<String, Composer, Int, Unit> = composableLambdaInstance(<>, false) { item: String, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A(item...>,<A(Wrap...>:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(item)) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = true\135.txt"
index 5ee1039..c41e4eb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testLocalParameterBasedTypeParameterSubstitution\133useFir = true\135.txt"
@@ -27,10 +27,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B)<A(Wrap...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(value)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(value)
+    } else {
+      %composer.changedInstance(value)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -51,16 +56,26 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(X)P(1)*<itemCo...>:Test.kt")
   val %dirty = %changed
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %dirty, -1, <>)
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
   }
-  val <iterator> = items.iterator()
-  while (<iterator>.hasNext()) {
-    val item = <iterator>.next()
-    itemContent(item, %composer, 0b01110000 and %dirty)
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(itemContent)) 0b00100000 else 0b00010000
   }
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    val <iterator> = items.iterator()
+    while (<iterator>.hasNext()) {
+      val item = <iterator>.next()
+      itemContent(item, %composer, 0b01110000 and %dirty)
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     X(items, itemContent, %composer, updateChangedFlags(%changed or 0b0001))
@@ -70,12 +85,20 @@
 fun C(items: List<String>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(C)<X(item...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
   }
-  X(items, ComposableSingletons%TestKt.lambda-1, %composer, 0b00111000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    X(items, ComposableSingletons%TestKt.lambda-1, %composer, 0b00110000 or 0b1110 and %dirty)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     C(items, %composer, updateChangedFlags(%changed or 0b0001))
@@ -85,10 +108,10 @@
   val lambda-1: Function3<String, Composer, Int, Unit> = composableLambdaInstance(<>, false) { item: String, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A(item...>,<A(Wrap...>:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(item)) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = false\135.txt"
index 290e146..aaf1993 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = false\135.txt"
@@ -56,18 +56,26 @@
 fun A(y: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<A(X(li...>,<A(Stab...>,<A(Unst...>,<A(Sing...>,<A(Sing...>,<A(Sing...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  used(y)
-  A(X(listOf(StableClass())), %composer, 0b1000)
-  A(StableDelegateProp(), %composer, 0)
-  A(UnstableDelegateProp(), %composer, UnstableDelegate.%stable)
-  A(SingleParamProp(0), %composer, SingleParamProp.%stable or 0)
-  A(SingleParamNonProp(0), %composer, SingleParamNonProp.%stable)
-  A(SingleParamProp(Any()), %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    A(X(listOf(StableClass())), %composer, 0)
+    A(StableDelegateProp(), %composer, 0)
+    A(UnstableDelegateProp(), %composer, UnstableDelegate.%stable)
+    A(SingleParamProp(0), %composer, SingleParamProp.%stable or 0)
+    A(SingleParamNonProp(0), %composer, SingleParamNonProp.%stable)
+    A(SingleParamProp(Any()), %composer, 0)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = true\135.txt"
index 290e146..aaf1993 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypesInSameModule\133useFir = true\135.txt"
@@ -56,18 +56,26 @@
 fun A(y: Any, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<A(X(li...>,<A(Stab...>,<A(Unst...>,<A(Sing...>,<A(Sing...>,<A(Sing...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  used(y)
-  A(X(listOf(StableClass())), %composer, 0b1000)
-  A(StableDelegateProp(), %composer, 0)
-  A(UnstableDelegateProp(), %composer, UnstableDelegate.%stable)
-  A(SingleParamProp(0), %composer, SingleParamProp.%stable or 0)
-  A(SingleParamNonProp(0), %composer, SingleParamNonProp.%stable)
-  A(SingleParamProp(Any()), %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(y)
+    A(X(listOf(StableClass())), %composer, 0)
+    A(StableDelegateProp(), %composer, 0)
+    A(UnstableDelegateProp(), %composer, UnstableDelegate.%stable)
+    A(SingleParamProp(0), %composer, SingleParamProp.%stable or 0)
+    A(SingleParamNonProp(0), %composer, SingleParamNonProp.%stable)
+    A(SingleParamProp(Any()), %composer, 0)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     A(y, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = false\135.txt"
index ec1c909..b57a2dc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = false\135.txt"
@@ -37,9 +37,11 @@
   sourceInformation(%composer, "C(A)<A()>,<A(Empt...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(X(li...>,<A(X(li...>,<A(NonB...>,<A(NonB...>,<A(Stab...>,<A(Unst...>:Test.kt")
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
-    %dirty = %dirty or 0b0010
+    %dirty = %dirty or 0b0110
+  } else if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       y = null
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = true\135.txt"
index ec1c909..b57a2dc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationOfVariousTypes\133useFir = true\135.txt"
@@ -37,9 +37,11 @@
   sourceInformation(%composer, "C(A)<A()>,<A(Empt...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(X(li...>,<A(X(li...>,<A(NonB...>,<A(NonB...>,<A(Stab...>,<A(Unst...>:Test.kt")
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
-    %dirty = %dirty or 0b0010
+    %dirty = %dirty or 0b0110
+  } else if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       y = null
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = false\135.txt"
index 63f6933..1a3e797 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = false\135.txt"
@@ -100,9 +100,11 @@
   sourceInformation(%composer, "C(A)<A(>:Test.kt#2p")
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
-    %dirty = %dirty or 0b0010
+    %dirty = %dirty or 0b0110
+  } else if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       y = null
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = true\135.txt"
index 63f6933..1a3e797 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParamsSameModule\133useFir = true\135.txt"
@@ -100,9 +100,11 @@
   sourceInformation(%composer, "C(A)<A(>:Test.kt#2p")
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
-    %dirty = %dirty or 0b0010
+    %dirty = %dirty or 0b0110
+  } else if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       y = null
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = false\135.txt"
index 0cc7dc7..1e357c1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = false\135.txt"
@@ -57,9 +57,11 @@
   sourceInformation(%composer, "C(A)<A(>:Test.kt")
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
-    %dirty = %dirty or 0b0010
+    %dirty = %dirty or 0b0110
+  } else if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       y = null
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = true\135.txt"
index 0cc7dc7..1e357c1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ClassStabilityTransformTests/testStabilityPropagationTooManyTypeParams\133useFir = true\135.txt"
@@ -57,9 +57,11 @@
   sourceInformation(%composer, "C(A)<A(>:Test.kt")
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
-    %dirty = %dirty or 0b0010
+    %dirty = %dirty or 0b0110
+  } else if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(y)) 0b0100 else 0b0010
   }
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       y = null
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = false\135.txt"
index 00c10f8..9605088 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = false\135.txt"
@@ -38,10 +38,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(composeVector)<emit>:Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(composable)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = true\135.txt"
index 00c10f8..9605088 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testComposableNestedCall\133useFir = true\135.txt"
@@ -38,10 +38,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(composeVector)<emit>:Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(composable)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = false\135.txt"
index 1239201..346633b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = false\135.txt"
@@ -88,7 +88,7 @@
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
-      val tmp0 = <this>.foo%delegate.getValue(<this>, ::foo, %composer, 0b001000000000 or 0b01110000 and %changed shl 0b0011)
+      val tmp0 = <this>.foo%delegate.getValue(<this>, ::foo, %composer, 0b01110000 and %changed shl 0b0011)
       if (isTraceInProgress()) {
         traceEventEnd()
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = true\135.txt"
index 1239201..346633b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testDelegateCall\133useFir = true\135.txt"
@@ -88,7 +88,7 @@
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
-      val tmp0 = <this>.foo%delegate.getValue(<this>, ::foo, %composer, 0b001000000000 or 0b01110000 and %changed shl 0b0011)
+      val tmp0 = <this>.foo%delegate.getValue(<this>, ::foo, %composer, 0b01110000 and %changed shl 0b0011)
       if (isTraceInProgress()) {
         traceEventEnd()
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = false\135.txt"
index b5fca55..22fcfc7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = false\135.txt"
@@ -44,10 +44,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Wrapper)<block(...>:Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(block)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -67,10 +67,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Leaf):Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -90,10 +90,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test):Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(value)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -101,7 +101,7 @@
     sourceInformation(%composer, "<Wrappe...>")
     Wrapper(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<Leaf("...>:Test.kt#2487m")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = true\135.txt"
index b5fca55..22fcfc7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testKeyCall\133useFir = true\135.txt"
@@ -44,10 +44,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Wrapper)<block(...>:Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(block)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -67,10 +67,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Leaf):Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -90,10 +90,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test):Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(value)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -101,7 +101,7 @@
     sourceInformation(%composer, "<Wrappe...>")
     Wrapper(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<Leaf("...>:Test.kt#2487m")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = false\135.txt"
index 9d740b5..aef3515 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = false\135.txt"
@@ -47,10 +47,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(test)<delega...>:Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(foo)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = true\135.txt"
index 9d740b5..aef3515 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableDelegateCall\133useFir = true\135.txt"
@@ -47,10 +47,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(test)<delega...>:Test.kt#2487m")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(foo)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = false\135.txt"
index 6d43cd4..104b4c0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = false\135.txt"
@@ -43,7 +43,7 @@
   if (%dirty and 0b1110 == 0) {
     %dirty = %dirty or 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = true\135.txt"
index 6d43cd4..104b4c0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testStableVarargParams\133useFir = true\135.txt"
@@ -43,7 +43,7 @@
   if (%dirty and 0b1110 == 0) {
     %dirty = %dirty or 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = false\135.txt"
index 4013b66..8bc3952 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = false\135.txt"
@@ -61,7 +61,7 @@
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
-        val tmp0 = foo%delegate.getValue(null, ::foo%delegate, %composer, 0b00111000)
+        val tmp0 = foo%delegate.getValue(null, ::foo%delegate, %composer, 0b00110000)
         if (isTraceInProgress()) {
           traceEventEnd()
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = true\135.txt"
index 4013b66..8bc3952 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testUnstableDelegateCall\133useFir = true\135.txt"
@@ -61,7 +61,7 @@
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
-        val tmp0 = foo%delegate.getValue(null, ::foo%delegate, %composer, 0b00111000)
+        val tmp0 = foo%delegate.getValue(null, ::foo%delegate, %composer, 0b00110000)
         if (isTraceInProgress()) {
           traceEventEnd()
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = false\135.txt"
index 428b269..b57aa24 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = false\135.txt"
@@ -31,12 +31,27 @@
 fun VarArgsFirst(foo: Array<out Any?>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(VarArgsFirst):Test.kt#2487m")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  %composer.startMovableGroup(<>, foo.size)
+  val <iterator> = foo.iterator()
+  while (<iterator>.hasNext()) {
+    val value = <iterator>.next()
+    %dirty = %dirty or if (%composer.changedInstance(value)) 0b0100 else 0
   }
-  println(foo)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  %composer.endMovableGroup()
+  if (%dirty and 0b1110 == 0) {
+    %dirty = %dirty or 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    println(foo)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     VarArgsFirst(*foo, %composer, updateChangedFlags(%changed or 0b0001))
@@ -52,7 +67,7 @@
     }
     VarArgsFirst(
       %composer = %composer,
-      %changed = 8
+      %changed = 0
     )
     if (isTraceInProgress()) {
       traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = true\135.txt"
index 428b269..b57aa24 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testVarargWithNoArgs\133useFir = true\135.txt"
@@ -31,12 +31,27 @@
 fun VarArgsFirst(foo: Array<out Any?>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(VarArgsFirst):Test.kt#2487m")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  %composer.startMovableGroup(<>, foo.size)
+  val <iterator> = foo.iterator()
+  while (<iterator>.hasNext()) {
+    val value = <iterator>.next()
+    %dirty = %dirty or if (%composer.changedInstance(value)) 0b0100 else 0
   }
-  println(foo)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  %composer.endMovableGroup()
+  if (%dirty and 0b1110 == 0) {
+    %dirty = %dirty or 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    println(foo)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     VarArgsFirst(*foo, %composer, updateChangedFlags(%changed or 0b0001))
@@ -52,7 +67,7 @@
     }
     VarArgsFirst(
       %composer = %composer,
-      %changed = 8
+      %changed = 0
     )
     if (isTraceInProgress()) {
       traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt"
index f8c822e..65f9106 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt"
@@ -22,7 +22,7 @@
 @Composable
 fun Test(foo: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
-  sourceInformation(%composer, "C(Test)*<A()>,<B()>:Test.kt")
+  sourceInformation(%composer, "C(Test)*<A()>:Test.kt")
   val %dirty = %changed
   if (%changed and 0b1110 == 0) {
     %dirty = %dirty or if (%composer.changed(foo)) 0b0100 else 0b0010
@@ -33,9 +33,12 @@
     }
     with(foo) {
       A(%this%with, %composer, 0)
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "*<B()>")
       with(Bar()) {
         B(%this%with, %this%with, %composer, 0)
       }
+      %composer.endReplaceableGroup()
     }
     if (isTraceInProgress()) {
       traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt"
index f8c822e..65f9106 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt"
@@ -22,7 +22,7 @@
 @Composable
 fun Test(foo: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
-  sourceInformation(%composer, "C(Test)*<A()>,<B()>:Test.kt")
+  sourceInformation(%composer, "C(Test)*<A()>:Test.kt")
   val %dirty = %changed
   if (%changed and 0b1110 == 0) {
     %dirty = %dirty or if (%composer.changed(foo)) 0b0100 else 0b0010
@@ -33,9 +33,12 @@
     }
     with(foo) {
       A(%this%with, %composer, 0)
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "*<B()>")
       with(Bar()) {
         B(%this%with, %this%with, %composer, 0)
       }
+      %composer.endReplaceableGroup()
     }
     if (isTraceInProgress()) {
       traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = false\135.txt"
index 436dd3e..4a2c924 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = false\135.txt"
@@ -41,7 +41,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A()>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = true\135.txt"
index 436dd3e..4a2c924 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testCallingAWrapperComposable\133useFir = true\135.txt"
@@ -41,7 +41,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A()>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt"
index f419f03..99f3e5e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt"
@@ -41,10 +41,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(b)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(b)
+    } else {
+      %composer.changedInstance(b)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt"
index f419f03..99f3e5e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt"
@@ -41,10 +41,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(b)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(b)
+    } else {
+      %composer.changedInstance(b)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = false\135.txt"
index 1369b3a..3452ced 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = false\135.txt"
@@ -23,10 +23,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)P(0:InlineClass)<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(value))) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = true\135.txt"
index 1369b3a..3452ced 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableWithInlineClass\133useFir = true\135.txt"
@@ -23,10 +23,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)P(0:InlineClass)<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(value))) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = false\135.txt"
index e9d58b0..e04ca63 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = false\135.txt"
@@ -39,15 +39,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(isError)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(keyboardActions2)) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011010001 != 0b10010000 || !%composer.skipping) {
+  if (%dirty and 0b10010001 != 0b10010000 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       isError = false
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = true\135.txt"
index e9d58b0..e04ca63 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposeIrSkippingWithDefaultsRelease\133useFir = true\135.txt"
@@ -39,15 +39,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(isError)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(keyboardActions2)) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011010001 != 0b10010000 || !%composer.skipping) {
+  if (%dirty and 0b10010001 != 0b10010000 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       isError = false
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt"
index 4c4ea1d..6eb97a7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt"
@@ -20,10 +20,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Dialog>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(param)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt"
index 4c4ea1d..6eb97a7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt"
@@ -20,10 +20,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Dialog>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(param)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt"
index 5deb31b..abf76e6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt"
@@ -25,10 +25,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<IW>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt"
index 5deb31b..abf76e6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt"
@@ -25,10 +25,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<IW>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = false\135.txt"
index b0ca058..2f15ece 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = false\135.txt"
@@ -35,10 +35,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = true\135.txt"
index b0ca058..2f15ece 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInNonInline_NormalComposable\133useFir = true\135.txt"
@@ -35,10 +35,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt"
index 20013e7..ac7376c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt"
@@ -25,10 +25,10 @@
   sourceInformation(%composer, "C(test_CM1_RetFun)<Text("...>,<M1>,<Text("...>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt"
index 20013e7..ac7376c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt"
@@ -25,10 +25,10 @@
   sourceInformation(%composer, "C(test_CM1_RetFun)<Text("...>,<M1>,<Text("...>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt"
index c63d5a6..98027c1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt"
@@ -24,13 +24,13 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)P(1)<rememb...>,*<get(bK...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(start)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(end)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt"
index c63d5a6..98027c1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt"
@@ -24,13 +24,13 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)P(1)<rememb...>,*<get(bK...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(start)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(end)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt"
new file mode 100644
index 0000000..c4bbba2
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt"
@@ -0,0 +1,122 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable
+private fun KeyContent1(items: List<Int>) {
+    items.forEach { item ->
+        if (item > -1) {
+            key(item) {
+                remember {
+                    item
+                }
+            }
+        }
+    }
+}
+
+@Composable
+private fun KeyContent2(items: List<Int>) {
+    for (item in items) {
+        if (item > -1) {
+            key(item) {
+                remember {
+                    item
+                }
+            }
+        }
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+private fun KeyContent1(items: List<Int>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(KeyContent1):Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    items.forEach { item: Int ->
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "")
+      if (item > -1) {
+        %composer.startMovableGroup(<>, item)
+        sourceInformation(%composer, "<rememb...>")
+        val tmp0 = <block>{
+          %composer.startReplaceableGroup(<>)
+          sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+          val tmp1_group = %composer.cache(false) {
+            item
+          }
+          %composer.endReplaceableGroup()
+          tmp1_group
+        }
+        %composer.endMovableGroup()
+        tmp0
+      }
+      %composer.endReplaceableGroup()
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    KeyContent1(items, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
+@Composable
+private fun KeyContent2(items: List<Int>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(KeyContent2):Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    val <iterator> = items.iterator()
+    while (<iterator>.hasNext()) {
+      val item = <iterator>.next()
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "")
+      if (item > -1) {
+        %composer.startMovableGroup(<>, item)
+        sourceInformation(%composer, "<rememb...>")
+        val tmp0 = <block>{
+          %composer.startReplaceableGroup(<>)
+          sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+          val tmp1_group = %composer.cache(false) {
+            item
+          }
+          %composer.endReplaceableGroup()
+          tmp1_group
+        }
+        %composer.endMovableGroup()
+        tmp0
+      }
+      %composer.endReplaceableGroup()
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    KeyContent2(items, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt"
new file mode 100644
index 0000000..b19edaf
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt"
@@ -0,0 +1,118 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable
+private fun KeyContent1(items: List<Int>) {
+    items.forEach { item ->
+        if (item > -1) {
+            key(item) {
+                remember {
+                    item
+                }
+            }
+        }
+    }
+}
+
+@Composable
+private fun KeyContent2(items: List<Int>) {
+    for (item in items) {
+        if (item > -1) {
+            key(item) {
+                remember {
+                    item
+                }
+            }
+        }
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+private fun KeyContent1(items: List<Int>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(KeyContent1):Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    items.forEach { item: Int ->
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "")
+      if (item > -1) {
+        %composer.startMovableGroup(<>, item)
+        sourceInformation(%composer, "<rememb...>")
+        %composer.startReplaceableGroup(<>)
+        sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+        %composer.cache(false) {
+          item
+        }
+        %composer.endReplaceableGroup()
+        %composer.endMovableGroup()
+      }
+      %composer.endReplaceableGroup()
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    KeyContent1(items, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
+@Composable
+private fun KeyContent2(items: List<Int>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(KeyContent2):Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    val <iterator> = items.iterator()
+    while (<iterator>.hasNext()) {
+      val item = <iterator>.next()
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "")
+      if (item > -1) {
+        %composer.startMovableGroup(<>, item)
+        sourceInformation(%composer, "<rememb...>")
+        val tmp0 = <block>{
+          %composer.startReplaceableGroup(<>)
+          sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+          val tmp1_group = %composer.cache(false) {
+            item
+          }
+          %composer.endReplaceableGroup()
+          tmp1_group
+        }
+        %composer.endMovableGroup()
+        tmp0
+      }
+      %composer.endReplaceableGroup()
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    KeyContent2(items, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = false\135.txt"
index 6806635..87cb845 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = false\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(ArrayConstructorTest)<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(n)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = true\135.txt"
index 6806635..87cb845 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineArrayConstructor\133useFir = true\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(ArrayConstructorTest)<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>,<rememb...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(n)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt"
index 212e96e..f603a80 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt"
@@ -26,11 +26,14 @@
     traceEventStart(<>, %changed, -1, <>)
   }
   %composer.startReplaceableGroup(<>)
-  sourceInformation(%composer, "*<Test("...>")
+  sourceInformation(%composer, "")
   InlineNonComposable {
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "*<Test("...>")
     repeat(10) { it: Int ->
       Test("InsideInline", %composer, 0b0110)
     }
+    %composer.endReplaceableGroup()
   }
   %composer.endReplaceableGroup()
   val tmp0 = Test("AfterInline", %composer, 0b0110)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt"
index 212e96e..f603a80 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt"
@@ -26,11 +26,14 @@
     traceEventStart(<>, %changed, -1, <>)
   }
   %composer.startReplaceableGroup(<>)
-  sourceInformation(%composer, "*<Test("...>")
+  sourceInformation(%composer, "")
   InlineNonComposable {
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "*<Test("...>")
     repeat(10) { it: Int ->
       Test("InsideInline", %composer, 0b0110)
     }
+    %composer.endReplaceableGroup()
   }
   %composer.endReplaceableGroup()
   val tmp0 = Test("AfterInline", %composer, 0b0110)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt"
index 9925e02..f4a59d1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt"
@@ -27,10 +27,10 @@
   sourceInformation(%composer, "C(Test)<A()>,<M3>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt"
index 9925e02..f4a59d1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt"
@@ -27,10 +27,10 @@
   sourceInformation(%composer, "C(Test)<A()>,<M3>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt"
index 04704d1..039aae79 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt"
@@ -34,13 +34,13 @@
   sourceInformation(%composer, "C(Test)<A()>,<M3>,<M3>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt"
index 04704d1..039aae79 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt"
@@ -34,13 +34,13 @@
   sourceInformation(%composer, "C(Test)<A()>,<M3>,<M3>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt"
index 54a51fd..5861274 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A()>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt"
index 54a51fd..5861274 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A()>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt"
index f8ec1a1..93faaff 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt"
@@ -33,10 +33,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(testInline_M1_W_Return_Func)<A()>,<M3>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt"
index f8ec1a1..93faaff 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt"
@@ -33,10 +33,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(testInline_M1_W_Return_Func)<A()>,<M3>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt"
index b70c5c4..ec150c6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt"
@@ -21,7 +21,7 @@
     %this%T.compose(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<M1>:Test.kt")
       val tmp0_marker = %composer.currentMarker
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt"
index b70c5c4..ec150c6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt"
@@ -21,7 +21,7 @@
     %this%T.compose(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<M1>:Test.kt")
       val tmp0_marker = %composer.currentMarker
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt"
index 3e4b12f..0ae15bf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt"
@@ -31,10 +31,10 @@
   sourceInformation(%composer, "C(testInline_M1_W_Return_Func)<A()>,<M1>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt"
index 3e4b12f..0ae15bf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt"
@@ -31,10 +31,10 @@
   sourceInformation(%composer, "C(testInline_M1_W_Return_Func)<A()>,<M1>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt"
index f6b0425..4e5850e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test_M3_M1_Return_M1)<A()>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt"
index f6b0425..4e5850e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test_M3_M1_Return_M1)<A()>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt"
index a2422c0..3fd2128 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test_M3_M1_Return_M3)<A()>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt"
index a2422c0..3fd2128 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test_M3_M1_Return_M3)<A()>,<M3>,<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt"
index 3e107a8..7471158 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<A(c)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt"
index 3e107a8..7471158 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<A(c)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = false\135.txt"
index 7f9961f..7464a8a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = false\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = true\135.txt"
index 7f9961f..7464a8a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithoutComposableCalls\133useFir = true\135.txt"
@@ -28,10 +28,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<A()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = false\135.txt"
index a69fcc1..f555bb9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = false\135.txt"
@@ -62,7 +62,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = true\135.txt"
index a69fcc1..f555bb9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNothingBody\133useFir = true\135.txt"
@@ -62,7 +62,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt"
index d4f4620..c4a2bf9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt"
@@ -34,37 +34,45 @@
 fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)*<P(i)>,<P(l)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
   }
-  while (items.hasNext()) {
-    val i = items.next()
-    val j = i
-    val k = i
-    val l = i
-    P(i, %composer, 0)
-    if (i == 0) {
-      %composer.startReplaceableGroup(<>)
-      sourceInformation(%composer, "<P(j)>")
-      P(j, %composer, 0)
-      %composer.endReplaceableGroup()
-      if (isTraceInProgress()) {
-        traceEventEnd()
-      }
-      %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
-        Example(items, %composer, updateChangedFlags(%changed or 0b0001))
-      }
-      return
-    } else {
-      %composer.startReplaceableGroup(<>)
-      sourceInformation(%composer, "<P(k)>")
-      P(k, %composer, 0)
-      %composer.endReplaceableGroup()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
     }
-    P(l, %composer, 0)
-  }
-  if (isTraceInProgress()) {
-    traceEventEnd()
+    while (items.hasNext()) {
+      val i = items.next()
+      val j = i
+      val k = i
+      val l = i
+      P(i, %composer, 0)
+      if (i == 0) {
+        %composer.startReplaceableGroup(<>)
+        sourceInformation(%composer, "<P(j)>")
+        P(j, %composer, 0)
+        %composer.endReplaceableGroup()
+        if (isTraceInProgress()) {
+          traceEventEnd()
+        }
+        %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+          Example(items, %composer, updateChangedFlags(%changed or 0b0001))
+        }
+        return
+      } else {
+        %composer.startReplaceableGroup(<>)
+        sourceInformation(%composer, "<P(k)>")
+        P(k, %composer, 0)
+        %composer.endReplaceableGroup()
+      }
+      P(l, %composer, 0)
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Example(items, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt"
index d4f4620..c4a2bf9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt"
@@ -34,37 +34,45 @@
 fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)*<P(i)>,<P(l)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(items)) 0b0100 else 0b0010
   }
-  while (items.hasNext()) {
-    val i = items.next()
-    val j = i
-    val k = i
-    val l = i
-    P(i, %composer, 0)
-    if (i == 0) {
-      %composer.startReplaceableGroup(<>)
-      sourceInformation(%composer, "<P(j)>")
-      P(j, %composer, 0)
-      %composer.endReplaceableGroup()
-      if (isTraceInProgress()) {
-        traceEventEnd()
-      }
-      %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
-        Example(items, %composer, updateChangedFlags(%changed or 0b0001))
-      }
-      return
-    } else {
-      %composer.startReplaceableGroup(<>)
-      sourceInformation(%composer, "<P(k)>")
-      P(k, %composer, 0)
-      %composer.endReplaceableGroup()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
     }
-    P(l, %composer, 0)
-  }
-  if (isTraceInProgress()) {
-    traceEventEnd()
+    while (items.hasNext()) {
+      val i = items.next()
+      val j = i
+      val k = i
+      val l = i
+      P(i, %composer, 0)
+      if (i == 0) {
+        %composer.startReplaceableGroup(<>)
+        sourceInformation(%composer, "<P(j)>")
+        P(j, %composer, 0)
+        %composer.endReplaceableGroup()
+        if (isTraceInProgress()) {
+          traceEventEnd()
+        }
+        %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+          Example(items, %composer, updateChangedFlags(%changed or 0b0001))
+        }
+        return
+      } else {
+        %composer.startReplaceableGroup(<>)
+        sourceInformation(%composer, "<P(k)>")
+        P(k, %composer, 0)
+        %composer.endReplaceableGroup()
+      }
+      P(l, %composer, 0)
+    }
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Example(items, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = false\135.txt"
index 094dfc9..060838d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = false\135.txt"
@@ -162,19 +162,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test01):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -197,19 +197,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test02)P(!2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -232,19 +232,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test03)P(!1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -267,19 +267,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test04)P(!1,2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -302,19 +302,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test05)P(!1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -337,19 +337,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test06)P(!1,3,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -372,19 +372,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test07)P(1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -407,19 +407,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test08)P(1!1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -442,19 +442,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test09)P(1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -477,19 +477,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test00)P(1,2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -512,19 +512,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test11)P(1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -547,19 +547,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test12)P(1,3,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -582,19 +582,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test13)P(2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -617,19 +617,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test14)P(2!1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -652,19 +652,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test15)P(2,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -687,19 +687,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test16)P(2,1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -722,19 +722,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test17)P(2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -757,19 +757,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test18)P(2,3,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -792,19 +792,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test19)P(3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -827,19 +827,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test20)P(3!1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -862,19 +862,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test21)P(3,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -897,19 +897,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test22)P(3,1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -932,19 +932,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test23)P(3,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -967,19 +967,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test24)P(3,2,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = true\135.txt"
index 094dfc9..060838d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testParameterOrderInformation\133useFir = true\135.txt"
@@ -162,19 +162,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test01):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -197,19 +197,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test02)P(!2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -232,19 +232,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test03)P(!1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -267,19 +267,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test04)P(!1,2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -302,19 +302,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test05)P(!1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -337,19 +337,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test06)P(!1,3,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -372,19 +372,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test07)P(1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -407,19 +407,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test08)P(1!1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -442,19 +442,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test09)P(1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -477,19 +477,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test00)P(1,2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -512,19 +512,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test11)P(1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -547,19 +547,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test12)P(1,3,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -582,19 +582,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test13)P(2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -617,19 +617,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test14)P(2!1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -652,19 +652,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test15)P(2,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -687,19 +687,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test16)P(2,1,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -722,19 +722,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test17)P(2,3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -757,19 +757,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test18)P(2,3,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -792,19 +792,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test19)P(3):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -827,19 +827,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test20)P(3!1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -862,19 +862,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test21)P(3,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -897,19 +897,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test22)P(3,1,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -932,19 +932,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test23)P(3,2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -967,19 +967,19 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test24)P(3,2,1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(p2)) 0b00100000 else 0b00010000
   }
-  if (%changed and 0b001110000000 == 0) {
+  if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p1)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(p0)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt"
index dd26235..36ea817 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Test(>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(param)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt"
index dd26235..36ea817 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Test(>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(param)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt"
index e3f76dc..d6d5953 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt"
@@ -40,7 +40,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<effect>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt"
index e3f76dc..d6d5953 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt"
@@ -40,7 +40,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<effect>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt"
index dabea88..537592c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt"
@@ -38,6 +38,30 @@
 fun Test6(): String? {
     TODO()
 }
+@Composable
+fun Test7(b: Boolean): String? {
+    if (b) {
+        return null
+    }
+    return "false"
+}
+@Composable
+fun Test8(): Unit? {
+    var unitNull: Unit? = null
+    Test6()
+    return unitNull
+}
+@Composable
+fun Test9(): Unit? {
+    var unitNotNull: Unit? = Unit
+    Test6()
+    return unitNotNull
+}
+@Composable
+fun Test10(): Unit? {
+    Test6()
+    return Unit
+}
 
 //
 // Transformed IR
@@ -220,4 +244,4 @@
   }
   %composer.endReplaceableGroup()
   return tmp0
-}
\ No newline at end of file
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt"
index bd4fb90..d205974 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt"
@@ -38,6 +38,30 @@
 fun Test6(): String? {
     TODO()
 }
+@Composable
+fun Test7(b: Boolean): String? {
+    if (b) {
+        return null
+    }
+    return "false"
+}
+@Composable
+fun Test8(): Unit? {
+    var unitNull: Unit? = null
+    Test6()
+    return unitNull
+}
+@Composable
+fun Test9(): Unit? {
+    var unitNotNull: Unit? = Unit
+    Test6()
+    return unitNotNull
+}
+@Composable
+fun Test10(): Unit? {
+    Test6()
+    return Unit
+}
 
 //
 // Transformed IR
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = false\135.txt"
index 805e55c..f839f83 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = false\135.txt"
@@ -20,10 +20,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)P(0:c#runtime.tests.LocalInlineClass):Test.kt#992ot2")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(value))) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, "androidx.compose.runtime.tests.Test (Test.kt:6)")
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = true\135.txt"
index 805e55c..f839f83 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceInformationWithPackageName\133useFir = true\135.txt"
@@ -20,10 +20,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)P(0:c#runtime.tests.LocalInlineClass):Test.kt#992ot2")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(value))) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, "androidx.compose.runtime.tests.Test (Test.kt:6)")
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt"
index 7cea7c6..4e5f7ed 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt"
@@ -43,7 +43,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<IW>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, "ComposableSingletons%TestKt.lambda-1.<anonymous> (Test.kt:6)")
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt"
index 7cea7c6..4e5f7ed 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt"
@@ -43,7 +43,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<IW>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, "ComposableSingletons%TestKt.lambda-1.<anonymous> (Test.kt:6)")
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = false\135.txt"
index a43f469..c30d56f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = false\135.txt"
@@ -32,7 +32,7 @@
   fun onCreate() {
     setContent(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<B(a)>,<B(a)>:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, "SomeClass.onCreate.<anonymous> (Test.kt:7)")
         }
@@ -53,7 +53,7 @@
   var a = "Test"
   setContent(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<B(a)>,<B(a)>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, "Test.<anonymous> (Test.kt:16)")
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = true\135.txt"
index a43f469..c30d56f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLocationOfCapturingComposableLambdas\133useFir = true\135.txt"
@@ -32,7 +32,7 @@
   fun onCreate() {
     setContent(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<B(a)>,<B(a)>:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, "SomeClass.onCreate.<anonymous> (Test.kt:7)")
         }
@@ -53,7 +53,7 @@
   var a = "Test"
   setContent(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<B(a)>,<B(a)>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, "Test.<anonymous> (Test.kt:16)")
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = false\135.txt"
index cac30e4..d4651ef 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = false\135.txt"
@@ -22,10 +22,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Text("...>,<Text("...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = true\135.txt"
index cac30e4..d4651ef 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable\133useFir = true\135.txt"
@@ -22,10 +22,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Text("...>,<Text("...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt"
index 30c84a6..af46314 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt"
@@ -25,10 +25,10 @@
   sourceInformation(%composer, "C(Test)<Text("...>,<M1>,<Text("...>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt"
index 30c84a6..af46314 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt"
@@ -25,10 +25,10 @@
   sourceInformation(%composer, "C(Test)<Text("...>,<M1>,<Text("...>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt"
index dbbe1f9..d924718 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Text("...>,<M1>,<Text("...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt"
index dbbe1f9..d924718 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<Text("...>,<M1>,<Text("...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt"
index 3c72d6c..468d6f3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt"
@@ -31,10 +31,10 @@
   sourceInformation(%composer, "C(test_CM1_CCM1_RetFun)<Text("...>,<M1>,<Text("...>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt"
index 3c72d6c..468d6f3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt"
@@ -31,10 +31,10 @@
   sourceInformation(%composer, "C(test_CM1_CCM1_RetFun)<Text("...>,<M1>,<Text("...>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = false\135.txt"
index 411b3cf..339eec7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = false\135.txt"
@@ -87,160 +87,160 @@
   val %dirty3 = %changed3
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b00010000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000000000000000
-  } else if (%changed1 and 0b001110000000000000000000 == 0) {
+  } else if (%changed1 and 0b000110000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a16)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b00100000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000000000000000
-  } else if (%changed1 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed1 and 0b110000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a17)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b01000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000000000000000
-  } else if (%changed1 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a18)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b10000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000000000000000
-  } else if (%changed1 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a19)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b000100000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110
-  } else if (%changed2 and 0b1110 == 0) {
+  } else if (%changed2 and 0b0110 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a20)) 0b0100 else 0b0010
   }
   if (%default and 0b001000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000
-  } else if (%changed2 and 0b01110000 == 0) {
+  } else if (%changed2 and 0b00110000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a21)) 0b00100000 else 0b00010000
   }
   if (%default and 0b010000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000
-  } else if (%changed2 and 0b001110000000 == 0) {
+  } else if (%changed2 and 0b000110000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a22)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b100000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000
-  } else if (%changed2 and 0b0001110000000000 == 0) {
+  } else if (%changed2 and 0b110000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a23)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0001000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000
-  } else if (%changed2 and 0b1110000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a24)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b0010000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000
-  } else if (%changed2 and 0b01110000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a25)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b0100000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000000000000000
-  } else if (%changed2 and 0b001110000000000000000000 == 0) {
+  } else if (%changed2 and 0b000110000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a26)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b1000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000000000000000
-  } else if (%changed2 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed2 and 0b110000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a27)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b00010000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000000000000000
-  } else if (%changed2 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a28)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b00100000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000000000000000
-  } else if (%changed2 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a29)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b01000000000000000000000000000000 != 0) {
     %dirty3 = %dirty3 or 0b0110
-  } else if (%changed3 and 0b1110 == 0) {
+  } else if (%changed3 and 0b0110 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a30)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty2 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty3 and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty2 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty3 and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = true\135.txt"
index 411b3cf..339eec7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test30Parameters\133useFir = true\135.txt"
@@ -87,160 +87,160 @@
   val %dirty3 = %changed3
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b00010000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000000000000000
-  } else if (%changed1 and 0b001110000000000000000000 == 0) {
+  } else if (%changed1 and 0b000110000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a16)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b00100000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000000000000000
-  } else if (%changed1 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed1 and 0b110000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a17)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b01000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000000000000000
-  } else if (%changed1 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a18)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b10000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000000000000000
-  } else if (%changed1 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a19)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b000100000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110
-  } else if (%changed2 and 0b1110 == 0) {
+  } else if (%changed2 and 0b0110 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a20)) 0b0100 else 0b0010
   }
   if (%default and 0b001000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000
-  } else if (%changed2 and 0b01110000 == 0) {
+  } else if (%changed2 and 0b00110000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a21)) 0b00100000 else 0b00010000
   }
   if (%default and 0b010000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000
-  } else if (%changed2 and 0b001110000000 == 0) {
+  } else if (%changed2 and 0b000110000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a22)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b100000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000
-  } else if (%changed2 and 0b0001110000000000 == 0) {
+  } else if (%changed2 and 0b110000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a23)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0001000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000
-  } else if (%changed2 and 0b1110000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a24)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b0010000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000
-  } else if (%changed2 and 0b01110000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a25)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b0100000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000000000000000
-  } else if (%changed2 and 0b001110000000000000000000 == 0) {
+  } else if (%changed2 and 0b000110000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a26)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b1000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000000000000000
-  } else if (%changed2 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed2 and 0b110000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a27)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b00010000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000000000000000
-  } else if (%changed2 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a28)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b00100000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000000000000000
-  } else if (%changed2 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a29)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b01000000000000000000000000000000 != 0) {
     %dirty3 = %dirty3 or 0b0110
-  } else if (%changed3 and 0b1110 == 0) {
+  } else if (%changed3 and 0b0110 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a30)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty2 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty3 and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty2 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty3 and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = false\135.txt"
index 09d27fa..481cf0d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = false\135.txt"
@@ -89,161 +89,161 @@
   val %dirty3 = %changed3
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
-  if (%changed and 0b01110000000000000000000000000000 == 0) {
+  if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%default and 0b001000000000 == 0 && %composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b00010000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000000000000000
-  } else if (%changed1 and 0b001110000000000000000000 == 0) {
+  } else if (%changed1 and 0b000110000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a16)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b00100000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000000000000000
-  } else if (%changed1 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed1 and 0b110000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a17)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b01000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000000000000000
-  } else if (%changed1 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a18)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b10000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000000000000000
-  } else if (%changed1 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a19)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b000100000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110
-  } else if (%changed2 and 0b1110 == 0) {
+  } else if (%changed2 and 0b0110 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a20)) 0b0100 else 0b0010
   }
   if (%default and 0b001000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000
-  } else if (%changed2 and 0b01110000 == 0) {
+  } else if (%changed2 and 0b00110000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a21)) 0b00100000 else 0b00010000
   }
   if (%default and 0b010000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000
-  } else if (%changed2 and 0b001110000000 == 0) {
+  } else if (%changed2 and 0b000110000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a22)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b100000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000
-  } else if (%changed2 and 0b0001110000000000 == 0) {
+  } else if (%changed2 and 0b110000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a23)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0001000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000
-  } else if (%changed2 and 0b1110000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a24)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b0010000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000
-  } else if (%changed2 and 0b01110000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a25)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b0100000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000000000000000
-  } else if (%changed2 and 0b001110000000000000000000 == 0) {
+  } else if (%changed2 and 0b000110000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a26)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b1000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000000000000000
-  } else if (%changed2 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed2 and 0b110000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a27)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b00010000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000000000000000
-  } else if (%changed2 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a28)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b00100000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000000000000000
-  } else if (%changed2 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a29)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b01000000000000000000000000000000 != 0) {
     %dirty3 = %dirty3 or 0b0110
-  } else if (%changed3 and 0b1110 == 0) {
+  } else if (%changed3 and 0b0110 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a30)) 0b0100 else 0b0010
   }
-  if (%changed3 and 0b01110000 == 0) {
+  if (%changed3 and 0b00110000 == 0) {
     %dirty3 = %dirty3 or if (%default1 and 0b0001 == 0 && %composer.changed(a31)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty2 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty3 and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty2 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty3 and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = true\135.txt"
index 09d27fa..481cf0d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31ParametersWithSomeUnstable\133useFir = true\135.txt"
@@ -89,161 +89,161 @@
   val %dirty3 = %changed3
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
-  if (%changed and 0b01110000000000000000000000000000 == 0) {
+  if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%default and 0b001000000000 == 0 && %composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b00010000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000000000000000
-  } else if (%changed1 and 0b001110000000000000000000 == 0) {
+  } else if (%changed1 and 0b000110000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a16)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b00100000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000000000000000
-  } else if (%changed1 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed1 and 0b110000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a17)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b01000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000000000000000
-  } else if (%changed1 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a18)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b10000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000000000000000
-  } else if (%changed1 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a19)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b000100000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110
-  } else if (%changed2 and 0b1110 == 0) {
+  } else if (%changed2 and 0b0110 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a20)) 0b0100 else 0b0010
   }
   if (%default and 0b001000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000
-  } else if (%changed2 and 0b01110000 == 0) {
+  } else if (%changed2 and 0b00110000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a21)) 0b00100000 else 0b00010000
   }
   if (%default and 0b010000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000
-  } else if (%changed2 and 0b001110000000 == 0) {
+  } else if (%changed2 and 0b000110000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a22)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b100000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000
-  } else if (%changed2 and 0b0001110000000000 == 0) {
+  } else if (%changed2 and 0b110000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a23)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0001000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000
-  } else if (%changed2 and 0b1110000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a24)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b0010000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000
-  } else if (%changed2 and 0b01110000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a25)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b0100000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000000000000000
-  } else if (%changed2 and 0b001110000000000000000000 == 0) {
+  } else if (%changed2 and 0b000110000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a26)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b1000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000000000000000
-  } else if (%changed2 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed2 and 0b110000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a27)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b00010000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000000000000000
-  } else if (%changed2 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a28)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b00100000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000000000000000
-  } else if (%changed2 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a29)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b01000000000000000000000000000000 != 0) {
     %dirty3 = %dirty3 or 0b0110
-  } else if (%changed3 and 0b1110 == 0) {
+  } else if (%changed3 and 0b0110 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a30)) 0b0100 else 0b0010
   }
-  if (%changed3 and 0b01110000 == 0) {
+  if (%changed3 and 0b00110000 == 0) {
     %dirty3 = %dirty3 or if (%default1 and 0b0001 == 0 && %composer.changed(a31)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty2 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty3 and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty2 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty3 and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = false\135.txt"
index a192882..b48332c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = false\135.txt"
@@ -89,165 +89,165 @@
   val %dirty3 = %changed3
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b00010000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000000000000000
-  } else if (%changed1 and 0b001110000000000000000000 == 0) {
+  } else if (%changed1 and 0b000110000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a16)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b00100000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000000000000000
-  } else if (%changed1 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed1 and 0b110000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a17)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b01000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000000000000000
-  } else if (%changed1 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a18)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b10000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000000000000000
-  } else if (%changed1 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a19)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b000100000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110
-  } else if (%changed2 and 0b1110 == 0) {
+  } else if (%changed2 and 0b0110 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a20)) 0b0100 else 0b0010
   }
   if (%default and 0b001000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000
-  } else if (%changed2 and 0b01110000 == 0) {
+  } else if (%changed2 and 0b00110000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a21)) 0b00100000 else 0b00010000
   }
   if (%default and 0b010000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000
-  } else if (%changed2 and 0b001110000000 == 0) {
+  } else if (%changed2 and 0b000110000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a22)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b100000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000
-  } else if (%changed2 and 0b0001110000000000 == 0) {
+  } else if (%changed2 and 0b110000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a23)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0001000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000
-  } else if (%changed2 and 0b1110000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a24)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b0010000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000
-  } else if (%changed2 and 0b01110000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a25)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b0100000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000000000000000
-  } else if (%changed2 and 0b001110000000000000000000 == 0) {
+  } else if (%changed2 and 0b000110000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a26)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b1000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000000000000000
-  } else if (%changed2 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed2 and 0b110000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a27)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b00010000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000000000000000
-  } else if (%changed2 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a28)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b00100000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000000000000000
-  } else if (%changed2 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a29)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b01000000000000000000000000000000 != 0) {
     %dirty3 = %dirty3 or 0b0110
-  } else if (%changed3 and 0b1110 == 0) {
+  } else if (%changed3 and 0b0110 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a30)) 0b0100 else 0b0010
   }
   if (%default1 and 0b0001 != 0) {
     %dirty3 = %dirty3 or 0b00110000
-  } else if (%changed3 and 0b01110000 == 0) {
+  } else if (%changed3 and 0b00110000 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a31)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty2 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty3 and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty2 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty3 and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = true\135.txt"
index a192882..b48332c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/test31Parameters\133useFir = true\135.txt"
@@ -89,165 +89,165 @@
   val %dirty3 = %changed3
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b00010000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000000000000000
-  } else if (%changed1 and 0b001110000000000000000000 == 0) {
+  } else if (%changed1 and 0b000110000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a16)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b00100000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000000000000000
-  } else if (%changed1 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed1 and 0b110000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a17)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b01000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000000000000000
-  } else if (%changed1 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a18)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b10000000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000000000000000
-  } else if (%changed1 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a19)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b000100000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110
-  } else if (%changed2 and 0b1110 == 0) {
+  } else if (%changed2 and 0b0110 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a20)) 0b0100 else 0b0010
   }
   if (%default and 0b001000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000
-  } else if (%changed2 and 0b01110000 == 0) {
+  } else if (%changed2 and 0b00110000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a21)) 0b00100000 else 0b00010000
   }
   if (%default and 0b010000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000
-  } else if (%changed2 and 0b001110000000 == 0) {
+  } else if (%changed2 and 0b000110000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a22)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b100000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000
-  } else if (%changed2 and 0b0001110000000000 == 0) {
+  } else if (%changed2 and 0b110000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a23)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0001000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000
-  } else if (%changed2 and 0b1110000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a24)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b0010000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000
-  } else if (%changed2 and 0b01110000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a25)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b0100000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b000110000000000000000000
-  } else if (%changed2 and 0b001110000000000000000000 == 0) {
+  } else if (%changed2 and 0b000110000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a26)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b1000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b110000000000000000000000
-  } else if (%changed2 and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed2 and 0b110000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a27)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b00010000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b0110000000000000000000000000
-  } else if (%changed2 and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b0110000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a28)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b00100000000000000000000000000000 != 0) {
     %dirty2 = %dirty2 or 0b00110000000000000000000000000000
-  } else if (%changed2 and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed2 and 0b00110000000000000000000000000000 == 0) {
     %dirty2 = %dirty2 or if (%composer.changed(a29)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b01000000000000000000000000000000 != 0) {
     %dirty3 = %dirty3 or 0b0110
-  } else if (%changed3 and 0b1110 == 0) {
+  } else if (%changed3 and 0b0110 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a30)) 0b0100 else 0b0010
   }
   if (%default1 and 0b0001 != 0) {
     %dirty3 = %dirty3 or 0b00110000
-  } else if (%changed3 and 0b01110000 == 0) {
+  } else if (%changed3 and 0b00110000 == 0) {
     %dirty3 = %dirty3 or if (%composer.changed(a31)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty2 and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty3 and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty2 and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty3 and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = false\135.txt"
index c44fe5e..51fd17f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = false\135.txt"
@@ -23,13 +23,13 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(b)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = true\135.txt"
index c44fe5e..51fd17f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testEarlierParameterReferences\133useFir = true\135.txt"
@@ -23,13 +23,13 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(b)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt"
index 33764ff..e2607bd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt"
@@ -26,10 +26,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(foo))) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       foo = Foo(0)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt"
index 33764ff..e2607bd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt"
@@ -26,10 +26,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(foo))) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       foo = Foo(0)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = false\135.txt"
index 07dd552..8195d4f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = false\135.txt"
@@ -20,10 +20,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = true\135.txt"
index 07dd552..8195d4f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.DefaultParamTransformTests/testNonStaticDefaultExpressions\133useFir = true\135.txt"
@@ -20,10 +20,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = false\135.txt"
index 605a789..0006e71 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = false\135.txt"
@@ -75,80 +75,80 @@
   val %dirty1 = %changed1
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b1011011011011011 != 0b0010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b0010010010010011 != 0b0010010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = true\135.txt"
index 605a789..0006e71 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test15Parameters\133useFir = true\135.txt"
@@ -75,80 +75,80 @@
   val %dirty1 = %changed1
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b1011011011011011 != 0b0010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b0010010010010011 != 0b0010010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = false\135.txt"
index a380a18..5b94981 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = false\135.txt"
@@ -78,85 +78,85 @@
   val %dirty1 = %changed1
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011 != 0b00010010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010011 != 0b00010010010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = true\135.txt"
index a380a18..5b94981 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test16Parameters\133useFir = true\135.txt"
@@ -78,85 +78,85 @@
   val %dirty1 = %changed1
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a00)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(a01)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a02)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a03)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a04)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a05)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a06)) 0b000100000000000000000000 else 0b10000000000000000000
   }
   if (%default and 0b10000000 != 0) {
     %dirty = %dirty or 0b110000000000000000000000
-  } else if (%changed and 0b0001110000000000000000000000 == 0) {
+  } else if (%changed and 0b110000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a07)) 0b100000000000000000000000 else 0b010000000000000000000000
   }
   if (%default and 0b000100000000 != 0) {
     %dirty = %dirty or 0b0110000000000000000000000000
-  } else if (%changed and 0b1110000000000000000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a08)) 0b0100000000000000000000000000 else 0b0010000000000000000000000000
   }
   if (%default and 0b001000000000 != 0) {
     %dirty = %dirty or 0b00110000000000000000000000000000
-  } else if (%changed and 0b01110000000000000000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(a09)) 0b00100000000000000000000000000000 else 0b00010000000000000000000000000000
   }
   if (%default and 0b010000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110
-  } else if (%changed1 and 0b1110 == 0) {
+  } else if (%changed1 and 0b0110 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a10)) 0b0100 else 0b0010
   }
   if (%default and 0b100000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000
-  } else if (%changed1 and 0b01110000 == 0) {
+  } else if (%changed1 and 0b00110000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a11)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0001000000000000 != 0) {
     %dirty1 = %dirty1 or 0b000110000000
-  } else if (%changed1 and 0b001110000000 == 0) {
+  } else if (%changed1 and 0b000110000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a12)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b0010000000000000 != 0) {
     %dirty1 = %dirty1 or 0b110000000000
-  } else if (%changed1 and 0b0001110000000000 == 0) {
+  } else if (%changed1 and 0b110000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a13)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b0100000000000000 != 0) {
     %dirty1 = %dirty1 or 0b0110000000000000
-  } else if (%changed1 and 0b1110000000000000 == 0) {
+  } else if (%changed1 and 0b0110000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a14)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b1000000000000000 != 0) {
     %dirty1 = %dirty1 or 0b00110000000000000000
-  } else if (%changed1 and 0b01110000000000000000 == 0) {
+  } else if (%changed1 and 0b00110000000000000000 == 0) {
     %dirty1 = %dirty1 or if (%composer.changed(a15)) 0b00100000000000000000 else 0b00010000000000000000
   }
-  if (%dirty and 0b01011011011011011011011011011011 != 0b00010010010010010010010010010010 || %dirty1 and 0b01011011011011011011 != 0b00010010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010010010010010011 != 0b00010010010010010010010010010010 || %dirty1 and 0b00010010010010010011 != 0b00010010010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       a00 = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = false\135.txt"
index 9f90663..8e181ee 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = false\135.txt"
@@ -37,7 +37,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = true\135.txt"
index 9f90663..8e181ee 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testAnnotationChecker\133useFir = true\135.txt"
@@ -37,7 +37,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = false\135.txt"
index 5223ae4..6103a7b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = false\135.txt"
@@ -28,10 +28,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(arrangement)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       arrangement = Arrangement.Top
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = true\135.txt"
index 5223ae4..6103a7b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrangement\133useFir = true\135.txt"
@@ -28,10 +28,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(arrangement)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       arrangement = Arrangement.Top
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = false\135.txt"
index 9ea5691..c246927 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = false\135.txt"
@@ -25,7 +25,7 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(state)) 0b0100 else 0b0010
   }
   %composer.startMovableGroup(<>, values.size)
@@ -38,7 +38,7 @@
   if (%dirty and 0b01110000 == 0) {
     %dirty = %dirty or 0b00010000
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0010 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = true\135.txt"
index 9ea5691..c246927 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testArrayDefaultArgWithState\133useFir = true\135.txt"
@@ -25,7 +25,7 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(state)) 0b0100 else 0b0010
   }
   %composer.startMovableGroup(<>, values.size)
@@ -38,7 +38,7 @@
   if (%dirty and 0b01110000 == 0) {
     %dirty = %dirty or 0b00010000
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0010 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = false\135.txt"
index 1bbe6b8..acc5437 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = false\135.txt"
@@ -33,20 +33,20 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(style)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(onTextLayout)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(overflow))) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+  if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       style = Companion.Default
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = true\135.txt"
index 1bbe6b8..acc5437 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testBasicText\133useFir = true\135.txt"
@@ -33,20 +33,20 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(style)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(onTextLayout)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(overflow))) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+  if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       style = Companion.Default
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = false\135.txt"
index c90f9f7..0898796 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = false\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<invoke...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = true\135.txt"
index c90f9f7..0898796 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaInvoke\133useFir = true\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<invoke...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = false\135.txt"
index 03b3be2..2ae1983 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = false\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(SomeThing)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -66,7 +66,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = true\135.txt"
index 03b3be2..2ae1983 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParamsAndReturnValue\133useFir = true\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(SomeThing)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -66,7 +66,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = false\135.txt"
index 278bc68..f81f400 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = false\135.txt"
@@ -21,13 +21,13 @@
   val lambda-1: Function4<Int, Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, y: Foo, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A(x)>,<B(y)>:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
     }
-    if (%changed and 0b01110000 == 0) {
+    if (%changed and 0b00110000 == 0) {
       %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
     }
-    if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+    if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = true\135.txt"
index 278bc68..f81f400 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithStableParams\133useFir = true\135.txt"
@@ -21,13 +21,13 @@
   val lambda-1: Function4<Int, Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, y: Foo, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A(x)>,<B(y)>:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
     }
-    if (%changed and 0b01110000 == 0) {
+    if (%changed and 0b00110000 == 0) {
       %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
     }
-    if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+    if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = false\135.txt"
index da112a1..ee286f7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = false\135.txt"
@@ -24,7 +24,7 @@
       traceEventStart(<>, %changed, -1, <>)
     }
     A(x, %composer, 0b1110 and %changed)
-    B(y, %composer, 0b1000)
+    B(y, %composer, 0b1110 and %changed shr 0b0011)
     if (isTraceInProgress()) {
       traceEventEnd()
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = true\135.txt"
index da112a1..ee286f7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdaWithUnstableParams\133useFir = true\135.txt"
@@ -24,7 +24,7 @@
       traceEventStart(<>, %changed, -1, <>)
     }
     A(x, %composer, 0b1110 and %changed)
-    B(y, %composer, 0b1000)
+    B(y, %composer, 0b1110 and %changed shr 0b0011)
     if (isTraceInProgress()) {
       traceEventEnd()
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = false\135.txt"
index 5cbf9070..6c194b3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = false\135.txt"
@@ -20,10 +20,10 @@
   val lambda-1: Function3<Int, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A(x)>:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = true\135.txt"
index 5cbf9070..6c194b3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambda\133useFir = true\135.txt"
@@ -20,10 +20,10 @@
   val lambda-1: Function3<Int, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<A(x)>:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = false\135.txt"
index 7466bdd..0aa0c97 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = false\135.txt"
@@ -25,18 +25,18 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(b)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+  if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = true\135.txt"
index 7466bdd..0aa0c97 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableParameter\133useFir = true\135.txt"
@@ -25,18 +25,18 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(b)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+  if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = false\135.txt"
index f636b43..255a38e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = false\135.txt"
@@ -26,10 +26,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       content = ComposableSingletons%TestKt.lambda-1
     }
@@ -50,7 +50,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = true\135.txt"
index f636b43..255a38e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableSingletonsAreStatic\133useFir = true\135.txt"
@@ -26,10 +26,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       content = ComposableSingletons%TestKt.lambda-1
     }
@@ -50,7 +50,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = false\135.txt"
index 2e23013..3279caf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = false\135.txt"
@@ -29,13 +29,13 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Wrap)P(1)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -57,15 +57,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       x = 0
     }
@@ -79,10 +79,10 @@
     Wrap(10, composableLambda(%composer, <>, true) { it: Int, %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<A(x)>:Test.kt")
       val %dirty = %changed
-      if (%changed and 0b1110 == 0) {
+      if (%changed and 0b0110 == 0) {
         %dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
       }
-      if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+      if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %dirty, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = true\135.txt"
index 78b2e9e..0974d96 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableWithAndWithoutDefaultParams\133useFir = true\135.txt"
@@ -29,13 +29,13 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Wrap)P(1)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -57,15 +57,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       x = 0
     }
@@ -79,10 +79,10 @@
     Wrap(10, composableLambda(%composer, <>, true) { it: @[ParameterName(name = 'x')] Int, %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<A(x)>:Test.kt")
       val %dirty = %changed
-      if (%changed and 0b1110 == 0) {
+      if (%changed and 0b0110 == 0) {
         %dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
       }
-      if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+      if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %dirty, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = false\135.txt"
index b39e593..dfcb401 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = false\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = true\135.txt"
index b39e593..dfcb401 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultSkipping\133useFir = true\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = false\135.txt"
index 8d2d815..14398557 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = false\135.txt"
@@ -33,20 +33,20 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(paddingStart))) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+  if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
@@ -75,7 +75,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = true\135.txt"
index 8d2d815..14398557 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDefaultsIssue\133useFir = true\135.txt"
@@ -33,20 +33,20 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(paddingStart))) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+  if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
@@ -75,7 +75,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = false\135.txt"
index cb7af836..a43bf78 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = false\135.txt"
@@ -30,10 +30,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<B(>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = true\135.txt"
index cb7af836..a43bf78 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testDifferentParameters\133useFir = true\135.txt"
@@ -30,10 +30,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<B(>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = false\135.txt"
index 2f12ff2..c56efc6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = false\135.txt"
@@ -25,13 +25,18 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(example):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(<this>)
+    } else {
+      %composer.changedInstance(<this>)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -52,13 +57,18 @@
   val lambda-1: @[ExtensionFunctionType] Function4<MaybeStable, Int, Composer, Int, Unit> = composableLambdaInstance(<>, false) { it: Int, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
-      %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+    if (%changed and 0b0110 == 0) {
+      %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+        %composer.changed(<this>)
+      } else {
+        %composer.changedInstance(<this>)
+      }
+      ) 0b0100 else 0b0010
     }
-    if (%changed and 0b01110000 == 0) {
+    if (%changed and 0b00110000 == 0) {
       %dirty = %dirty or if (%composer.changed(it)) 0b00100000 else 0b00010000
     }
-    if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+    if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = true\135.txt"
index 2f12ff2..c56efc6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testExtensionReceiver\133useFir = true\135.txt"
@@ -25,13 +25,18 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(example):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(<this>)
+    } else {
+      %composer.changedInstance(<this>)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -52,13 +57,18 @@
   val lambda-1: @[ExtensionFunctionType] Function4<MaybeStable, Int, Composer, Int, Unit> = composableLambdaInstance(<>, false) { it: Int, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
-      %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+    if (%changed and 0b0110 == 0) {
+      %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+        %composer.changed(<this>)
+      } else {
+        %composer.changedInstance(<this>)
+      }
+      ) 0b0100 else 0b0010
     }
-    if (%changed and 0b01110000 == 0) {
+    if (%changed and 0b00110000 == 0) {
       %dirty = %dirty or if (%composer.changed(it)) 0b00100000 else 0b00010000
     }
-    if (%dirty and 0b001011011011 != 0b10010010 || !%composer.skipping) {
+    if (%dirty and 0b10010011 != 0b10010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt"
index ee19210..fe95e6c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt"
@@ -31,10 +31,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Button)<getCol...>,<Text("...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(colors)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(colors)
+    } else {
+      %composer.changedInstance(colors)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt"
index ee19210..fe95e6c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt"
@@ -31,10 +31,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Button)<getCol...>,<Text("...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(colors)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(colors)
+    } else {
+      %composer.changedInstance(colors)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = false\135.txt"
index 55efab5..063a871 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = false\135.txt"
@@ -25,13 +25,13 @@
         %composer = %composer.startRestartGroup(<>)
         sourceInformation(%composer, "C(compute)<comput...>:Test.kt")
         val %dirty = %changed
-        if (%changed and 0b1110 == 0) {
+        if (%changed and 0b0110 == 0) {
           %dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
         }
-        if (%changed and 0b01110000 == 0) {
+        if (%changed and 0b00110000 == 0) {
           %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
         }
-        if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+        if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %dirty, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = true\135.txt"
index 55efab5..063a871 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces\133useFir = true\135.txt"
@@ -25,13 +25,13 @@
         %composer = %composer.startRestartGroup(<>)
         sourceInformation(%composer, "C(compute)<comput...>:Test.kt")
         val %dirty = %changed
-        if (%changed and 0b1110 == 0) {
+        if (%changed and 0b0110 == 0) {
           %dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
         }
-        if (%changed and 0b01110000 == 0) {
+        if (%changed and 0b00110000 == 0) {
           %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
         }
-        if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+        if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %dirty, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt"
index 2ab906d..0228cbe 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt"
@@ -30,15 +30,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       x = 0
     }
@@ -51,7 +51,7 @@
     used(y)
     Wrap(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt"
index 2ab906d..0228cbe 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt"
@@ -30,15 +30,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       x = 0
     }
@@ -51,7 +51,7 @@
     used(y)
     Wrap(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt"
index 3298250..a41f4c2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = false\135.txt"
@@ -27,10 +27,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<B(text...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -52,15 +52,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(color))) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0010 != 0) {
       color = Companion.Unset
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt"
index 3298250..a41f4c2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testInlineClassDefaultParameter\133useFir = true\135.txt"
@@ -27,10 +27,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<B(text...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -52,15 +52,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(<unsafe-coerce>(color))) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0010 != 0) {
       color = Companion.Unset
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = false\135.txt"
index 83c9a6c..bd9b924 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = false\135.txt"
@@ -23,7 +23,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: @[ExtensionFunctionType] Function5<LazyItemScope, Int, User?, Composer, Int, Unit> = composableLambdaInstance(<>, false) { index: Int, user: User?, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b0001010000000001 != 0b010000000000 || !%composer.skipping) {
+    if (%changed and 0b010000000001 != 0b010000000000 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = true\135.txt"
index 83c9a6c..bd9b924 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLambdaSkipping\133useFir = true\135.txt"
@@ -23,7 +23,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: @[ExtensionFunctionType] Function5<LazyItemScope, Int, User?, Composer, Int, Unit> = composableLambdaInstance(<>, false) { index: Int, user: User?, %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b0001010000000001 != 0b010000000000 || !%composer.skipping) {
+    if (%changed and 0b010000000001 != 0b010000000000 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = false\135.txt"
index bbd5212..e72a3c57 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = false\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<Inner(...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = true\135.txt"
index bbd5212..e72a3c57 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalComposableFunctions\133useFir = true\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Example)<Inner(...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = false\135.txt"
index 74a928e..7ef5d06 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = false\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<foo(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = true\135.txt"
index 74a928e..7ef5d06 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLocalFunction\133useFir = true\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<foo(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = false\135.txt"
index ed3c95a..06d6558 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = false\135.txt"
@@ -23,26 +23,28 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%default and 0b1000 == 0 && %composer.changed(d)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
-    %dirty = %dirty or 0b0010000000000000
+    %dirty = %dirty or 0b0110000000000000
+  } else if (%changed and 0b0110000000000000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(e)) 0b0100000000000000 else 0b0010000000000000
   }
-  if (%default and 0b00010000 != 0b00010000 || %dirty and 0b1011011011011011 != 0b0010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b0010010010010011 != 0b0010010010010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0100 != 0) {
@@ -65,7 +67,7 @@
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
-    A(a, b, c, d, e, %composer, 0b1000000000000000 or 0b1110 and %dirty or 0b01110000 and %dirty or 0b001110000000 and %dirty or 0b0001110000000000 and %dirty)
+    A(a, b, c, d, e, %composer, 0b1110 and %dirty or 0b01110000 and %dirty or 0b001110000000 and %dirty or 0b0001110000000000 and %dirty or 0b1110000000000000 and %dirty)
     if (isTraceInProgress()) {
       traceEventEnd()
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = true\135.txt"
index ed3c95a..06d6558 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testManyNonOptionalParams\133useFir = true\135.txt"
@@ -23,26 +23,28 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
   }
-  if (%changed and 0b0001110000000000 == 0) {
+  if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%default and 0b1000 == 0 && %composer.changed(d)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
-    %dirty = %dirty or 0b0010000000000000
+    %dirty = %dirty or 0b0110000000000000
+  } else if (%changed and 0b0110000000000000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(e)) 0b0100000000000000 else 0b0010000000000000
   }
-  if (%default and 0b00010000 != 0b00010000 || %dirty and 0b1011011011011011 != 0b0010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b0010010010010011 != 0b0010010010010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0100 != 0) {
@@ -65,7 +67,7 @@
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
-    A(a, b, c, d, e, %composer, 0b1000000000000000 or 0b1110 and %dirty or 0b01110000 and %dirty or 0b001110000000 and %dirty or 0b0001110000000000 and %dirty)
+    A(a, b, c, d, e, %composer, 0b1110 and %dirty or 0b01110000 and %dirty or 0b001110000000 and %dirty or 0b0001110000000000 and %dirty or 0b1110000000000000 and %dirty)
     if (isTraceInProgress()) {
       traceEventEnd()
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = false\135.txt"
index 2a745d94..7aa096c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = false\135.txt"
@@ -27,30 +27,30 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<Provid...>,<B(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
     Provide(composableLambda(%composer, <>, true) { y: Int, %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<Provid...>,<B(x,>:Test.kt")
       val %dirty = %changed
-      if (%changed and 0b1110 == 0) {
+      if (%changed and 0b0110 == 0) {
         %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
       }
-      if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+      if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %dirty, -1, <>)
         }
         Provide(composableLambda(%composer, <>, true) { z: Int, %composer: Composer?, %changed: Int ->
           sourceInformation(%composer, "C<B(x,>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(z)) 0b0100 else 0b0010
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = true\135.txt"
index 2a745d94..7aa096c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testNestedCalls\133useFir = true\135.txt"
@@ -27,30 +27,30 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(A)<Provid...>,<B(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
     Provide(composableLambda(%composer, <>, true) { y: Int, %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<Provid...>,<B(x,>:Test.kt")
       val %dirty = %changed
-      if (%changed and 0b1110 == 0) {
+      if (%changed and 0b0110 == 0) {
         %dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
       }
-      if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+      if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %dirty, -1, <>)
         }
         Provide(composableLambda(%composer, <>, true) { z: Int, %composer: Composer?, %changed: Int ->
           sourceInformation(%composer, "C<B(x,>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(z)) 0b0100 else 0b0010
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = false\135.txt"
index a13798a..eb4ee5d4 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = false\135.txt"
@@ -20,7 +20,7 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(CanSkip):Test.kt")
   val %dirty = %changed
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b0001 != 0 || !%composer.skipping) {
+  if (%dirty and 0b0001 != 0 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = true\135.txt"
index a13798a..eb4ee5d4 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testOptionalUnstableWithStableExtensionReceiver\133useFir = true\135.txt"
@@ -20,7 +20,7 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(CanSkip):Test.kt")
   val %dirty = %changed
-  if (%default and 0b0001 != 0b0001 || %dirty and 0b0001 != 0 || !%composer.skipping) {
+  if (%dirty and 0b0001 != 0 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = false\135.txt"
index afb7f4a..46a7e0a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = false\135.txt"
@@ -20,13 +20,13 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(y>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = true\135.txt"
index afb7f4a..46a7e0a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testParamReordering\133useFir = true\135.txt"
@@ -20,13 +20,13 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(y>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(y)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = false\135.txt"
index 3c659c1..38244a2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = false\135.txt"
@@ -22,10 +22,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<doSome...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(<this>)
+    } else {
+      %composer.changedInstance(<this>)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = true\135.txt"
index 3c659c1..38244a2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPassedExtensionWhenExtensionIsPotentiallyUnstable\133useFir = true\135.txt"
@@ -22,10 +22,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<doSome...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(<this>)
+    } else {
+      %composer.changedInstance(<this>)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = false\135.txt"
index 98e5aca..15297a1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = false\135.txt"
@@ -31,7 +31,7 @@
   if (%dirty and 0b1110 == 0) {
     %dirty = %dirty or 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = true\135.txt"
index 98e5aca..15297a1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testPrimitiveVarargParams\133useFir = true\135.txt"
@@ -31,7 +31,7 @@
   if (%dirty and 0b1110 == 0) {
     %dirty = %dirty or 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = false\135.txt"
index b3df740..95819ba 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b01010001 != 0b00010000 || !%composer.skipping) {
+    if (%changed and 0b00010001 != 0b00010000 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
@@ -44,10 +44,15 @@
   val lambda-2: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
-      %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+    if (%changed and 0b0110 == 0) {
+      %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+        %composer.changed(<this>)
+      } else {
+        %composer.changedInstance(<this>)
+      }
+      ) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
@@ -61,7 +66,7 @@
   }
   val lambda-3: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b01010001 != 0b00010000 || !%composer.skipping) {
+    if (%changed and 0b00010001 != 0b00010000 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
@@ -76,10 +81,10 @@
   val lambda-4: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = true\135.txt"
index b976185..15262c5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverLambdaCall\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b01010001 != 0b00010000 || !%composer.skipping) {
+    if (%changed and 0b00010001 != 0b00010000 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
@@ -44,10 +44,15 @@
   val lambda-2: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
-      %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
+    if (%changed and 0b0110 == 0) {
+      %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+        %composer.changed(<this>)
+      } else {
+        %composer.changedInstance(<this>)
+      }
+      ) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
@@ -61,7 +66,7 @@
   }
   val lambda-3: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b01010001 != 0b00010000 || !%composer.skipping) {
+    if (%changed and 0b00010001 != 0b00010000 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
@@ -76,10 +81,10 @@
   val lambda-4: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
     val %dirty = %changed
-    if (%changed and 0b1110 == 0) {
+    if (%changed and 0b0110 == 0) {
       %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
     }
-    if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+    if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %dirty, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = false\135.txt"
index e694ebe..03cba4a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = false\135.txt"
@@ -48,12 +48,20 @@
   fun B(%composer: Composer?, %changed: Int) {
     %composer = %composer.startRestartGroup(<>)
     sourceInformation(%composer, "C(B):Test.kt")
-    if (isTraceInProgress()) {
-      traceEventStart(<>, %changed, -1, <>)
+    val %dirty = %changed
+    if (%changed and 0b0110 == 0) {
+      %dirty = %dirty or if (%composer.changedInstance(<this>)) 0b0100 else 0b0010
     }
-    print(counter)
-    if (isTraceInProgress()) {
-      traceEventEnd()
+    if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+      if (isTraceInProgress()) {
+        traceEventStart(<>, %dirty, -1, <>)
+      }
+      print(counter)
+      if (isTraceInProgress()) {
+        traceEventEnd()
+      }
+    } else {
+      %composer.skipToGroupEnd()
     }
     val tmp0_rcvr = <this>
     %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = true\135.txt"
index e694ebe..03cba4a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testReceiverParamSkippability\133useFir = true\135.txt"
@@ -48,12 +48,20 @@
   fun B(%composer: Composer?, %changed: Int) {
     %composer = %composer.startRestartGroup(<>)
     sourceInformation(%composer, "C(B):Test.kt")
-    if (isTraceInProgress()) {
-      traceEventStart(<>, %changed, -1, <>)
+    val %dirty = %changed
+    if (%changed and 0b0110 == 0) {
+      %dirty = %dirty or if (%composer.changedInstance(<this>)) 0b0100 else 0b0010
     }
-    print(counter)
-    if (isTraceInProgress()) {
-      traceEventEnd()
+    if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+      if (isTraceInProgress()) {
+        traceEventStart(<>, %dirty, -1, <>)
+      }
+      print(counter)
+      if (isTraceInProgress()) {
+        traceEventEnd()
+      }
+    } else {
+      %composer.skipToGroupEnd()
     }
     val tmp0_rcvr = <this>
     %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = false\135.txt"
index 0ace20a..344bef7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = false\135.txt"
@@ -22,10 +22,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(X)<X(x>,<X(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = true\135.txt"
index 0ace20a..344bef7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testRecursiveCall\133useFir = true\135.txt"
@@ -22,10 +22,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(X)<X(x>,<X(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt"
index faf99be..f3a5067 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<B()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(cond)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt"
index faf99be..f3a5067 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt"
@@ -26,10 +26,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<B()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(cond)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = false\135.txt"
index fbef31c..9a13342 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = false\135.txt"
@@ -24,13 +24,18 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
-    %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(shape)) 0b00100000 else 0b00010000
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%default and 0b0010 == 0 && if (%changed and 0b01000000 == 0) {
+      %composer.changed(shape)
+    } else {
+      %composer.changedInstance(shape)
+    }
+    ) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = true\135.txt"
index fbef31c..9a13342 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBoxWithShape\133useFir = true\135.txt"
@@ -24,13 +24,18 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
-    %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(shape)) 0b00100000 else 0b00010000
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%default and 0b0010 == 0 && if (%changed and 0b01000000 == 0) {
+      %composer.changed(shape)
+    } else {
+      %composer.changedInstance(shape)
+    }
+    ) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = false\135.txt"
index ccb90fe..3e5c831 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = false\135.txt"
@@ -25,15 +25,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
@@ -58,7 +58,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = true\135.txt"
index ccb90fe..3e5c831 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleBox\133useFir = true\135.txt"
@@ -25,15 +25,15 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
@@ -58,7 +58,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = false\135.txt"
index d3c3c8f..cc6c52cd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = false\135.txt"
@@ -53,35 +53,35 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(orientation)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(arrangement)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(crossAxisAlignment)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(crossAxisSize)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b00100000000000000000 else 0b00010000000000000000
   }
-  if (%dirty and 0b01011011011011011011 != 0b00010010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010011 != 0b00010010010010010010 || !%composer.skipping) {
     if (%default and 0b0010 != 0) {
       modifier = Companion
     }
@@ -121,25 +121,25 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(verticalArrangement)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(horizontalGravity)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = true\135.txt"
index d3c3c8f..cc6c52cd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimpleColumn\133useFir = true\135.txt"
@@ -53,35 +53,35 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(orientation)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(arrangement)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(crossAxisAlignment)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changed(crossAxisSize)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b00100000000000000000 else 0b00010000000000000000
   }
-  if (%dirty and 0b01011011011011011011 != 0b00010010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b00010010010010010011 != 0b00010010010010010010 || !%composer.skipping) {
     if (%default and 0b0010 != 0) {
       modifier = Companion
     }
@@ -121,25 +121,25 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(verticalArrangement)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changed(horizontalGravity)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b100000000000 else 0b010000000000
   }
-  if (%dirty and 0b0001011011011011 != 0b010010010010 || !%composer.skipping) {
+  if (%dirty and 0b010010010011 != 0b010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = false\135.txt"
index 547c1b3..cd25cfa 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = false\135.txt"
@@ -23,10 +23,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = true\135.txt"
index 547c1b3..cd25cfa 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSimplerBox\133useFir = true\135.txt"
@@ -23,10 +23,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(modifier)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       modifier = Companion
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = false\135.txt"
index a42e379..c61ff5e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = false\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<I()>,<A(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = true\135.txt"
index a42e379..c61ff5e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithComposableDefault\133useFir = true\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<I()>,<A(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = false\135.txt"
index 48bdb7c..555c042 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = false\135.txt"
@@ -23,10 +23,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       x = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = true\135.txt"
index 48bdb7c..555c042 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParamWithDefault\133useFir = true\135.txt"
@@ -23,10 +23,10 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       x = 0
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = false\135.txt"
index b65366d..c15af6f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = false\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = true\135.txt"
index b65366d..c15af6f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleStableParam\133useFir = true\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = false\135.txt"
index b3491d9..6688118 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = false\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = true\135.txt"
index b3491d9..6688118 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParamWithDefault\133useFir = true\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%default and 0b0001 == 0 && %composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = false\135.txt"
index 388b7bd..c9f2060 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = false\135.txt"
@@ -20,12 +20,20 @@
 fun Test(x: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  A(x, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    A(x, %composer, 0b1110 and %dirty)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Test(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = true\135.txt"
index 388b7bd..c9f2060 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSingleUnstableParam\133useFir = true\135.txt"
@@ -20,12 +20,20 @@
 fun Test(x: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  A(x, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    A(x, %composer, 0b1110 and %dirty)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Test(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = false\135.txt"
index 78dec06..1d2fbd0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = false\135.txt"
@@ -31,13 +31,13 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%default and 0b0010 != 0) {
-    %dirty = %dirty or 0b00010000
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changedInstance(b)) 0b00100000 else 0b00010000
   }
-  if (%default and 0b0010 != 0b0010 || %dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
@@ -73,14 +73,25 @@
 fun CannotSkip(a: Int, b: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(CannotSkip):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  used(a)
-  used(b)
-  print("Hello World")
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(b)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(a)
+    used(b)
+    print("Hello World")
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     CannotSkip(a, b, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = true\135.txt"
index 78dec06..1d2fbd0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableUnstableParams\133useFir = true\135.txt"
@@ -31,13 +31,13 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  if (%default and 0b0010 != 0) {
-    %dirty = %dirty or 0b00010000
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changedInstance(b)) 0b00100000 else 0b00010000
   }
-  if (%default and 0b0010 != 0b0010 || %dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
@@ -73,14 +73,25 @@
 fun CannotSkip(a: Int, b: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(CannotSkip):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
   }
-  used(a)
-  used(b)
-  print("Hello World")
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(b)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(a)
+    used(b)
+    print("Hello World")
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     CannotSkip(a, b, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = false\135.txt"
index 01b138d..cebf20b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = false\135.txt"
@@ -31,7 +31,7 @@
   if (%dirty and 0b1110 == 0) {
     %dirty = %dirty or 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = true\135.txt"
index 01b138d..cebf20b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStableVarargParams\133useFir = true\135.txt"
@@ -31,7 +31,7 @@
   if (%dirty and 0b1110 == 0) {
     %dirty = %dirty or 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = false\135.txt"
index 99abdd3..22214e3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = false\135.txt"
@@ -27,13 +27,13 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(wontChange)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(mightChange)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = true\135.txt"
index 99abdd3..22214e3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticAndNonStaticDefaultValueSkipping\133useFir = true\135.txt"
@@ -27,13 +27,13 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(wontChange)) 0b0100 else 0b0010
   }
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%default and 0b0010 == 0 && %composer.changed(mightChange)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+  if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
     %composer.startDefaults()
     if (%changed and 0b0001 == 0 || %composer.defaultsInvalid) {
       if (%default and 0b0001 != 0) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = false\135.txt"
index e10b4f6..ff725cf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = false\135.txt"
@@ -96,7 +96,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = true\135.txt"
index 45d6ce8..6203ee4 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testStaticDetection\133useFir = true\135.txt"
@@ -96,7 +96,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = false\135.txt"
index e6e15a0..f2c01be 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = false\135.txt"
@@ -20,12 +20,27 @@
 fun B(values: Array<out Foo>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  %composer.startMovableGroup(<>, values.size)
+  val <iterator> = values.iterator()
+  while (<iterator>.hasNext()) {
+    val value = <iterator>.next()
+    %dirty = %dirty or if (%composer.changedInstance(value)) 0b0100 else 0
   }
-  print(values)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  %composer.endMovableGroup()
+  if (%dirty and 0b1110 == 0) {
+    %dirty = %dirty or 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    print(values)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     B(*values, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = true\135.txt"
index e6e15a0..f2c01be 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnstableVarargParams\133useFir = true\135.txt"
@@ -20,12 +20,27 @@
 fun B(values: Array<out Foo>, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(B):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  %composer.startMovableGroup(<>, values.size)
+  val <iterator> = values.iterator()
+  while (<iterator>.hasNext()) {
+    val value = <iterator>.next()
+    %dirty = %dirty or if (%composer.changedInstance(value)) 0b0100 else 0
   }
-  print(values)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  %composer.endMovableGroup()
+  if (%dirty and 0b1110 == 0) {
+    %dirty = %dirty or 0b0010
+  }
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    print(values)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     B(*values, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = false\135.txt"
index 19d681c..7ffa866 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = false\135.txt"
@@ -30,12 +30,20 @@
 fun Unskippable(a: Unstable, b: Stable, c: MaybeStable, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Unskippable):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(a)) 0b0100 else 0b0010
   }
-  used(a)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(a)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Unskippable(a, b, c, %composer, updateChangedFlags(%changed or 0b0001))
@@ -46,10 +54,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Skippable1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01010001 != 0b00010000 || !%composer.skipping) {
+  if (%dirty and 0b00010001 != 0b00010000 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -69,10 +77,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Skippable2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b001110000000 == 0) {
-    %dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
+  if (%changed and 0b000110000000 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b001000000000 == 0) {
+      %composer.changed(c)
+    } else {
+      %composer.changedInstance(c)
+    }
+    ) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001010000001 != 0b10000000 || !%composer.skipping) {
+  if (%dirty and 0b10000001 != 0b10000000 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = true\135.txt"
index 19d681c..7ffa866 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testUnusedParameters\133useFir = true\135.txt"
@@ -30,12 +30,20 @@
 fun Unskippable(a: Unstable, b: Stable, c: MaybeStable, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Unskippable):Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(a)) 0b0100 else 0b0010
   }
-  used(a)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    used(a)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Unskippable(a, b, c, %composer, updateChangedFlags(%changed or 0b0001))
@@ -46,10 +54,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Skippable1):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b01110000 == 0) {
+  if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
   }
-  if (%dirty and 0b01010001 != 0b00010000 || !%composer.skipping) {
+  if (%dirty and 0b00010001 != 0b00010000 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -69,10 +77,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Skippable2):Test.kt")
   val %dirty = %changed
-  if (%changed and 0b001110000000 == 0) {
-    %dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
+  if (%changed and 0b000110000000 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b001000000000 == 0) {
+      %composer.changed(c)
+    } else {
+      %composer.changedInstance(c)
+    }
+    ) 0b000100000000 else 0b10000000
   }
-  if (%dirty and 0b001010000001 != 0b10000000 || !%composer.skipping) {
+  if (%dirty and 0b10000001 != 0b10000000 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = false\135.txt"
index 00194e8..b7b5ab6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = false\135.txt"
@@ -29,10 +29,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<{>,<Exampl...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(int)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = true\135.txt"
index 00194e8..b7b5ab6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testCaptureStableFunInterface\133useFir = true\135.txt"
@@ -29,10 +29,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<{>,<Exampl...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(int)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = false\135.txt"
index 93c9361..3a187b8 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = false\135.txt"
@@ -39,10 +39,10 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(invoke):Test.kt")
           val %dirty = %changed
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01010001 != 0b00010000 || !%composer.skipping) {
+          if (%dirty and 0b00010001 != 0b00010000 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = true\135.txt"
index 93c9361..3a187b8 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWAnonymousParam\133useFir = true\135.txt"
@@ -39,10 +39,10 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(invoke):Test.kt")
           val %dirty = %changed
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01010001 != 0b00010000 || !%composer.skipping) {
+          if (%dirty and 0b00010001 != 0b00010000 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = false\135.txt"
index df9eca5..24b5aeb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = false\135.txt"
@@ -33,10 +33,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decorated)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(boolean)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -49,13 +49,13 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(Decoration)<conten...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
           }
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
@@ -91,10 +91,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decoratable)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(decorator)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(decorator)
+    } else {
+      %composer.changedInstance(decorator)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -116,7 +121,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = true\135.txt"
index df9eca5..24b5aeb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambdaCaptureVariable\133useFir = true\135.txt"
@@ -33,10 +33,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decorated)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(boolean)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -49,13 +49,13 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(Decoration)<conten...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
           }
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
@@ -91,10 +91,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decoratable)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(decorator)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(decorator)
+    } else {
+      %composer.changedInstance(decorator)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -116,7 +121,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = false\135.txt"
index 7e07bc9..d06f6a8 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = false\135.txt"
@@ -32,10 +32,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decorated)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(boolean)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -47,13 +47,13 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(Decoration)<conten...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
           }
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
@@ -89,10 +89,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decoratable)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(decorator)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(decorator)
+    } else {
+      %composer.changedInstance(decorator)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -114,7 +119,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = true\135.txt"
index 7e07bc9..d06f6a8 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaceWComposableLambda\133useFir = true\135.txt"
@@ -32,10 +32,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decorated)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(boolean)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -47,13 +47,13 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(Decoration)<conten...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
           }
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
@@ -89,10 +89,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Decoratable)<Decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(decorator)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(decorator)
+    } else {
+      %composer.changedInstance(decorator)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -114,7 +119,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = false\135.txt"
index febf9aa..c09d665 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = false\135.txt"
@@ -39,13 +39,13 @@
         %composer = %composer.startRestartGroup(<>)
         sourceInformation(%composer, "C(consume):Test.kt")
         val %dirty = %changed
-        if (%changed and 0b1110 == 0) {
+        if (%changed and 0b0110 == 0) {
           %dirty = %dirty or if (%composer.changed(string)) 0b0100 else 0b0010
         }
-        if (%changed and 0b01110000 == 0) {
+        if (%changed and 0b00110000 == 0) {
           %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
         }
-        if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+        if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %dirty, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = true\135.txt"
index febf9aa..c09d665 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfacesInVariance\133useFir = true\135.txt"
@@ -39,13 +39,13 @@
         %composer = %composer.startRestartGroup(<>)
         sourceInformation(%composer, "C(consume):Test.kt")
         val %dirty = %changed
-        if (%changed and 0b1110 == 0) {
+        if (%changed and 0b0110 == 0) {
           %dirty = %dirty or if (%composer.changed(string)) 0b0100 else 0b0010
         }
-        if (%changed and 0b01110000 == 0) {
+        if (%changed and 0b00110000 == 0) {
           %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
         }
-        if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+        if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %dirty, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = false\135.txt"
index 8469e9b..7e68cab 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = false\135.txt"
@@ -27,13 +27,13 @@
         %composer = %composer.startRestartGroup(<>)
         sourceInformation(%composer, "C(compute)<comput...>:Test.kt")
         val %dirty = %changed
-        if (%changed and 0b1110 == 0) {
+        if (%changed and 0b0110 == 0) {
           %dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
         }
-        if (%changed and 0b01110000 == 0) {
+        if (%changed and 0b00110000 == 0) {
           %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
         }
-        if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+        if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %dirty, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = true\135.txt"
index 8469e9b..7e68cab 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testComposableFunInterfaces\133useFir = true\135.txt"
@@ -27,13 +27,13 @@
         %composer = %composer.startRestartGroup(<>)
         sourceInformation(%composer, "C(compute)<comput...>:Test.kt")
         val %dirty = %changed
-        if (%changed and 0b1110 == 0) {
+        if (%changed and 0b0110 == 0) {
           %dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
         }
-        if (%changed and 0b01110000 == 0) {
+        if (%changed and 0b00110000 == 0) {
           %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
         }
-        if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+        if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %dirty, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = false\135.txt"
index f2ffbbf..5b73ea0c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = false\135.txt"
@@ -23,17 +23,30 @@
 @Composable
 fun Example(a: A, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
-  sourceInformation(%composer, "C(Example)<Exampl...>:Test.kt")
+  sourceInformation(%composer, "C(Example)<{>,<Exampl...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(a)
+    } else {
+      %composer.changedInstance(a)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
-    Example(A { it: Int ->
-      a.compute(it)
+    Example(<block>{
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100 || %dirty and 0b1000 != 0 && %composer.changedInstance(a)) {
+        A { it: Int ->
+          a.compute(it)
+        }
+      }
+      %composer.endReplaceableGroup()
+      tmp0_group
     }, %composer, 0)
     if (isTraceInProgress()) {
       traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = true\135.txt"
index f2ffbbf..5b73ea0c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunInterfaces\133useFir = true\135.txt"
@@ -23,17 +23,30 @@
 @Composable
 fun Example(a: A, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
-  sourceInformation(%composer, "C(Example)<Exampl...>:Test.kt")
+  sourceInformation(%composer, "C(Example)<{>,<Exampl...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(a)
+    } else {
+      %composer.changedInstance(a)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
-    Example(A { it: Int ->
-      a.compute(it)
+    Example(<block>{
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100 || %dirty and 0b1000 != 0 && %composer.changedInstance(a)) {
+        A { it: Int ->
+          a.compute(it)
+        }
+      }
+      %composer.endReplaceableGroup()
+      tmp0_group
     }, %composer, 0)
     if (isTraceInProgress()) {
       traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = false\135.txt"
index 61c3960..e744151 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = false\135.txt"
@@ -33,10 +33,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)*<Conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(content)
+    } else {
+      %composer.changedInstance(content)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -68,13 +73,13 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(Content):Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(%this%Test)) 0b0100 else 0b0010
           }
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = true\135.txt"
index 61c3960..e744151 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionalInterfaceTransformTests/testFunctionalInterfaceWithExtensionReceiverTransformation\133useFir = true\135.txt"
@@ -33,10 +33,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)*<Conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(content)
+    } else {
+      %composer.changedInstance(content)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -68,13 +73,13 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(Content):Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(%this%Test)) 0b0100 else 0b0010
           }
-          if (%changed and 0b01110000 == 0) {
+          if (%changed and 0b00110000 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b00100000 else 0b00010000
           }
-          if (%dirty and 0b01011011 != 0b00010010 || !%composer.skipping) {
+          if (%dirty and 0b00010011 != 0b00010010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = false\135.txt"
index e5d7343..2829255 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = false\135.txt"
@@ -15,7 +15,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = true\135.txt"
index e5d7343..2829255 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testJvmNameComposableSingletons\133useFir = true\135.txt"
@@ -15,7 +15,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = false\135.txt"
index 779bc05..a12ab70 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = false\135.txt"
@@ -26,7 +26,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = true\135.txt"
index 779bc05..a12ab70 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass2\133useFir = true\135.txt"
@@ -26,7 +26,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = false\135.txt"
index a7b7cb1..e77c91b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = false\135.txt"
@@ -20,7 +20,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = true\135.txt"
index a7b7cb1..e77c91b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationRegressionTests/testNestedComposableSingletonsClass\133useFir = true\135.txt"
@@ -20,7 +20,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testAdaptedFunctionRef\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testAdaptedFunctionRef\133useFir = false\135.txt"
new file mode 100644
index 0000000..5785249
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testAdaptedFunctionRef\133useFir = false\135.txt"
@@ -0,0 +1,149 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.Composable
+
+class ScrollState {
+    fun test(index: Int, default: Int = 0): Int = 0
+    fun testExact(index: Int): Int = 0
+}
+fun scrollState(): ScrollState = TODO()
+
+@Composable fun rememberFooInline() = fooInline(scrollState()::test)
+@Composable fun rememberFoo() = foo(scrollState()::test)
+@Composable fun rememberFooExactInline() = fooInline(scrollState()::testExact)
+@Composable fun rememberFooExact() = foo(scrollState()::testExact)
+
+@Composable
+inline fun fooInline(block: (Int) -> Int) = block(0)
+
+@Composable
+fun foo(block: (Int) -> Int) = block(0)
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@StabilityInferred(parameters = 1)
+class ScrollState {
+  fun test(index: Int, default: Int = 0): Int {
+    return 0
+  }
+  fun testExact(index: Int): Int {
+    return 0
+  }
+  static val %stable: Int = 0
+}
+fun scrollState(): ScrollState {
+  return TODO()
+}
+@Composable
+fun rememberFooInline(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFooInline)<fooInl...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = fooInline(<block>{
+    fun ScrollState.test(p0: Int): Int {
+      val tmp0_return = receiver.test(
+        index = p0
+      )
+      tmp0_return
+    }
+    scrollState()::test
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun rememberFoo(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFoo)<scroll...>,<foo(sc...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = foo(<block>{
+    val tmp0 = scrollState()
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+    val tmp1_group = %composer.cache(%composer.changed(tmp0)) {
+      fun ScrollState.test(p0: Int): Int {
+        receiver.test(
+          index = p0
+        )
+      }
+      tmp0::test
+    }
+    %composer.endReplaceableGroup()
+    tmp1_group
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun rememberFooExactInline(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFooExactInline)<fooInl...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = fooInline(scrollState()::testExact, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun rememberFooExact(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFooExact)<scroll...>,<foo(sc...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = foo(<block>{
+    val tmp0 = scrollState()
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+    val tmp1_group = %composer.cache(%composer.changed(tmp0)) {
+      tmp0::testExact
+    }
+    %composer.endReplaceableGroup()
+    tmp1_group
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun fooInline(block: Function1<Int, Int>, %composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "CC(fooInline):Test.kt")
+  val tmp0 = block(0)
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun foo(block: Function1<Int, Int>, %composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(foo):Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = block(0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testAdaptedFunctionRef\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testAdaptedFunctionRef\133useFir = true\135.txt"
new file mode 100644
index 0000000..ab1b9ff
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testAdaptedFunctionRef\133useFir = true\135.txt"
@@ -0,0 +1,149 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.Composable
+
+class ScrollState {
+    fun test(index: Int, default: Int = 0): Int = 0
+    fun testExact(index: Int): Int = 0
+}
+fun scrollState(): ScrollState = TODO()
+
+@Composable fun rememberFooInline() = fooInline(scrollState()::test)
+@Composable fun rememberFoo() = foo(scrollState()::test)
+@Composable fun rememberFooExactInline() = fooInline(scrollState()::testExact)
+@Composable fun rememberFooExact() = foo(scrollState()::testExact)
+
+@Composable
+inline fun fooInline(block: (Int) -> Int) = block(0)
+
+@Composable
+fun foo(block: (Int) -> Int) = block(0)
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@StabilityInferred(parameters = 1)
+class ScrollState {
+  fun test(index: Int, default: Int = 0): Int {
+    return 0
+  }
+  fun testExact(index: Int): Int {
+    return 0
+  }
+  static val %stable: Int = 0
+}
+fun scrollState(): ScrollState {
+  return TODO()
+}
+@Composable
+fun rememberFooInline(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFooInline)<fooInl...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = fooInline(<block>{
+    fun ScrollState.test(p0: Int): Int {
+      val tmp0_return = receiver.test(
+        index = p0
+      )
+      tmp0_return
+    }
+    scrollState()::test
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun rememberFoo(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFoo)<test>,<foo(sc...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = foo(<block>{
+    val tmp0 = scrollState()
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+    val tmp1_group = %composer.cache(%composer.changed(tmp0)) {
+      fun ScrollState.test(p0: Int): Int {
+        receiver.test(
+          index = p0
+        )
+      }
+      tmp0::test
+    }
+    %composer.endReplaceableGroup()
+    tmp1_group
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun rememberFooExactInline(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFooExactInline)<fooInl...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = fooInline(scrollState()::testExact, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun rememberFooExact(%composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(rememberFooExact)<testEx...>,<foo(sc...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = foo(<block>{
+    val tmp0 = scrollState()
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+    val tmp1_group = %composer.cache(%composer.changed(tmp0)) {
+      tmp0::testExact
+    }
+    %composer.endReplaceableGroup()
+    tmp1_group
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun fooInline(block: Function1<Int, Int>, %composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "CC(fooInline):Test.kt")
+  val tmp0 = block(0)
+  %composer.endReplaceableGroup()
+  return tmp0
+}
+@Composable
+fun foo(block: Function1<Int, Int>, %composer: Composer?, %changed: Int): Int {
+  %composer.startReplaceableGroup(<>)
+  sourceInformation(%composer, "C(foo):Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  val tmp0 = block(0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endReplaceableGroup()
+  return tmp0
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWStableCapture\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWStableCapture\133useFir = false\135.txt"
new file mode 100644
index 0000000..f4fb2cc
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWStableCapture\133useFir = false\135.txt"
@@ -0,0 +1,49 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable fun Test(param: String, unstable: List<*>) {
+    Wrapper {
+        println(param)
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+fun Test(param: String, unstable: List<*>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(Test)<{>,<Wrappe...>:Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b1110 == 0) {
+    %dirty = %dirty or if (%composer.changed(param)) 0b0100 else 0b0010
+  }
+  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    Wrapper(<block>{
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100) {
+        {
+          println(param)
+        }
+      }
+      %composer.endReplaceableGroup()
+      tmp0_group
+    }, %composer, 0)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    Test(param, unstable, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWStableCapture\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWStableCapture\133useFir = true\135.txt"
new file mode 100644
index 0000000..f4fb2cc
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWStableCapture\133useFir = true\135.txt"
@@ -0,0 +1,49 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable fun Test(param: String, unstable: List<*>) {
+    Wrapper {
+        println(param)
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+fun Test(param: String, unstable: List<*>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(Test)<{>,<Wrappe...>:Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b1110 == 0) {
+    %dirty = %dirty or if (%composer.changed(param)) 0b0100 else 0b0010
+  }
+  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    Wrapper(<block>{
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100) {
+        {
+          println(param)
+        }
+      }
+      %composer.endReplaceableGroup()
+      tmp0_group
+    }, %composer, 0)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    Test(param, unstable, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWUnstableCapture\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWUnstableCapture\133useFir = false\135.txt"
new file mode 100644
index 0000000..aa030ee
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWUnstableCapture\133useFir = false\135.txt"
@@ -0,0 +1,33 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable fun Test(param: String, unstable: List<*>) {
+    Wrapper {
+        println(unstable)
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+fun Test(param: String, unstable: List<*>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(Test)<Wrappe...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  Wrapper({
+    println(unstable)
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    Test(param, unstable, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWUnstableCapture\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWUnstableCapture\133useFir = true\135.txt"
new file mode 100644
index 0000000..aa030ee
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testMemoizationWUnstableCapture\133useFir = true\135.txt"
@@ -0,0 +1,33 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable fun Test(param: String, unstable: List<*>) {
+    Wrapper {
+        println(unstable)
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+fun Test(param: String, unstable: List<*>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(Test)<Wrappe...>:Test.kt")
+  if (isTraceInProgress()) {
+    traceEventStart(<>, %changed, -1, <>)
+  }
+  Wrapper({
+    println(unstable)
+  }, %composer, 0)
+  if (isTraceInProgress()) {
+    traceEventEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    Test(param, unstable, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = false\135.txt"
index 05ba6c9..e276214 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = false\135.txt"
@@ -30,9 +30,12 @@
     used(<block>{
       %composer.startReplaceableGroup(<>)
       sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
-      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100) {
-        effect()
-      }
+      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100, <block>{
+        fun effect(): Int {
+          effect()
+        }
+        ::effect
+      })
       %composer.endReplaceableGroup()
       tmp0_group
     })
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = true\135.txt"
index 05ba6c9..e276214 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberAdaptedFunctionReference\133useFir = true\135.txt"
@@ -30,9 +30,12 @@
     used(<block>{
       %composer.startReplaceableGroup(<>)
       sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
-      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100) {
-        effect()
-      }
+      val tmp0_group = %composer.cache(%dirty and 0b1110 == 0b0100, <block>{
+        fun effect(): Int {
+          effect()
+        }
+        ::effect
+      })
       %composer.endReplaceableGroup()
       tmp0_group
     })
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTestsStrongSkipping/testRememberWithUnstableParam\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTestsStrongSkipping/testRememberWithUnstableParam\133useFir = false\135.txt"
new file mode 100644
index 0000000..9cc440b
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTestsStrongSkipping/testRememberWithUnstableParam\133useFir = false\135.txt"
@@ -0,0 +1,45 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable fun Test(param: String, unstable: List<*>) {
+    remember(unstable) {
+        unstable[0]
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+fun Test(param: String, unstable: List<*>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(Test)<rememb...>:Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(unstable)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010001 != 0b00010000 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+    val tmp0_group = %composer.cache(%composer.changed(unstable)) {
+      unstable[0]
+    }
+    %composer.endReplaceableGroup()
+    tmp0_group
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    Test(param, unstable, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTestsStrongSkipping/testRememberWithUnstableParam\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTestsStrongSkipping/testRememberWithUnstableParam\133useFir = true\135.txt"
new file mode 100644
index 0000000..9cc440b
--- /dev/null
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTestsStrongSkipping/testRememberWithUnstableParam\133useFir = true\135.txt"
@@ -0,0 +1,45 @@
+//
+// Source
+// ------------------------------------------
+
+import androidx.compose.runtime.*
+
+@Composable fun Test(param: String, unstable: List<*>) {
+    remember(unstable) {
+        unstable[0]
+    }
+}
+
+//
+// Transformed IR
+// ------------------------------------------
+
+@Composable
+fun Test(param: String, unstable: List<*>, %composer: Composer?, %changed: Int) {
+  %composer = %composer.startRestartGroup(<>)
+  sourceInformation(%composer, "C(Test)<rememb...>:Test.kt")
+  val %dirty = %changed
+  if (%changed and 0b00110000 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(unstable)) 0b00100000 else 0b00010000
+  }
+  if (%dirty and 0b00010001 != 0b00010000 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
+    }
+    %composer.startReplaceableGroup(<>)
+    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+    val tmp0_group = %composer.cache(%composer.changed(unstable)) {
+      unstable[0]
+    }
+    %composer.endReplaceableGroup()
+    tmp0_group
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
+  }
+  %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+    Test(param, unstable, %composer, updateChangedFlags(%changed or 0b0001))
+  }
+}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = false\135.txt"
index 1b894a8..9210ddc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = false\135.txt"
@@ -23,10 +23,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = true\135.txt"
index 1b894a8..9210ddc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownStable\133useFir = true\135.txt"
@@ -23,10 +23,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = false\135.txt"
index 6248fde..b89201a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = false\135.txt"
@@ -22,22 +22,30 @@
 fun Test(x: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  A(x, %composer, 0b1000)
-  A(Foo(0), %composer, 0b1000)
-  A(<block>{
-    %composer.startReplaceableGroup(<>)
-    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
-    val tmp0_group = %composer.cache(false) {
-      Foo(0)
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
     }
-    %composer.endReplaceableGroup()
-    tmp0_group
-  }, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+    A(x, %composer, 0b1110 and %dirty)
+    A(Foo(0), %composer, 0)
+    A(<block>{
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+      val tmp0_group = %composer.cache(false) {
+        Foo(0)
+      }
+      %composer.endReplaceableGroup()
+      tmp0_group
+    }, %composer, 0)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Test(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = true\135.txt"
index 6248fde..b89201a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.StabilityPropagationTransformTests/testPassingLocalKnownUnstable\133useFir = true\135.txt"
@@ -22,22 +22,30 @@
 fun Test(x: Foo, %composer: Composer?, %changed: Int) {
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
-  if (isTraceInProgress()) {
-    traceEventStart(<>, %changed, -1, <>)
+  val %dirty = %changed
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (%composer.changedInstance(x)) 0b0100 else 0b0010
   }
-  A(x, %composer, 0b1000)
-  A(Foo(0), %composer, 0b1000)
-  A(<block>{
-    %composer.startReplaceableGroup(<>)
-    sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
-    val tmp0_group = %composer.cache(false) {
-      Foo(0)
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
+    if (isTraceInProgress()) {
+      traceEventStart(<>, %dirty, -1, <>)
     }
-    %composer.endReplaceableGroup()
-    tmp0_group
-  }, %composer, 0b1000)
-  if (isTraceInProgress()) {
-    traceEventEnd()
+    A(x, %composer, 0b1110 and %dirty)
+    A(Foo(0), %composer, 0)
+    A(<block>{
+      %composer.startReplaceableGroup(<>)
+      sourceInformation(%composer, "CC(remember):Test.kt#9igjgp")
+      val tmp0_group = %composer.cache(false) {
+        Foo(0)
+      }
+      %composer.endReplaceableGroup()
+      tmp0_group
+    }, %composer, 0)
+    if (isTraceInProgress()) {
+      traceEventEnd()
+    }
+  } else {
+    %composer.skipToGroupEnd()
   }
   %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
     Test(x, %composer, updateChangedFlags(%changed or 0b0001))
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = false\135.txt"
index 69f6169..d0b840e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = false\135.txt"
@@ -22,7 +22,7 @@
     list.add(1) { it: Int ->
       composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
         sourceInformation(%composer, "C<conten...>:Test.kt")
-        if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+        if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %changed, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = true\135.txt"
index 69f6169..d0b840e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testAddingComposablesToAList\133useFir = true\135.txt"
@@ -22,7 +22,7 @@
     list.add(1) { it: Int ->
       composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
         sourceInformation(%composer, "C<conten...>:Test.kt")
-        if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+        if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
           if (isTraceInProgress()) {
             traceEventStart(<>, %changed, -1, <>)
           }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = false\135.txt"
index 2bf471c..3b0bf91 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = false\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(decorator)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -42,7 +42,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = true\135.txt"
index 2bf471c..3b0bf91 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingComposableParameterWithComposableParameter\133useFir = true\135.txt"
@@ -21,10 +21,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<decora...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(decorator)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -42,7 +42,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = false\135.txt"
index ba5d12b..c35f40b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = false\135.txt"
@@ -85,10 +85,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test2)<Layout...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -156,16 +156,16 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test5)<Compos...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
     CompositionLocalProvider(Local provides 5, composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<Test1(...>,<conten...>:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
@@ -194,16 +194,16 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test6)<Compos...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(test)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
     CompositionLocalProvider(Local provides 6, composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<T(test...>,<Test1(...>:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = true\135.txt"
index ba5d12b..c35f40b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCallingLayout\133useFir = true\135.txt"
@@ -85,10 +85,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test2)<Layout...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -156,16 +156,16 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test5)<Compos...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
     CompositionLocalProvider(Local provides 5, composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<Test1(...>,<conten...>:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
@@ -194,16 +194,16 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test6)<Compos...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(test)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
     CompositionLocalProvider(Local provides 6, composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C<T(test...>,<Test1(...>:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = false\135.txt"
index f6fd18e..ab2b4cf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = false\135.txt"
@@ -38,7 +38,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = true\135.txt"
index f6fd18e..ab2b4cf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCanInferWithGeneric\133useFir = true\135.txt"
@@ -38,7 +38,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = false\135.txt"
index 7da5ff3..5f20df0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = false\135.txt"
@@ -28,7 +28,7 @@
     CompositionLocalProvider(
       content = ComposableSingletons%TestKt.lambda-1,
       %composer = %composer,
-      %changed = 56
+      %changed = 48
     )
     if (isTraceInProgress()) {
       traceEventEnd()
@@ -43,7 +43,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = true\135.txt"
index 7da5ff3..5f20df0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testCompositionLocalsProvider\133useFir = true\135.txt"
@@ -28,7 +28,7 @@
     CompositionLocalProvider(
       content = ComposableSingletons%TestKt.lambda-1,
       %composer = %composer,
-      %changed = 56
+      %changed = 48
     )
     if (isTraceInProgress()) {
       traceEventEnd()
@@ -43,7 +43,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = false\135.txt"
index 944f0fb..1c17d14 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = false\135.txt"
@@ -38,7 +38,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = true\135.txt"
index 944f0fb..1c17d14 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferLambdaParameter\133useFir = true\135.txt"
@@ -38,7 +38,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Text("...>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = false\135.txt"
index f848dfe..a5da811 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = false\135.txt"
@@ -19,10 +19,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = true\135.txt"
index f848dfe..a5da811 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferUnifiedParameters\133useFir = true\135.txt"
@@ -19,10 +19,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = false\135.txt"
index 2303321..e7bba70 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = false\135.txt"
@@ -44,10 +44,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(OpenCustom)<call()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(content)
+    } else {
+      %composer.changedInstance(content)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -68,10 +73,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(ClosedCustom)<Text("...>,<call()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(content)
+    } else {
+      %composer.changedInstance(content)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -104,10 +114,10 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(call)<Text("...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
           }
-          if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+          if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
@@ -134,10 +144,10 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(call)<Text("...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
           }
-          if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+          if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = true\135.txt"
index 2303321..e7bba70 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testInferringFunInterfaceParameterAnnotations\133useFir = true\135.txt"
@@ -44,10 +44,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(OpenCustom)<call()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(content)
+    } else {
+      %composer.changedInstance(content)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -68,10 +73,15 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(ClosedCustom)<Text("...>,<call()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
-    %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+  if (%changed and 0b0110 == 0) {
+    %dirty = %dirty or if (if (%changed and 0b1000 == 0) {
+      %composer.changed(content)
+    } else {
+      %composer.changedInstance(content)
+    }
+    ) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -104,10 +114,10 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(call)<Text("...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
           }
-          if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+          if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
@@ -134,10 +144,10 @@
           %composer = %composer.startRestartGroup(<>)
           sourceInformation(%composer, "C(call)<Text("...>:Test.kt")
           val %dirty = %changed
-          if (%changed and 0b1110 == 0) {
+          if (%changed and 0b0110 == 0) {
             %dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
           }
-          if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+          if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %dirty, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = false\135.txt"
index 704fe0d..639daab 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = false\135.txt"
@@ -19,10 +19,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)*<it()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = true\135.txt"
index 704fe0d..639daab 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testLetIt\133useFir = true\135.txt"
@@ -19,10 +19,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)*<it()>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt"
index e58ce9e..3b7e3a1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt"
@@ -78,10 +78,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Wrapper)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -104,40 +104,40 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(one)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(two)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(three)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(four)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(five)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(six)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b000100000000000000000000 else 0b10000000000000000000
   }
-  if (%dirty and 0b001011011011011011011011 != 0b10010010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b10010010010010010011 != 0b10010010010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       one = ComposableSingletons%TestKt.lambda-1
     }
@@ -246,7 +246,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
@@ -260,7 +260,7 @@
   }
   val lambda-2: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Leaf()>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt"
index e58ce9e..3b7e3a1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt"
@@ -78,10 +78,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Wrapper)<conten...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -104,40 +104,40 @@
   val %dirty = %changed
   if (%default and 0b0001 != 0) {
     %dirty = %dirty or 0b0110
-  } else if (%changed and 0b1110 == 0) {
+  } else if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(one)) 0b0100 else 0b0010
   }
   if (%default and 0b0010 != 0) {
     %dirty = %dirty or 0b00110000
-  } else if (%changed and 0b01110000 == 0) {
+  } else if (%changed and 0b00110000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(two)) 0b00100000 else 0b00010000
   }
   if (%default and 0b0100 != 0) {
     %dirty = %dirty or 0b000110000000
-  } else if (%changed and 0b001110000000 == 0) {
+  } else if (%changed and 0b000110000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(three)) 0b000100000000 else 0b10000000
   }
   if (%default and 0b1000 != 0) {
     %dirty = %dirty or 0b110000000000
-  } else if (%changed and 0b0001110000000000 == 0) {
+  } else if (%changed and 0b110000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(four)) 0b100000000000 else 0b010000000000
   }
   if (%default and 0b00010000 != 0) {
     %dirty = %dirty or 0b0110000000000000
-  } else if (%changed and 0b1110000000000000 == 0) {
+  } else if (%changed and 0b0110000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(five)) 0b0100000000000000 else 0b0010000000000000
   }
   if (%default and 0b00100000 != 0) {
     %dirty = %dirty or 0b00110000000000000000
-  } else if (%changed and 0b01110000000000000000 == 0) {
+  } else if (%changed and 0b00110000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(six)) 0b00100000000000000000 else 0b00010000000000000000
   }
   if (%default and 0b01000000 != 0) {
     %dirty = %dirty or 0b000110000000000000000000
-  } else if (%changed and 0b001110000000000000000000 == 0) {
+  } else if (%changed and 0b000110000000000000000000 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b000100000000000000000000 else 0b10000000000000000000
   }
-  if (%dirty and 0b001011011011011011011011 != 0b10010010010010010010 || !%composer.skipping) {
+  if (%dirty and 0b10010010010010010011 != 0b10010010010010010010 || !%composer.skipping) {
     if (%default and 0b0001 != 0) {
       one = ComposableSingletons%TestKt.lambda-1
     }
@@ -246,7 +246,7 @@
 internal object ComposableSingletons%TestKt {
   val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
@@ -260,7 +260,7 @@
   }
   val lambda-2: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
     sourceInformation(%composer, "C<Leaf()>:Test.kt")
-    if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+    if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
       if (isTraceInProgress()) {
         traceEventStart(<>, %changed, -1, <>)
       }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = false\135.txt"
index ce41a8f..7dff6aa 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = false\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<rememb...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -39,13 +39,13 @@
     }
     Defer(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
         UiContent(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
           sourceInformation(%composer, "C<update...>:Test.kt")
-          if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+          if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %changed, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = true\135.txt"
index ce41a8f..7dff6aa 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testRememberUpdatedState\133useFir = true\135.txt"
@@ -24,10 +24,10 @@
   %composer = %composer.startRestartGroup(<>)
   sourceInformation(%composer, "C(Test)<rememb...>:Test.kt")
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changedInstance(content)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
@@ -39,13 +39,13 @@
     }
     Defer(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
       sourceInformation(%composer, "C:Test.kt")
-      if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+      if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
         if (isTraceInProgress()) {
           traceEventStart(<>, %changed, -1, <>)
         }
         UiContent(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
           sourceInformation(%composer, "C<update...>:Test.kt")
-          if (%changed and 0b1011 != 0b0010 || !%composer.skipping) {
+          if (%changed and 0b0011 != 0b0010 || !%composer.skipping) {
             if (isTraceInProgress()) {
               traceEventStart(<>, %changed, -1, <>)
             }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt"
index c217496..6fba851 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt"
@@ -36,10 +36,10 @@
   sourceInformation(%composer, "C(Test)<A()>,<Wrappe...>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt"
index c217496..6fba851 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt"
@@ -36,10 +36,10 @@
   sourceInformation(%composer, "C(Test)<A()>,<Wrappe...>,<A()>:Test.kt")
   val tmp0_marker = %composer.currentMarker
   val %dirty = %changed
-  if (%changed and 0b1110 == 0) {
+  if (%changed and 0b0110 == 0) {
     %dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
   }
-  if (%dirty and 0b1011 != 0b0010 || !%composer.skipping) {
+  if (%dirty and 0b0011 != 0b0010 || !%composer.skipping) {
     if (isTraceInProgress()) {
       traceEventStart(<>, %dirty, -1, <>)
     }
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
index df1ebf9..db3c96d 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
@@ -266,7 +266,7 @@
     companion object {
         fun checkCompilerVersion(configuration: CompilerConfiguration): Boolean {
             try {
-                val KOTLIN_VERSION_EXPECTATION = "1.9.20"
+                val KOTLIN_VERSION_EXPECTATION = "1.9.21"
                 KotlinCompilerVersion.getVersion()?.let { version ->
                     val msgCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
                     val suppressKotlinVersionCheck = configuration.get(
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
index 569b3da..9e42502 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
@@ -142,7 +142,7 @@
          * The maven version string of this compiler. This string should be updated before/after every
          * release.
          */
-        const val compilerVersion: String = "1.5.5"
+        const val compilerVersion: String = "1.5.6"
         private val minimumRuntimeVersion: String
             get() = runtimeVersionToMavenVersionTable[minimumRuntimeVersionInt] ?: "unknown"
     }
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/k2/ComposableCallChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/k2/ComposableCallChecker.kt
index 46a822b..4465723 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/k2/ComposableCallChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/k2/ComposableCallChecker.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.compiler.plugins.kotlin.k2
 
+import org.jetbrains.kotlin.KtSourceElement
 import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
 import org.jetbrains.kotlin.diagnostics.reportOn
 import org.jetbrains.kotlin.fir.FirElement
@@ -41,12 +42,16 @@
 import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
 import org.jetbrains.kotlin.fir.expressions.FirTryExpression
 import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
+import org.jetbrains.kotlin.fir.psi
 import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
 import org.jetbrains.kotlin.fir.references.toResolvedValueParameterSymbol
 import org.jetbrains.kotlin.fir.resolve.isInvoke
 import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
 import org.jetbrains.kotlin.fir.types.coneType
 import org.jetbrains.kotlin.fir.types.functionTypeKind
+import org.jetbrains.kotlin.psi.KtFunction
+import org.jetbrains.kotlin.psi.KtFunctionLiteral
+import org.jetbrains.kotlin.psi.KtLambdaExpression
 
 object ComposablePropertyAccessExpressionChecker : FirPropertyAccessExpressionChecker() {
     override fun check(
@@ -119,49 +124,44 @@
         visitAnonymousFunction = { function ->
             if (function.typeRef.coneType.functionTypeKind(context.session) === ComposableFunction)
                 return
+            val functionPsi = function.psi
+            if (functionPsi is KtFunctionLiteral || functionPsi is KtLambdaExpression ||
+                functionPsi !is KtFunction
+            ) {
+                return@visitCurrentScope
+            }
+            val nonReadOnlyCalleeReference =
+                if (!calleeFunction.isReadOnlyComposable(context.session)) {
+                    expression.calleeReference.source
+                } else {
+                    null
+                }
+            if (checkComposableFunction(
+                    function,
+                    nonReadOnlyCalleeReference,
+                    context,
+                    reporter,
+                ) == ComposableCheckForScopeStatus.STOP
+            ) {
+                return
+            }
         },
         visitFunction = { function ->
-            if (function.hasComposableAnnotation(context.session)) {
-                if (
-                    function.hasReadOnlyComposableAnnotation(context.session) &&
-                    !calleeFunction.isReadOnlyComposable(context.session)
-                ) {
-                    reporter.reportOn(
-                        expression.calleeReference.source,
-                        ComposeErrors.NONREADONLY_CALL_IN_READONLY_COMPOSABLE,
-                        context
-                    )
+            val nonReadOnlyCalleeReference =
+                if (!calleeFunction.isReadOnlyComposable(context.session)) {
+                    expression.calleeReference.source
+                } else {
+                    null
                 }
+            if (checkComposableFunction(
+                    function,
+                    nonReadOnlyCalleeReference,
+                    context,
+                    reporter,
+                ) == ComposableCheckForScopeStatus.STOP
+            ) {
                 return
             }
-            // We allow composable calls in local delegated properties.
-            // The only call this could be is a getValue/setValue in the synthesized getter/setter.
-            if (function is FirPropertyAccessor && function.propertySymbol.hasDelegate) {
-                if (function.propertySymbol.isVar) {
-                    reporter.reportOn(
-                        function.source,
-                        ComposeErrors.COMPOSE_INVALID_DELEGATE,
-                        context
-                    )
-                }
-                // Only local variables can be implicitly composable, for top-level or class-level
-                // declarations we require an explicit annotation.
-                if (!function.propertySymbol.isLocal) {
-                    reporter.reportOn(
-                        function.propertySymbol.source,
-                        ComposeErrors.COMPOSABLE_EXPECTED,
-                        context
-                    )
-                }
-                return
-            }
-            // We've found a non-composable function which contains a composable call.
-            val source = if (function is FirPropertyAccessor) {
-                function.propertySymbol.source
-            } else {
-                function.source
-            }
-            reporter.reportOn(source, ComposeErrors.COMPOSABLE_EXPECTED, context)
         },
         visitTryExpression = { tryExpression, container ->
             // Only report an error if the composable call happens inside of the `try`
@@ -182,6 +182,69 @@
     )
 }
 
+private enum class ComposableCheckForScopeStatus {
+    STOP,
+    CONTINUE,
+}
+
+/**
+ * This function will be called by [visitCurrentScope], and this function determines
+ * whether it will continue the composable element check for the scope or not
+ * by returning [ComposableCheckForScopeStatus].
+ */
+private fun checkComposableFunction(
+    function: FirFunction,
+    nonReadOnlyCallInsideFunction: KtSourceElement?,
+    context: CheckerContext,
+    reporter: DiagnosticReporter,
+): ComposableCheckForScopeStatus {
+    // [function] is a function with "read-only" composable annotation, but it has a call
+    // without "read-only" composable annotation.
+    // -> report NONREADONLY_CALL_IN_READONLY_COMPOSABLE.
+    if (function.hasComposableAnnotation(context.session)) {
+        if (
+            function.hasReadOnlyComposableAnnotation(context.session) &&
+            nonReadOnlyCallInsideFunction != null
+        ) {
+            reporter.reportOn(
+                nonReadOnlyCallInsideFunction,
+                ComposeErrors.NONREADONLY_CALL_IN_READONLY_COMPOSABLE,
+                context
+            )
+        }
+        return ComposableCheckForScopeStatus.STOP
+    }
+    // We allow composable calls in local delegated properties.
+    // The only call this could be is a getValue/setValue in the synthesized getter/setter.
+    if (function is FirPropertyAccessor && function.propertySymbol.hasDelegate) {
+        if (function.propertySymbol.isVar) {
+            reporter.reportOn(
+                function.source,
+                ComposeErrors.COMPOSE_INVALID_DELEGATE,
+                context
+            )
+        }
+        // Only local variables can be implicitly composable, for top-level or class-level
+        // declarations we require an explicit annotation.
+        if (!function.propertySymbol.isLocal) {
+            reporter.reportOn(
+                function.propertySymbol.source,
+                ComposeErrors.COMPOSABLE_EXPECTED,
+                context
+            )
+        }
+        return ComposableCheckForScopeStatus.STOP
+    }
+    // We've found a non-composable function which contains a composable call.
+    val source = if (function is FirPropertyAccessor) {
+        function.propertySymbol.source
+    } else {
+        function.source
+    }
+    reporter.reportOn(source, ComposeErrors.COMPOSABLE_EXPECTED, context)
+    return ComposableCheckForScopeStatus.CONTINUE
+}
+
 /**
  * Reports an error if we are invoking a lambda parameter of an inline function in a context
  * where composable calls are not allowed, unless the lambda parameter is itself annotated
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt
index f7a2f24..117e9f7 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt
@@ -1204,7 +1204,7 @@
         currentComposer: IrExpression,
         value: IrExpression,
         inferredStable: Boolean,
-        strongSkippingEnabled: Boolean
+        compareInstanceForUnstableValues: Boolean
     ): IrExpression {
         // compose has a unique opportunity to avoid inline class boxing for changed calls, since
         // we know that the only thing that we are detecting here is "changed or not", we can
@@ -1222,7 +1222,7 @@
         val primitiveDescriptor = type.toPrimitiveType()
             .let { changedPrimitiveFunctions[it] }
 
-        return if (!strongSkippingEnabled) {
+        return if (!compareInstanceForUnstableValues) {
             val descriptor = primitiveDescriptor
                 ?: if (type.isFunction()) changedInstanceFunction else changedFunction
             irMethodCall(currentComposer, descriptor).also {
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
index c18ad5c..9f7db48 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
@@ -983,7 +983,7 @@
             }
         }
 
-        scope.applyIntrinsicRememberFixups { args, metas ->
+        scope.applyIntrinsicRememberFixups { isMemoizedLambda, args, metas ->
             // replace dirty with changed param in meta used for inference, as we are not
             // populating dirty
             if (!canSkipExecution) {
@@ -993,7 +993,7 @@
                     }
                 }
             }
-            irIntrinsicRememberInvalid(args, metas, ::irInferredChanged)
+            irIntrinsicRememberInvalid(isMemoizedLambda, args, metas, ::irInferredChanged)
         }
 
         if (canSkipExecution) {
@@ -1149,7 +1149,7 @@
             dirty
         } else changedParam
 
-        scope.applyIntrinsicRememberFixups { args, metas ->
+        scope.applyIntrinsicRememberFixups { isMemoizedLambda, args, metas ->
             // replace dirty with changed param in meta used for inference, as we are not
             // populating dirty
             if (!canSkipExecution) {
@@ -1159,7 +1159,7 @@
                     }
                 }
             }
-            irIntrinsicRememberInvalid(args, metas, ::irInferredChanged)
+            irIntrinsicRememberInvalid(isMemoizedLambda, args, metas, ::irInferredChanged)
         }
 
         val transformedBody = if (canSkipExecution) {
@@ -1636,13 +1636,13 @@
                 irCurrentComposer(),
                 irGet(param),
                 inferredStable = true,
-                strongSkippingEnabled = true
+                compareInstanceForUnstableValues = true
             ),
             elsePart = irChanged(
                 irCurrentComposer(),
                 irGet(param),
                 inferredStable = false,
-                strongSkippingEnabled = true
+                compareInstanceForUnstableValues = true
             )
         )
     } else {
@@ -2119,11 +2119,14 @@
         return irMethodCall(scope.irCurrentComposer(), endRestartGroupFunction)
     }
 
-    private fun irChanged(value: IrExpression): IrExpression = irChanged(
+    private fun irChanged(
+        value: IrExpression,
+        compareInstanceForUnstableValues: Boolean = strongSkippingEnabled
+    ): IrExpression = irChanged(
         irCurrentComposer(),
         value,
         inferredStable = false,
-        strongSkippingEnabled = strongSkippingEnabled
+        compareInstanceForUnstableValues = compareInstanceForUnstableValues
     )
 
     private fun irSkipToGroupEnd(startOffset: Int, endOffset: Int): IrExpression {
@@ -2778,6 +2781,9 @@
                     expression.transformChildrenVoid()
                 }
                 return if (captureScope.hasCapturedComposableCall) {
+                    // if the inlined lambda has composable calls, realize its coalescable groups
+                    // in the body to ensure that repeated invocations are not colliding.
+                    captureScope.realizeAllDirectChildren()
                     expression.asCoalescableGroup(captureScope)
                 } else {
                     expression
@@ -2806,7 +2812,7 @@
                     visitNormalComposableCall(expression)
                 }
             }
-            ComposeFqNames.key -> visitKeyCall(expression)
+            ComposeFqNames.key,
             DecoyFqNames.key -> visitKeyCall(expression)
             else -> visitNormalComposableCall(expression)
         }
@@ -3033,18 +3039,25 @@
         }
         val usesDirty = inputArgMetas.any { it.maskParam is IrChangedBitMaskVariable }
 
+        val isMemoizedLambda = expression.origin == ComposeMemoizedLambdaOrigin
+
         // We can only rely on the $changed or $dirty if the flags are correctly updated in
         // the restart function or the result of replacing remember with cached will be
         // different.
         val metaMaskConsistent = updateChangedFlagsFunction != null
-        val changedFunction: (IrExpression, ParamMeta) -> IrExpression? =
+        val changedFunction: (Boolean, IrExpression, ParamMeta) -> IrExpression? =
             if (usesDirty || !metaMaskConsistent) {
-                { arg, _ -> irChanged(arg) }
+                { _, arg, _ -> irChanged(arg, compareInstanceForUnstableValues = isMemoizedLambda) }
             } else {
                 ::irInferredChanged
             }
 
-        val invalidExpr = irIntrinsicRememberInvalid(inputArgs, inputArgMetas, changedFunction)
+        val invalidExpr = irIntrinsicRememberInvalid(
+            isMemoizedLambda,
+            inputArgs,
+            inputArgMetas,
+            changedFunction
+        )
         val functionScope = currentFunctionScope
         val cacheCall = irCache(
             irCurrentComposer(),
@@ -3056,6 +3069,7 @@
         )
         if (usesDirty && metaMaskConsistent) {
             functionScope.recordIntrinsicRememberFixUp(
+                isMemoizedLambda,
                 inputArgs,
                 inputArgMetas,
                 cacheCall
@@ -3103,16 +3117,21 @@
     }
 
     private fun irIntrinsicRememberInvalid(
+        isMemoizedLambda: Boolean,
         args: List<IrExpression>,
         metas: List<ParamMeta>,
-        changedExpr: (IrExpression, ParamMeta) -> IrExpression?
+        changedExpr: (Boolean, IrExpression, ParamMeta) -> IrExpression?
     ): IrExpression =
         args
-            .mapIndexedNotNull { i, arg -> changedExpr(arg, metas[i]) }
+            .mapIndexedNotNull { i, arg -> changedExpr(isMemoizedLambda, arg, metas[i]) }
             .reduceOrNull { acc, changed -> irBooleanOr(acc, changed) }
             ?: irConst(false)
 
-    private fun irInferredChanged(arg: IrExpression, meta: ParamMeta): IrExpression? {
+    private fun irInferredChanged(
+        isMemoizedLambda: Boolean,
+        arg: IrExpression,
+        meta: ParamMeta
+    ): IrExpression? {
         val param = meta.maskParam
         return when {
             meta.isStatic -> null
@@ -3144,7 +3163,7 @@
                 val stableBits = param.irSlotAnd(meta.maskSlot, StabilityBits.UNSTABLE.bits)
                 val maskIsUnstableAndChanged = irAndAnd(
                     irNotEqual(stableBits, irConst(0)),
-                    irChanged(arg)
+                    irChanged(arg, compareInstanceForUnstableValues = isMemoizedLambda)
                 )
                 irOrOr(
                     maskIsStableAndDifferent,
@@ -3173,7 +3192,7 @@
                 irOrOr(
                     irAndAnd(
                         maskIsUnstableOrUncertain,
-                        irChanged(arg)
+                        irChanged(arg, compareInstanceForUnstableValues = isMemoizedLambda)
                     ),
                     irEqual(
                         param.irIsolateBitsAtSlot(meta.maskSlot, includeStableBit = false),
@@ -3181,7 +3200,7 @@
                     )
                 )
             }
-            else -> irChanged(arg)
+            else -> irChanged(arg, compareInstanceForUnstableValues = isMemoizedLambda)
         }
     }
 
@@ -3570,7 +3589,7 @@
             // If a loop contains composable calls but not a otherwise need a group per iteration
             // group, none of the children can be coalesced and must be realized as the second
             // iteration as composable calls at the end might end of overlapping slots with the
-            // start of the loop. See b/205590513 for details.
+            // start of the loop. See b/232007227 for details.
             loopScope.realizeAllDirectChildren()
             loop.asCoalescableGroup(loopScope)
         } else {
@@ -3936,6 +3955,7 @@
             }
 
             private class IntrinsicRememberFixup(
+                val isMemoizedLambda: Boolean,
                 val args: List<IrExpression>,
                 val metas: List<ParamMeta>,
                 val call: IrCall
@@ -3943,13 +3963,16 @@
             private val intrinsicRememberFixups = mutableListOf<IntrinsicRememberFixup>()
 
             fun recordIntrinsicRememberFixUp(
+                isMemoizedLambda: Boolean,
                 args: List<IrExpression>,
                 metas: List<ParamMeta>,
                 call: IrCall
             ) {
                 val dirty = metas.find { it.maskParam is IrChangedBitMaskVariable }
                 if (dirty?.maskParam == this.dirty) {
-                    intrinsicRememberFixups.add(IntrinsicRememberFixup(args, metas, call))
+                    intrinsicRememberFixups.add(
+                        IntrinsicRememberFixup(isMemoizedLambda, args, metas, call)
+                    )
                 } else {
                     // capturing dirty is only allowed from inline function context, which doesn't
                     // have dirty params.
@@ -3957,15 +3980,19 @@
                     // means that we should apply the fixup higher in the tree.
                     var scope = parent
                     while (scope !is FunctionScope) scope = scope!!.parent
-                    scope.recordIntrinsicRememberFixUp(args, metas, call)
+                    scope.recordIntrinsicRememberFixUp(isMemoizedLambda, args, metas, call)
                 }
             }
 
             fun applyIntrinsicRememberFixups(
-                invalidExpr: (List<IrExpression>, List<ParamMeta>) -> IrExpression
+                invalidExpr: (
+                    isMemoizedLambda: Boolean,
+                    List<IrExpression>,
+                    List<ParamMeta>
+                ) -> IrExpression
             ) {
                 intrinsicRememberFixups.forEach {
-                    val invalid = invalidExpr(it.args, it.metas)
+                    val invalid = invalidExpr(it.isMemoizedLambda, it.args, it.metas)
                     // $composer.cache(invalid, calc)
                     it.call.putValueArgument(0, invalid)
                 }
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt
index c727084..90acac0 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt
@@ -62,7 +62,7 @@
 import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
 import org.jetbrains.kotlin.ir.declarations.IrValueParameter
 import org.jetbrains.kotlin.ir.declarations.IrVariable
-import org.jetbrains.kotlin.ir.declarations.copyAttributes
+import org.jetbrains.kotlin.ir.expressions.IrBlock
 import org.jetbrains.kotlin.ir.expressions.IrCall
 import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
 import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -74,7 +74,6 @@
 import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
 import org.jetbrains.kotlin.ir.expressions.IrValueAccessExpression
 import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
 import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
 import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
 import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
@@ -458,17 +457,64 @@
         return super.visitValueAccess(expression)
     }
 
+    override fun visitBlock(expression: IrBlock): IrExpression {
+        val result = super.visitBlock(expression)
+
+        if (result is IrBlock && result.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE) {
+            if (inlineLambdaInfo.isInlineFunctionExpression(expression)) {
+                // Do not memoize function references for inline lambdas
+                return result
+            }
+
+            val functionReference = result.statements.last()
+            if (functionReference !is IrFunctionReference) {
+                //  Do not memoize if the expected shape doesn't match.
+                return result
+            }
+
+            return rememberFunctionReference(functionReference, expression)
+        }
+
+        return result
+    }
+
     // Memoize the instance created by using the :: operator
     override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
+        val result = super.visitFunctionReference(expression)
+
+        if (
+            inlineLambdaInfo.isInlineFunctionExpression(expression) ||
+                inlineLambdaInfo.isInlineLambda(expression.symbol.owner)
+        ) {
+            // Do not memoize function references used in inline parameters.
+            return result
+        }
+
+        if (expression.symbol.owner.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) {
+            // Adapted function reference (inexact function signature match) is handled in block
+            return result
+        }
+
+        if (result !is IrFunctionReference) {
+            // Do not memoize if the shape doesn't match
+            return result
+        }
+
+        return rememberFunctionReference(result, result)
+    }
+
+    private fun rememberFunctionReference(
+        reference: IrFunctionReference,
+        expression: IrExpression
+    ): IrExpression {
         // Get the local captures for local function ref, to make sure we invalidate memoized
         // reference if its capture is different.
-        val localCaptures = if (expression.symbol.owner.isLocal) {
-            declarationContextStack.recordLocalCapture(expression.symbol.owner)
+        val localCaptures = if (reference.symbol.owner.isLocal) {
+            declarationContextStack.recordLocalCapture(reference.symbol.owner)
         } else {
             null
         }
-        val result = super.visitFunctionReference(expression)
-        val functionContext = currentFunctionContext ?: return result
+        val functionContext = currentFunctionContext ?: return expression
 
         // The syntax <expr>::<method>(<params>) and ::<function>(<params>) is reserved for
         // future use. Revisit implementation if this syntax is as a curry syntax in the future.
@@ -476,27 +522,27 @@
         // receivers are treated below.
 
         // Do not attempt memoization if the referenced function has context receivers.
-        if (expression.symbol.owner.contextReceiverParametersCount > 0) {
-            return result
+        if (reference.symbol.owner.contextReceiverParametersCount > 0) {
+            return expression
         }
 
         // Do not attempt memoization if value parameters are not null. This is to guard against
         // unexpected IR shapes.
-        for (i in 0 until expression.valueArgumentsCount) {
-            if (expression.getValueArgument(i) != null) {
-                return result
+        for (i in 0 until reference.valueArgumentsCount) {
+            if (reference.getValueArgument(i) != null) {
+                return expression
             }
         }
 
         if (functionContext.canRemember) {
             // Memoize the reference for <expr>::<method>
-            val dispatchReceiver = expression.dispatchReceiver
-            val extensionReceiver = expression.extensionReceiver
+            val dispatchReceiver = reference.dispatchReceiver
+            val extensionReceiver = reference.extensionReceiver
 
             val hasReceiver = dispatchReceiver != null || extensionReceiver != null
             val receiverIsStable =
                 dispatchReceiver.isNullOrStable() &&
-                extensionReceiver.isNullOrStable()
+                    extensionReceiver.isNullOrStable()
 
             val captures = mutableListOf<IrValueDeclaration>()
             if (localCaptures != null) {
@@ -526,28 +572,22 @@
                         tmp
                     }
 
+                    // Patch reference receiver in place
+                    reference.dispatchReceiver = tempDispatchReceiver?.let { irGet(it) }
+                    reference.extensionReceiver = tempExtensionReceiver?.let { irGet(it) }
+
                     +rememberExpression(
                         functionContext,
-                        IrFunctionReferenceImpl(
-                            startOffset,
-                            endOffset,
-                            expression.type,
-                            expression.symbol,
-                            expression.typeArgumentsCount,
-                            expression.valueArgumentsCount,
-                            expression.reflectionTarget
-                        ).copyAttributes(expression).apply {
-                            this.dispatchReceiver = tempDispatchReceiver?.let { irGet(it) }
-                            this.extensionReceiver = tempExtensionReceiver?.let { irGet(it) }
-                        },
+                        expression,
                         captures
                     )
                 }
             } else if (dispatchReceiver == null && extensionReceiver == null) {
-                return rememberExpression(functionContext, result, captures)
+                return rememberExpression(functionContext, expression, captures)
             }
         }
-        return result
+
+        return expression
     }
 
     override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
@@ -996,7 +1036,8 @@
 
         return irBuilder.irCall(
             callee = rememberFunctionSymbol,
-            type = expression.type
+            type = expression.type,
+            origin = ComposeMemoizedLambdaOrigin
         ).apply {
             // The result type type parameter is first, followed by the argument types
             putTypeArgument(0, expression.type)
@@ -1042,7 +1083,7 @@
         irCurrentComposer(),
         value,
         inferredStable = false,
-        strongSkippingEnabled = strongSkippingModeEnabled
+        compareInstanceForUnstableValues = strongSkippingModeEnabled
     )
 
     private fun IrValueDeclaration.isVar(): Boolean =
@@ -1135,3 +1176,5 @@
 
 // This must match the highest value of FunctionXX which is current Function22
 private const val MAX_RESTART_ARGUMENT_COUNT = 22
+
+internal object ComposeMemoizedLambdaOrigin : IrStatementOrigin
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt
index 852ae18..8c72dac 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt
@@ -46,10 +46,14 @@
 
 class ComposeInlineLambdaLocator(private val context: IrPluginContext) {
     private val inlineLambdaToParameter = mutableMapOf<IrFunctionSymbol, IrValueParameter>()
+    private val inlineFunctionExpressions = mutableSetOf<IrExpression>()
 
     fun isInlineLambda(irFunction: IrFunction): Boolean =
         irFunction.symbol in inlineLambdaToParameter.keys
 
+    fun isInlineFunctionExpression(expression: IrExpression): Boolean =
+        expression in inlineFunctionExpressions
+
     fun preservesComposableScope(irFunction: IrFunction): Boolean =
         inlineLambdaToParameter[irFunction.symbol]?.let {
             !it.isCrossinline && !it.type.hasAnnotation(ComposeFqNames.DisallowComposableCalls)
@@ -66,7 +70,7 @@
                 declaration.acceptChildrenVoid(this)
                 val parent = declaration.parent as? IrFunction
                 if (parent?.isInlineFunctionCall(context) == true &&
-                    declaration.isInlineParameter()) {
+                    declaration.isInlinedFunction()) {
                     declaration.defaultValue?.expression?.unwrapLambda()?.let {
                         inlineLambdaToParameter[it] = declaration
                     }
@@ -78,8 +82,9 @@
                 val function = expression.symbol.owner
                 if (function.isInlineFunctionCall(context)) {
                     for (parameter in function.valueParameters) {
-                        if (parameter.isInlineParameter()) {
+                        if (parameter.isInlinedFunction()) {
                             expression.getValueArgument(parameter.index)
+                                ?.also { inlineFunctionExpressions += it }
                                 ?.unwrapLambda()
                                 ?.let { inlineLambdaToParameter[it] = parameter }
                         }
@@ -119,7 +124,7 @@
 
 // This is copied from JvmIrInlineUtils.kt in the Kotlin compiler, since we
 // need to check for synthetic composable functions.
-private fun IrValueParameter.isInlineParameter(): Boolean =
+private fun IrValueParameter.isInlinedFunction(): Boolean =
     index >= 0 && !isNoinline && (type.isFunction() || type.isSuspendFunction() ||
         type.isSyntheticComposableFunction()) &&
         // Parameters with default values are always nullable, so check the expression too.
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt
index 9980397..0b0f561 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt
@@ -522,8 +522,7 @@
                 val param = symbol.owner.valueParameters[i]
                 val isLambda = arg is IrFunctionExpression ||
                     (arg is IrBlock &&
-                        (arg.origin == IrStatementOrigin.LAMBDA ||
-                            arg.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE))
+                        (arg.origin == IrStatementOrigin.LAMBDA))
                 if (isLambda) {
                     arg.unwrapLambda()?.let {
                         returnTargetToCall[it] = this
@@ -881,7 +880,7 @@
                 lhs.print()
                 print("--")
             }
-            IrStatementOrigin.LAMBDA, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE -> {
+            IrStatementOrigin.LAMBDA -> {
                 val function = expression.statements[0] as IrFunction
                 function.printAsLambda()
             }
diff --git a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
deleted file mode 100644
index 9cabe4e..0000000
--- a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2022 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.compose.foundation.layout
-
-import android.view.View
-import androidx.compose.foundation.text.BasicTextField
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.WindowInsetsControllerCompat
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
-import java.util.concurrent.TimeUnit
-import org.junit.After
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-
-@MediumTest
-class WindowInsetsAnimationTest {
-    @get:Rule
-    val rule = createAndroidComposeRule<WindowInsetsActionBarActivity>()
-
-    @Before
-    fun setup() {
-        rule.activity.createdLatch.await(1, TimeUnit.SECONDS)
-        rule.activity.attachedToWindowLatch.await(1, TimeUnit.SECONDS)
-    }
-
-    @After
-    fun teardown() {
-        rule.runOnUiThread {
-            val window = rule.activity.window
-            val view = window.decorView
-            WindowInsetsControllerCompat(window, view).hide(WindowInsetsCompat.Type.ime())
-        }
-    }
-
-    @SdkSuppress(minSdkVersion = 22) // b/266742122
-    @OptIn(ExperimentalLayoutApi::class)
-    @Test
-    @Ignore("b/266742122")
-    fun imeAnimationWhenShowingIme() {
-        val imeAnimationSourceValues = mutableListOf<Int>()
-        val imeAnimationTargetValues = mutableListOf<Int>()
-        val focusRequester = FocusRequester()
-        rule.setContent {
-            val density = LocalDensity.current
-            val source = WindowInsets.imeAnimationSource
-            val target = WindowInsets.imeAnimationTarget
-            val sourceBottom = source.getBottom(density)
-            imeAnimationSourceValues += sourceBottom
-            val targetBottom = target.getBottom(density)
-            imeAnimationTargetValues += targetBottom
-            BasicTextField(
-                value = "Hello World",
-                onValueChange = {},
-                Modifier.focusRequester(focusRequester)
-            )
-        }
-
-        rule.waitForIdle()
-        rule.runOnUiThread {
-            focusRequester.requestFocus()
-        }
-
-        rule.waitForIdle()
-        rule.waitUntil(timeoutMillis = 3000) {
-            imeAnimationSourceValues.last() > imeAnimationTargetValues.first()
-        }
-
-        rule.waitUntil(timeoutMillis = 3000) {
-            imeAnimationTargetValues.last() == imeAnimationSourceValues.last()
-        }
-    }
-
-    @OptIn(ExperimentalLayoutApi::class)
-    @FlakyTest(bugId = 256020254)
-    @Test
-    fun imeAnimationWhenHidingIme() {
-        val imeAnimationSourceValues = mutableListOf<Int>()
-        val imeAnimationTargetValues = mutableListOf<Int>()
-        val focusRequester = FocusRequester()
-        lateinit var view: View
-        rule.setContent {
-            view = LocalView.current
-            val density = LocalDensity.current
-            val source = WindowInsets.imeAnimationSource
-            val target = WindowInsets.imeAnimationTarget
-            val sourceBottom = source.getBottom(density)
-            imeAnimationSourceValues += sourceBottom
-            val targetBottom = target.getBottom(density)
-            imeAnimationTargetValues += targetBottom
-            BasicTextField(
-                value = "Hello World",
-                onValueChange = {},
-                Modifier.focusRequester(focusRequester)
-            )
-        }
-
-        rule.waitForIdle()
-        rule.runOnUiThread {
-            focusRequester.requestFocus()
-        }
-
-        rule.waitUntil(timeoutMillis = 3000) {
-            val target = imeAnimationTargetValues.last()
-            val source = imeAnimationSourceValues.last()
-            target > imeAnimationSourceValues.first() && target == source
-        }
-
-        rule.runOnUiThread {
-            val window = rule.activity.window
-            WindowInsetsControllerCompat(window, view).hide(WindowInsetsCompat.Type.ime())
-        }
-
-        rule.waitForIdle()
-
-        rule.waitUntil(timeoutMillis = 3000) {
-            imeAnimationTargetValues.last() == imeAnimationSourceValues.first()
-        }
-    }
-}
diff --git a/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt b/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt
index 9512a4a..7572615 100644
--- a/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt
+++ b/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt
@@ -43,13 +43,13 @@
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.Velocity
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.compose.ui.util.packFloats
 import androidx.compose.ui.util.unpackFloat1
 import androidx.compose.ui.util.unpackFloat2
 import kotlin.math.abs
 import kotlin.math.exp
 import kotlin.math.ln
-import kotlin.math.roundToInt
 import kotlin.math.sign
 import kotlinx.coroutines.CancellableContinuation
 import kotlinx.coroutines.CancellationException
@@ -269,8 +269,8 @@
         }
 
         val total = current + scrollAmount + partialConsumption
-        val next = total.roundToInt().coerceIn(hidden, shown)
-        partialConsumption = total - total.roundToInt()
+        val next = total.fastRoundToInt().coerceIn(hidden, shown)
+        partialConsumption = total - total.fastRoundToInt()
 
         if (next != current) {
             animationController.setInsetsAndAlpha(
@@ -388,7 +388,7 @@
     private fun adjustInsets(inset: Float) {
         animationController?.let {
             val currentInsets = it.currentInsets
-            val nextInsets = sideCalculator.adjustInsets(currentInsets, inset.roundToInt())
+            val nextInsets = sideCalculator.adjustInsets(currentInsets, inset.fastRoundToInt())
             it.setInsetsAndAlpha(
                 nextInsets,
                 1f, // alpha
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
index b7e385e..25a14a3 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
@@ -24,8 +24,8 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.min
-import kotlin.math.roundToInt
 
 /**
  * Used to specify the arrangement of the layout's children in layouts like [Row] or [Column] in
@@ -639,7 +639,7 @@
         val consumedSize = size.fold(0) { a, b -> a + b }
         var current = (totalSize - consumedSize).toFloat() / 2
         size.forEachIndexed(reverseInput) { index, it ->
-            outPosition[index] = current.roundToInt()
+            outPosition[index] = current.fastRoundToInt()
             current += it.toFloat()
         }
     }
@@ -654,7 +654,7 @@
         val gapSize = (totalSize - consumedSize).toFloat() / (size.size + 1)
         var current = gapSize
         size.forEachIndexed(reverseInput) { index, it ->
-            outPosition[index] = current.roundToInt()
+            outPosition[index] = current.fastRoundToInt()
             current += it.toFloat() + gapSize
         }
     }
@@ -678,7 +678,7 @@
             current = gapSize
         }
         size.forEachIndexed(reverseInput) { index, it ->
-            outPosition[index] = current.roundToInt()
+            outPosition[index] = current.fastRoundToInt()
             current += it.toFloat() + gapSize
         }
     }
@@ -697,7 +697,7 @@
         }
         var current = gapSize / 2
         size.forEachIndexed(reverseInput) { index, it ->
-            outPosition[index] = current.roundToInt()
+            outPosition[index] = current.fastRoundToInt()
             current += it.toFloat() + gapSize
         }
     }
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt
index bcfcde8..0e84e13 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt
@@ -31,7 +31,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.isSatisfiedBy
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Attempts to size the content to match a specified aspect ratio by trying to match one of the
@@ -126,7 +126,7 @@
         measurable: IntrinsicMeasurable,
         height: Int
     ) = if (height != Constraints.Infinity) {
-        (height * aspectRatio).roundToInt()
+        (height * aspectRatio).fastRoundToInt()
     } else {
         measurable.minIntrinsicWidth(height)
     }
@@ -135,7 +135,7 @@
         measurable: IntrinsicMeasurable,
         height: Int
     ) = if (height != Constraints.Infinity) {
-        (height * aspectRatio).roundToInt()
+        (height * aspectRatio).fastRoundToInt()
     } else {
         measurable.maxIntrinsicWidth(height)
     }
@@ -144,7 +144,7 @@
         measurable: IntrinsicMeasurable,
         width: Int
     ) = if (width != Constraints.Infinity) {
-        (width / aspectRatio).roundToInt()
+        (width / aspectRatio).fastRoundToInt()
     } else {
         measurable.minIntrinsicHeight(width)
     }
@@ -153,7 +153,7 @@
         measurable: IntrinsicMeasurable,
         width: Int
     ) = if (width != Constraints.Infinity) {
-        (width / aspectRatio).roundToInt()
+        (width / aspectRatio).fastRoundToInt()
     } else {
         measurable.maxIntrinsicHeight(width)
     }
@@ -184,7 +184,7 @@
     private fun Constraints.tryMaxWidth(enforceConstraints: Boolean = true): IntSize {
         val maxWidth = this.maxWidth
         if (maxWidth != Constraints.Infinity) {
-            val height = (maxWidth / aspectRatio).roundToInt()
+            val height = (maxWidth / aspectRatio).fastRoundToInt()
             if (height > 0) {
                 val size = IntSize(maxWidth, height)
                 if (!enforceConstraints || isSatisfiedBy(size)) {
@@ -198,7 +198,7 @@
     private fun Constraints.tryMaxHeight(enforceConstraints: Boolean = true): IntSize {
         val maxHeight = this.maxHeight
         if (maxHeight != Constraints.Infinity) {
-            val width = (maxHeight * aspectRatio).roundToInt()
+            val width = (maxHeight * aspectRatio).fastRoundToInt()
             if (width > 0) {
                 val size = IntSize(width, maxHeight)
                 if (!enforceConstraints || isSatisfiedBy(size)) {
@@ -211,7 +211,7 @@
 
     private fun Constraints.tryMinWidth(enforceConstraints: Boolean = true): IntSize {
         val minWidth = this.minWidth
-        val height = (minWidth / aspectRatio).roundToInt()
+        val height = (minWidth / aspectRatio).fastRoundToInt()
         if (height > 0) {
             val size = IntSize(minWidth, height)
             if (!enforceConstraints || isSatisfiedBy(size)) {
@@ -223,7 +223,7 @@
 
     private fun Constraints.tryMinHeight(enforceConstraints: Boolean = true): IntSize {
         val minHeight = this.minHeight
-        val width = (minHeight * aspectRatio).roundToInt()
+        val width = (minHeight * aspectRatio).fastRoundToInt()
         if (width > 0) {
             val size = IntSize(width, minHeight)
             if (!enforceConstraints || isSatisfiedBy(size)) {
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
index a835aba..82150c7 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
@@ -39,9 +39,9 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.max
 import kotlin.math.min
-import kotlin.math.roundToInt
 
 internal data class RowColumnMeasurePolicy(
     private val orientation: LayoutOrientation,
@@ -569,10 +569,10 @@
             fixedSpace += size
         } else if (weight > 0f) {
             totalWeight += weight
-            weightUnitSpace = max(weightUnitSpace, (size / weight).roundToInt())
+            weightUnitSpace = max(weightUnitSpace, (size / weight).fastRoundToInt())
         }
     }
-    return (weightUnitSpace * totalWeight).roundToInt() + fixedSpace +
+    return (weightUnitSpace * totalWeight).fastRoundToInt() + fixedSpace +
         (children.size - 1) * mainAxisSpacing
 }
 
@@ -612,7 +612,7 @@
     } else if (mainAxisAvailable == Constraints.Infinity) {
         Constraints.Infinity
     } else {
-        (max(mainAxisAvailable - fixedSpace, 0) / totalWeight).roundToInt()
+        (max(mainAxisAvailable - fixedSpace, 0) / totalWeight).fastRoundToInt()
     }
 
     children.fastForEach { child ->
@@ -623,7 +623,7 @@
                 crossAxisMax,
                 child.crossAxisSize(
                     if (weightUnitSpace != Constraints.Infinity) {
-                        (weightUnitSpace * weight).roundToInt()
+                        (weightUnitSpace * weight).fastRoundToInt()
                     } else {
                         Constraints.Infinity
                     }
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt
index 2c76aec..0b54663 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt
@@ -23,9 +23,9 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.max
 import kotlin.math.min
-import kotlin.math.roundToInt
 import kotlin.math.sign
 
 /**
@@ -151,7 +151,7 @@
 
             val weightUnitSpace = if (totalWeight > 0) remainingToTarget / totalWeight else 0f
             var remainder = remainingToTarget - (startIndex until endIndex).sumOf {
-                (weightUnitSpace * rowColumnParentData[it].weight).roundToInt()
+                (weightUnitSpace * rowColumnParentData[it].weight).fastRoundToInt()
             }
 
             for (i in startIndex until endIndex) {
@@ -167,7 +167,7 @@
                     remainder -= remainderUnit
                     val childMainAxisSize = max(
                         0,
-                        (weightUnitSpace * weight).roundToInt() + remainderUnit
+                        (weightUnitSpace * weight).fastRoundToInt() + remainderUnit
                     )
                     val placeable = child.measure(
                         OrientationIndependentConstraints(
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
index 6e8b669..3fa5e57 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
@@ -39,7 +39,7 @@
 import androidx.compose.ui.unit.constrain
 import androidx.compose.ui.unit.constrainHeight
 import androidx.compose.ui.unit.constrainWidth
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Declare the preferred width of the content to be exactly [width]dp. The incoming measurement
@@ -677,7 +677,7 @@
         val minWidth: Int
         val maxWidth: Int
         if (constraints.hasBoundedWidth && direction != Direction.Vertical) {
-            val width = (constraints.maxWidth * fraction).roundToInt()
+            val width = (constraints.maxWidth * fraction).fastRoundToInt()
                 .coerceIn(constraints.minWidth, constraints.maxWidth)
             minWidth = width
             maxWidth = width
@@ -688,7 +688,7 @@
         val minHeight: Int
         val maxHeight: Int
         if (constraints.hasBoundedHeight && direction != Direction.Horizontal) {
-            val height = (constraints.maxHeight * fraction).roundToInt()
+            val height = (constraints.maxHeight * fraction).fastRoundToInt()
                 .coerceIn(constraints.minHeight, constraints.maxHeight)
             minHeight = height
             maxHeight = height
diff --git a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt
index 8052414..8575d8f 100644
--- a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt
+++ b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/BoxWithConstraintsDetectorTest.kt
@@ -29,7 +29,7 @@
 private val ExternalModuleFunctionStub = kotlinAndBytecodeStub(
     filename = "Other.kt",
     filepath = "bar/compose",
-    checksum = 0xad5be2a5,
+    checksum = 0xdc553c55,
     source = """
         package bar.compose
 
@@ -51,54 +51,54 @@
         }
     """.trimIndent(),
     """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGJ2KM3AZcWllJiXUpSfmVKhl5yfW5BfnKqX
-                ll+al5JYkpmfp5eTWJlfWiIk4pRfEZ5ZkuGcn1dcUpSYmVdS7F3CJcbFnZRY
-                BNMmxO5fkpFaBBTn5WJOy88XYgtJLS7xLlFi0GIAALeBd4B7AAAA
-                """,
+    META-INF/main.kotlin_module:
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuJSSsxLKcrPTKnQS87PLcgvTtVL
+    yy/NS0ksyczP08tJrMwvLRESccqvCM8syXDOzysuKUrMzCsp9i7hEuPiTkos
+    gmkTYvcvyUgtAorzcjGn5ecLsYWkFpd4lygxaDEAADRmnbZ7AAAA
+    """,
     """
-                bar/compose/OtherKt$Test$1.class:
-                H4sIAAAAAAAA/6VU33MTVRT+7ibNJtvFlCLQFgSVCGmrbIv4i8RiCa2sxOCY
-                Usfp083m0myzubezezdT3vrm/+FfIDojjM44HR/9oxzP3cYQhuKDPOTck3PP
-                +c53zv2Sv/7+7Q8AN3GfYaHDYy9Qg32VCO+B7on4vq5siURXVm0whh+afaWj
-                UHp7w4EXSi1iySOvyQedLq9N3j1KZaBDJRNvc+St1ptcdmMVdg/GHR6pVHa5
-                ufUi/lil2rujDr4Lda9BlTrm1CFpB2pfjLEfylDX1mrE9NVEbOQZLv03GRsF
-                hkI9JLg1hlx1cZshX/UXt10U4TiYwjQFdC9MGC42X70VYlII5VD1BcPt6utM
-                aBhcaap419sTumNuEo9LqTQ/pt5SupVGETWcqxhelZeBiph9cfDxYnypYwIM
-                g8TGmwxng54I+iPEb3jMB4ISGa5Vm3t8yImq3PUedPZEoGsTkbYB2a2ZJZ3D
-                eQdnMcdw5oTl2FhgsB8mYouIuriIGQcX8BbDa2mA4eoJ/BZfDjHc+v9tbLzj
-                omwYW7jCMD0hPBvvMRT9VntrvdXYYDj1gipdXEO1hKtYZLD2VxlmT2JWrAdR
-                pjojtJJpct0UvlEib4Xh9L+QXwvNiS+nEmswzNEPlBljM7C+cXIUPwiNR1VW
-                l9pVjg5d5+jQsWYsx5qzyJ05OlywVtiStWLdc/78sWAVTVX3Bk1V51LJxwOV
-                JiR/kNSNnF3cRokoZq94va8p3FBdYSZRAY+2eRzyTiS2jGEoN0MpWumgI+JR
-                pPJtKnU4EL4chklIobG01p8LmcH1pRRxI+JJIuhreUMGkUpIWTRzT3UZSu1w
-                V3KdxoTptFUaB2IzNA3mRw22j+EnULFC+5uiQehvCvNmobSZPH1oyRS5Q16F
-                MmhWFJbyT+E+MRtFg6x7HMWprOa0eXvKNBUNOi06p5dnzzzD/PIzXDJlFu6S
-                NU9XoFSHSgzMuePUEYzxZnGZoDdGr0ZpmFkn9LdHfL4YobtLy0d491dUfsbS
-                T2P4QsaqPAHtjqFdLON9ui/ig/F057Mcavs7rO+fwvsFq0+ywBQ2M7ZslDCH
-                L7PVXCAC97J2OfjZuY6v6PyEMm9Q1Yc7yPm46eMjsvjYp4tPfXyGWztgCWqo
-                7yCf4PMEawkuJyj/AyfuA+BHBgAA
-                """,
+    bar/compose/OtherKt$Test$1.class:
+    H4sIAAAAAAAA/6VU33PbRBD+TnYsW1FxmtI2SUsL1LROAlVSCoXapE1NQkWN
+    y+A0DJOns3yNFct3GenkSd/yxv/BX0BhhnZghsnwyB/FsKcY405THuiD9lb7
+    49tv91b6869ffwdwE02GhQ6PvUAN9lUivIe6J+IHurIlEl1ZtcEYvm/2lY5C
+    6e0NB14otYglj7wmH3S6vDbpe5zKQIdKJt7mSFutN7nsxirsHowrPFap7HLj
+    9SL+RKXau6cOvg11r0GZOuZUIWkHal+MsR/JUNfWasT01URs5Bku/TcZGwWG
+    Qj0kuDWGXHVxmyFf9Re3XRThOJjCNBl0L0wYLjZfPRViUgjlUPUFw53q63Ro
+    GFxpqnjX2xO6YzyJx6VUmh9TbyndSqOICs5VDK/Ky0BFzL7Y+HgwvtQxAYZB
+    YuNNhrNBTwT9EeLXPOYDQYEM16rNPT7kRFXueg87eyLQtQlL24Ds1syQzuG8
+    g7OYYzhzwnBsLDDYjxKxRURdXMSMgwt4i+G1doDh6gn8Fl82Mdz+/2VsvOOi
+    bBhbuMIwPbF4Nt5jKPqt9tZ6q7HBcOqFrXRxDdUSrmKRwdpfZZg9iVmxHkTZ
+    1plFK5ki103iGyXSVhhO/wP5ldCc+HJKsQbDHH2gzIiSEWBgfaPkyHkQGo1S
+    rS7VrBwdus7RoWPNWI41Z5E6c3S4YK2wJWvFuu/88UPBKpqs7g1qrc6lkk8G
+    Kk3oGyDQvNlpF3dRIp7ZVV7vazI3VFeYdlTAo20eh7wTiS0jGMrNUIpWOuiI
+    eGSpfJNKHQ6EL4dhEpJpvF/r/24zg+tLKeJGxJNE0Gt5QwaRSmi9qPGe6jKU
+    2uGu5DqNCdNpqzQOxGZoCsyPCmwfw0+gYoWGOEWN0L8K82aqNJk8PTRpsjRI
+    q1AE9YrCUv4Z3KfZLD8n6R5bcSrLOW0WgCJNRoNOi87p5dkzzzG//ByXTJqF
+    DZLm/goU6lCKgTl3HDqCMdosLhP0Juk23RqFYWad0N8e8bk7QneXlo/w7i+o
+    /ISlH8fwhYxVeQLaHUO7WMb75C/ig3F357MYKvsbrO+ewfsZq08zwxS+yNiy
+    UcAc7mejuYB1+Fm5HL7Mznt4QOctirxBWR/uIOfjpo+PfHyMWz4+wac+bqO2
+    A5agjs92kE+wluBOgssJyn8D0BOnRkwGAAA=
+    """,
     """
-                bar/compose/OtherKt.class:
-                H4sIAAAAAAAA/6VUWVMTQRD+ZhNICEGWcMglHgQJqCzggRo8MCXlljFYglgl
-                T5PNAAubWWpnQuEbf0mfKB8snv1Rlj1LRDnUKk1Vpo/p/rr7m06+fvv8BcAd
-                FBm6qzxyvLC+EyrhLOlNEb3UKTAGe4vvcifgcsNZqm4Jj7wJhpY4hOFJocxl
-                LQr92t5x9nrYkDWu/VBS2oewoZ1n4d47X2+WQql0xH2p1bIX7ojixCrD2FmA
-                qCG1XxdOKbZ5NRDU4Gg5jDacLaGrBkE5XMpQx1WUUwl1pREEFNU6rzd99TiN
-                NoaR7VAHvnS2dusO1RSR5IHjSh1Ruu+pFNoZer1N4W0381/ziNeFNnONF8qn
-                5y7+4lk2IBvUfxYduJBBFp0M7XlTO99kZv5/iGFIvVViheCIamVcafQwJFeE
-                0gyJgiFu8JwXy5uA/EwK/Qxpt7K8slApPWcYLv8+tpjFIIbaMIDhk5StN6R3
-                RO9iUyPcEYa5f5rLbNMVavrsTb4m1nkjoLnmCu/Lf26g6J59FvMI1zCawVXk
-                Gbp+ILwSmlNTnLi06rsJ2nNmjhQD2zaKRf4932jTpNVmGJ4e7tuZw/2MZVsZ
-                K03ffovMwbRNhzXNXqQGbdsy2myrnSCZJE/WbjGeydgyOLOMCiEdczy1TUMl
-                S2FNMHSWfSkqjXpVRCtmoxly5dDjwSqPfGM3nUNvjnbflbu+8sm18HPNGfKn
-                b4839kRY1pVSRKWAKyXIzCyHjcgTi74pMNCEWD0DjxlYSMJ8ErQNLWgleZss
-                42eGuslc5gD2R0Me/WmAAugHhzTukp49CkEXciTvNW9TJOearFMgCLf7PNze
-                c3DbT+D2/A23Dxcp3eBONKfoSHzCpUNcTrIDjBl0FqNnKAzoJOTcCbwE7se3
-                xFGc3o8HcUezeEjyEfmvEynja0i4KLiYoBOTLm7gpotbmFoDU3AwvYZWhT5i
-                U6FboUchp9DyHfyqvvRqBQAA
-                """
+    bar/compose/OtherKt.class:
+    H4sIAAAAAAAA/6VT21ITQRA9s7kSoqwBkYt3owZUFvCCGrxgSsotY7QEsUqe
+    JpuBLNnMWjsTCt/4JXyifLB49qMse5aIRlCr9GFnus90n54+0/vl66fPAG5h
+    nmGwziPHC9vvQyWcl7opouc6A8Zgb/BN7gRcrjsv6xvCIzTBkIpDGB6Vqlw2
+    otBvbB1kr4Ud2eDaDyWlfQg72nkSbr31dbMSSqUj7kutlrzwvShPrDBcPkwQ
+    daT228KpxD6vB6LMcKkaRuvOhtB1w6AcLmWo4yrKqYW61gkCikrP66avHmbR
+    x3C2FerAl87GZtuhmiKSPHBcqSNK9z2VQT/DSa8pvFY3/xWPeFto09fVUvXX
+    vss/IUuGZJ3un8cxHM8hjwGG/qKpXewqM/8/wjBk3iixTHQktTJQFkMMyWWh
+    NEOiZIQbO+LFiiagOJPBCEPWrS0tL9QqTxlOV38fW85jDON9GMXpXsnWOtLb
+    l3exaxHvWYa5f+rLTNN5uvThk2JDrPFOQH3Nld5V/3yBsnv4WcwjXMSlHC6g
+    yHDiO8MLoTldipOWVnszQXPOzNJnFjCwljEsOtzyjTVNVmOG4fHetp3b285Z
+    tpWzsvSNWOSOZW1arGn2LDNm25axZtN2gvYkIXk7ZZDJ2DM8s8yUyMZCT7Wo
+    s2QlbAiGgaovRa3Troto2Yw1Q6EaejxY4ZFv/C44/nr/B3Dlpq98ghZ+zDpD
+    8dfTg7HtCcu7UoqoEnClBLm5pbATeWLRNwVGuxQrh+gxAwtJIxESNBIppGm/
+    RZ7BqStkJgu5Xdg7RjzcpjVNcBpZ3CE7vx+CEyjQPtc9zdB+1+DMiELGKAaP
+    4j15BG9/D+/Q33iHcYrSDe9Et4tjiY84s4dzSbaLyzvx0xv2HIUBA8Rc6OFL
+    4F58ShrF6SO4H9/oJsq0PyD8ColydRUJFyUXEy4mcc3FddxwMQVnFUxhGjOr
+    SCsMK8wqDCoMKRQUUt8ADl3qEW8FAAA=
+    """
 )
 
 @RunWith(JUnit4::class)
@@ -111,7 +111,7 @@
     private val BoxWithConstraintsStub = bytecodeStub(
         filename = "BoxWithConstraints.kt",
         filepath = "androidx/compose/foundation/layout",
-        checksum = 0xddc1f733,
+        checksum = 0x12a1c0a0,
         source =
         """
             package androidx.compose.foundation.layout
@@ -137,67 +137,67 @@
             ) {}
         """.trimIndent(),
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGJ2KM3AZcWllJiXUpSfmVKhl5yfW5BfnKqX
-                ll+al5JYkpmfp5eTWJlfWiIk4pRfEZ5ZkuGcn1dcUpSYmVdS7F3CxcvFnJaf
-                L8QWklpc4l2ixKDFAAD5174zYwAAAA==
-                """,
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuJSSsxLKcrPTKnQS87PLcgvTtVL
+        yy/NS0ksyczP08tJrMwvLRESccqvCM8syXDOzysuKUrMzCsp9i7hEuPiTkos
+        gmkTYvcvyUgt8i5RYtBiAADDkmqHbAAAAA==
+        """,
         """
-                androidx/compose/foundation/layout/BoxWithConstraintsKt.class:
-                H4sIAAAAAAAA/6VTXU8TQRQ9sy394qsU+SqIKCAgwhZiwkOJiRKJjQWNRYzw
-                NGyHsrSdaXZnCbwY/oav/gPfiA+G+OiPMt7ZtlrsA4lusnfunTl77p17z/74
-                +fUbgCdYZ9jgsuwpt3xuO6reUL6wj1Ugy1y7Sto1fqECbT9X5+9dfbKlpK89
-                7krtv9JxMIb0KT/jhJIV+/XRqXBoN8KQ6cYzzC0eFKtK11xpn57V7eNAOiaF
-                b2+3vLX80j5D41bY5krxn0ouOaoh8m3yd9LV+adhyvluPi+Q2q0LeyuM+VFN
-                5Blmi8qr2KdCHxlC3+ZSKs2b1e0qvRvUaoSKO0pqIXUCKYbpjqtQDcKTvGYX
-                pPboe9fx4+hjGHFOhFNtEbzhHq8LAjIsLBb/7m6+Y6dkSCp0gT4MYDCFfqQZ
-                xhqeavAK12LHlTfazw4YZm4bAEO2u29zZXHMg5omqdw+wkJ3zabCHsRSsDDG
-                MNRm2BGa08g4JbXqZxGSIzMmTqVWjWPR/rlrvBx55TWGD9eX06nry5SVtppL
-                b7iMW51vNpe+vsxaObaeSBCQvMj6VDqaHc9EM1YuFlqW6/n+OWYl4qFNvIyb
-                BPQrgKTbLq+zKZv/IzgSQZvzxTkJw6dv2uR7FyFgpPvb1Sr1O7qlyoJhsOhK
-                sRvUj4S3Z6RoqlQOr+1zzzVxazNZciuS68Ajf/JtU8AFeeb6Lh0/+6NV+hX/
-                Pv2tuhuw/pLmTnWHN1oJUiUVeI7Ydk0w0eLY7+LHGk06CvNYmDCjp2iJojzF
-                lhnxcqb3CkNfQsAjsjFqfAwjWCZ/tAlBBsMhRRwp3KHzxyE6jpUWPkHrKr1J
-                A6fLA+kkUYySb3JttGoYmIp+/ISeSD67fIXxZkqbbAQsEeYegJFYhjiHiTND
-                x7kQtEjXALaJzlwhe4hIAZMFTJHF3QKmca+AGdw/BPPxALOHSPro8THnIxPa
-                lI95Hw99JHws/AJecgBzcAUAAA==
-                """,
+        androidx/compose/foundation/layout/BoxWithConstraintsKt.class:
+        H4sIAAAAAAAA/6VTW08TQRT+Zlt6A7GucrEioqKCqNuiCQ81JkokNhY0FjHK
+        03Q7lO1lptmdbcqL4W/46j/wzfhgiI/+KOOZbavVPpDoQ89l55vvnDnn6/cf
+        X74CeID7DBtc1nzl1XqOq9odFQjnQIWyxrWnpNPiRyrUzhPVe+Ppw00lA+1z
+        T+rguU6CMWQbvMsJJevOi2pDuPQ1xmCP4xmWV96Vm0q3POk0um3nIJSuKRE4
+        W4OoUFzdY+icCnt4t/xPLVdc1RHFIflr6enio6jkjXE+P5TaawtnM8p5tSWK
+        DNfLyq87DaGrhjBwuJRK8353O0rvhK0WoZKuklpInUKGYXHkKdSD8CVvOSWp
+        fbrvuUESUwwz7qFwmwOCl9znbUFAhlsr5b+nWxz5UjEkdXrAFKZxNoMzyDLM
+        dXzV4XWuxbYn/xg/e8ewdNoCGHLjc1uuiQMetjRJ5fQVlsZ7Nh1OIJGBhTmG
+        c0OGbaE5rYxTUavdjZEcmTFpY0D9Nk1g0WHPM1GeolqB4e3J8WLm5DhjZa2+
+        m4zcvDX6y+WzJ8c5K8/WUykCUhRbX8jGc/N23Lbyiciy/MS3jwkrlYxs6lnS
+        FFhnprY97HF0Mg//R3WkhCHn0x6pI6A7Q/LdowgwM373XpOGHt9UNcFwtuxJ
+        sRO2q8LfNXo0XSqXt/a475l88DFd8eqS69Cn+NKrvopLsusFHh0//i1Y+j/+
+        ffpLen/AzlQ0d5vbvDMokKmo0HfFlmeSiwOOvTF+FGjdcbNK8hfN/im7TVmR
+        cot8cs2e/IxznyLAGtkEDT6BGdyheLYPgY3zEUUSGVyg87sROol7A3yKvGNE
+        Y0WaSQPZNFHMUmxqbQx6mF6Iv/+AiVgxt/YZ8/2SebIxsFRUexpGYjZxnidO
+        m44LEWgV6+S3iM48IbePWAmXSlgo4TIWS7iCpRKu4to+WIDrWN5HOsBEgBsB
+        7MhmAtwMcCtAKsDKT2vS8Et1BQAA
+        """,
         """
-                androidx/compose/foundation/layout/BoxWithConstraintsScope.class:
-                H4sIAAAAAAAA/5WSzW7aQBDH/2vA2IYQJ21aQvqdSm0uNUU9tb30Q1WRSCol
-                UhOJkzEOLNi7iF0QvfEUfYAe+hA9VCjHPlTVMSUBQSpRazWz89N/dtYz++v3
-                j58AXuAxw0tfNPuSN0deIOOeVKF3Lgei6WsuhRf5X+RAe2/l6JTr9jsplO77
-                XGh1EshemAVjcDv+0CehaHmfGp0w0FmkGAqtUC/IGSpPD2prVFrIecWwX5P9
-                ltcJdSNByvOFkHqqV96R1EeDKCJVjmodcnHKm7rNcLBeofe9y0x/NMvM/z3n
-                Y8hbbT0L/dFluFXrSh1x4R2G2qezfMo34mGK+sgSk2VgXUIjnkRl2jWfM3yd
-                jEuOUTQcw52MHVrTvZWaecs6L07GFaPMjrddo2SUU2cX39MX30yzlLbSboao
-                STS7QC3XJuos0dyU5pfoxpQWluimaye3qzC8XqdT/xg+/T6og8HikMv/P2I7
-                nrf4ydqDs+KrqdnxfGRWfPUMdlav/axLkr3jgdA8DqtiyBVvROGb+ZticE7k
-                oB+EH3gUMuzOpJ9XhCb1D2kkXybNkIFJrXhIUeKzADEL9gpzrmG5a1h+mVG1
-                R1P7APvk60Q3qGqhjlQVm1W4ZLGVmO0qbuAmCRR2cKsOV+G2QlFhV6GkkFEw
-                FfYU7ijkFWyFuwqOwj2FnMJ9BesPb1xrKxsEAAA=
-                """,
+        androidx/compose/foundation/layout/BoxWithConstraintsScope.class:
+        H4sIAAAAAAAA/5WS3W4SQRTH/7MLy+5C6bZapdTvarQ3LhKv1Bs/YiShNWkT
+        a8LVAlsY2J0hzEDwjqfwAbzwIbwwpJc+lPEs0kKgJphszscv/zNn9pz59fvH
+        TwDP8YjhRSCafcmbI78h455UoX8mB6IZaC6FHwVf5ED7b+TolOv2WymU7gdc
+        aHXSkL0wA8bgdYJhQELR8j/WO2FDZ2Ay5FuhXpAzlJ8cVNfotFDzkmG/Kvst
+        vxPqeoKUHwgh9VSv/COpjwZRRKos9Trk4pQ3dZvhYL1G73oXlcFoVpn7e86H
+        kLfaepYGo4t0q9qVOuLCPwx1QGcFVG/EQ5PmyBLjJAYMrEt8xJOsRFHzGcPX
+        ybjoGgXDNbzJ2KVvGtvmzNv2WWEyLhsldrztGUWjZH4+/546/2ZZxZSd8tJE
+        LaKZBWp7DlF3iWanNLdEN6Y0v0Q3PSe5XZnh1Trj+scLoBnQL2cbi5su/f+e
+        nXg+58drb8+OL1fnxPO92fHlW9hZvfbTLkn2jgdC8zisiCFXvB6Fr+cPi8E9
+        kYN+I3zPo5Bhdyb9tCK0aH5IJUtHOsWQhkWjeEBZ4jMAMRvOCnOvYNkrWG6Z
+        Ubf9qb2Ph+RrRDeoa74Gs4LNCrwKtrBNIa5VcB07JFC4gZs1eAoFhV2FosKe
+        QlrBUrilcFshp+Ao3FFwFe4qZBXuKdh/AAfjFM8gBAAA
+        """,
         """
-                androidx/compose/foundation/layout/Constraints.class:
-                H4sIAAAAAAAA/5WPz07CQBDGv9mWUot/CooiT6AXWonxYjyoiQkJxAQTMeFU
-                aIEVumvYheCNZ/HgQ3gwhKMPZdxyMF7dbH47szO73zdf3x+fAM5xRKhFIp5K
-                Hi+CvkxfpEqCgZyJONJcimASvcqZDm6lUHoacaFVHkTwn6N5ZIpiGNz3npO+
-                zsMiFIaJbnHR4bEeEayT0wah2BxLPeEiaCU6Mp9GlwSWzi2jThnyBBqbqwXP
-                stBE8RnhYrUseazCPOavlp7ZzHc95jJ3UFkt6yykdslnVRZaT+t3e/3mOFXb
-                tf1c9rpOCJv/G8lYAsFNf62Xb+Siw/XoT09trAneg5xN+8kdnySE4/ZMaJ4m
-                j1zx3iS5FkLqjYJyjA/YyBbZhBwcEzGUNzzAoTmvjGDeVNwurAa2GvAMUciw
-                3cAOdrsghT34XTgKRYWSwv6GOQXnB5/tt/C/AQAA
-                """,
+        androidx/compose/foundation/layout/Constraints.class:
+        H4sIAAAAAAAA/5VPy07CQBQ9d1pKKT4KiiJfoBtaiXFjXKiJSROICSZiwqrQ
+        AsNjxjADwR3f4sKPcGEISz/KOLAwbk0mZ859nnO/vj8+AVygTKjGIplKniyC
+        rpy8SJUGPTkTSay5FME4fpUzHdxJofQ05kKrLIjgD+N5bIqiHzx0hmlXZ2ER
+        8v1UN7ho8UQPCNbpWUQo1EdSj7kIGqmOzdL4isAmc8uo0wZyGwCBRia/4Jso
+        NCw5J1yulkWPlZnH/NXSM4/5rsdc5vbKq2WNhdQs+qzCQut5/W6v3xynYru2
+        n9lM1whh/X93GV/Ghjv59V+6lYsW14M/PdWRJniPcjbtpvd8nBJOmjOh+SR9
+        4op3xumNEFJvFZRjfMDG9jqbkIFjGMPRFks4Nv+1EcyaituGFSEXwYuQx46h
+        2I2wh/02SMFHoQ1HoahwoHC4xYyC8wPcDr7hxAEAAA==
+        """,
         """
-                androidx/compose/foundation/layout/Dp.class:
-                H4sIAAAAAAAA/41Oy07DQAwcb6Ep4ZXykMoHIG6krXrjxENIlYqQQIJDT9tm
-                C9sku1V2U4Vbv4sD6pmPQjjlB7Cl8diWZ/z98/kFYIATwrk0SWF1UsVTmy+s
-                U/HMliaRXlsTZ/LDlj6+WwQgQjSXS8kz8xY/TuZq6gM0CO1Ran2mTfygvOQ7
-                eUUQ+bLBBlRDQKCUR5Wuuy6zpEc4Xa9aoeiIUETMZp31qi+6VC/7hIvRv55i
-                I7DSja1etX+/tcb5Qmrj3WXqCeGzLYuputeZIpw9lcbrXL1opyeZujbG+o2a
-                a7IntvAXAkcbbOOYa4/VtzmbYzSGCIZoMWKnhnCIXeyNQQ77OBhDOBw6RL/m
-                nxtjWQEAAA==
-                """
+        androidx/compose/foundation/layout/Dp.class:
+        H4sIAAAAAAAA/41Oy07DQAwcb6GP8GqBSuUDEDfSVr1x4iGkSEVIIMGhp22z
+        hW2S3Sq7qcKt38UB9cxHIZzyA9jSeGzLM/7++fwCMEKXcC5NnFsdl+HMZkvr
+        VDi3hYml19aEqfywhQ/vlg0Qob2QK8kz8xY+Thdq5huoETrjxPpUm/BBecl3
+        8oogslWNDaiCVgUgUMLzUlddn1k8IHQ362YgeiIQbWbz3mY9FH2qlkPCxfhf
+        n7Ebi3dvbPmq/futNc7nUhvvLhNPCJ5tkc/UvU4V4eypMF5n6kU7PU3VtTHW
+        b9VcnT2xg78QONniMU65Dlh9l7M+QS1CI0IzQgsBU+xF2MfBBORwiKMJhEPb
+        ofMLzHJE/14BAAA=
+        """
     )
 
     @Test
diff --git a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/LazyLayoutStateReadInCompositionDetectorTest.kt b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/LazyLayoutStateReadInCompositionDetectorTest.kt
index 3fb5c9a..1fe039d 100644
--- a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/LazyLayoutStateReadInCompositionDetectorTest.kt
+++ b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/LazyLayoutStateReadInCompositionDetectorTest.kt
@@ -37,7 +37,7 @@
     private val lazyGridStateStub = bytecodeStub(
         filename = "LazyGridState.kt",
         filepath = "androidx/compose/foundation/lazy/grid",
-        checksum = 0xd5891ae4,
+        checksum = 0x1f30c0f3,
         source = """
                     package androidx.compose.foundation.lazy.grid
 
@@ -51,59 +51,59 @@
                         val layoutInfo: LazyGridLayoutInfo get() = object : LazyGridLayoutInfo {}
                     }
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGI2Bijg0uSST8xLKcrPTKnQS87PLcgvTtVL
-        yy/NS0ksyczPAzLzhdhCUotLvEuUGLQYAJ1f4slDAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uSST8xLKcrPTKnQS87PLcgvTtVL
+        yy/NS0ksyczPAzLzhdhCUotLvEuUGLQYAAC6oXVDAAAA
         """,
         """
         androidx/compose/foundation/lazy/grid/LazyGridLayoutInfo.class:
-        H4sIAAAAAAAAAJ2OzU7CQBSFzx2UYv0rKgm+hAPEhdGVG02TGhNJ3LAa2ikZ
-        KDOGTgm44rlcGNY+lPEW4ws4Nznz3bmTc8/X98cngGt0CDfKZgtnspVM3fzN
-        lVrmrrKZ8sZZWaj3tZwsTCYTpkeGRK1d5WObuwBEiKZqqfibncjn8VSnPkCD
-        0E5mzhfGyiftFVupO4KYLxu8k2pp1gICzfh9Zequx5T1CZ3tphWKrghFxJR3
-        t5uB6FE9HBBuk/+G5QC8L/obDL3y+mrmCeHQVYtUP5hCEy5fKuvNXL+a0owL
-        fW+t8zvvsskJsIffI3C+0zNc8N1n432u5giNGEGMVowDhIw4jHGE4xGoxAlO
-        RxAlohLtH5JfRp1/AQAA
+        H4sIAAAAAAAA/52OzU4CMRSFzy3Kz/g3qCT4EhaIC4MrN5pJxphI4oZVmemQ
+        wtAapkPAFc/lwrD2oYx3ML6Avcnpd3ubc8/X98cngBt0CLfKpktn0rVM3OLN
+        FVpmrrSp8sZZmav3jZwuTSpjpkeGWG1c6SObuQaIEM7USvE3O5XPk5lOfAM1
+        QjueO58bK5+0V2yl7ghisarxTqqkVQkINOf3tam6HlPaJ3R222YguiIQIVPW
+        3W0HokfVcEAYxv8NywF4X/g3GHnl9fXcE4KRK5eJfjC5Jly9lNabhX41hZnk
+        +t5a5/feRZ0T4AC/R+Bir+e45LvPxodc9TFqERoRmhFaCBhxFOEYJ2NQgVOc
+        jSEKhAXaP+1d5AJ/AQAA
         """,
         """
         androidx/compose/foundation/lazy/grid/LazyGridState$layoutInfo$1.class:
-        H4sIAAAAAAAAAKVSTW/TQBB946R1a1zSlo8mfBcCanvATeGAoEJABciSAYlW
-        ueS0sbfpNs4ustdVyyl/iRMSB5QzPwoxGxAVx5bLzJu3M7Oz++bHz2/fATzG
-        A8ILobPCqOw4Ss3okylltG8qnQmrjI5y8fkkGhQqixJGbxnsWmFlOxcnprKx
-        3jftjg8iLB6KI8HpehB96B/K1PqoEZ6crXfyt6uPGcLsttLKPifU1ta7IXzM
-        BahjnlC3B6okvEr+d/RnhKVkaGyudPROWsGlgjlvdFTj7yFnZp0BgYbMHysX
-        bTLKOoSVyXg+mIwDr+lt0GQ8FzQn4y1vk9zxFuHpGcc7fT2P8OgcT/PRIiwM
-        pD3tRNheWz//HCGu4waL+881D4eWJdgxmSQ0EqXl+2rUl8We6OfMLCcmFXlX
-        FMrFf8gw1loWO7koS8nCNV7rNDel0gP+9AOTEYJdUxWpfKNcdutjpa0aya4q
-        FZe/1NrY6bAlOvB4BXg1pprA7QT724wipxH7mY2vCL4w8HDHyTclL2CVbfg7
-        gaOQfR132QbMeU5htHBvyl7DTbSn9bdwn32HMxa46mIPtRiNGIsxlrDMEJdi
-        XMaVHqjEVaz04JUONn8B8d9xtF4DAAA=
+        H4sIAAAAAAAA/6VSTW/TQBB946R1Y1zSlo8mfH8E1PaAm8IBQYWACpAlAxJF
+        ueS0sbfpNs4ustdVyyl/iRMSB5QzPwoxGxAVx5bLzJu3M7Oz++bHz2/fATzC
+        fcJzobPCqOwoSs34kylltGcqnQmrjI5y8fk4GhYqixJGbxjsWmFlJxfHprKx
+        3jOdrg8iLB2IQ8Hpehi9HxzI1PqoER6frnfyt6uPOcL8ttLKPiPU1tZ7IXws
+        BKijQajbfVUSXib/O/pTwnIyMjZXOnorreBSwZw3Pqzx95AzDWdAoBHzR8pF
+        m4yyLmF1OmkE00ngtbwNmk4WgtZ0suVtkjveIjw55Xgnr+cRHp7haT7ahMWh
+        tCedCNtr62efI8RVXGNx/7nmwciyBDsmk4RmorR8V40HsvgoBjkzK4lJRd4T
+        hXLxHzKMtZbFTi7KUrJwzVc6zU2p9JA/fd9khGDXVEUqXyuX3f5QaavGsqdK
+        xeUvtDZ2NmyJLjxeAV6NmSZwO8H+JqPIacR+buMrgi8MPNxiOz8jz+E22/B3
+        Akch+zrusA2Y85zCaOPujL2C6+jM6m/gHvsuZyxy1fk+ajGaMZZiLGOFIS7E
+        uIhLfVCJy1jtwysdbP0CBEAxIl4DAAA=
         """,
         """
         androidx/compose/foundation/lazy/grid/LazyGridState.class:
-        H4sIAAAAAAAAAKVTS08UQRD+evbJ7CKzKLo8FBVUQGUAJSFKjEqCmWSEBMwm
-        htPsbu/a7GyPme4l4Inf4tmDnkg0MRuP/ihj9bDhJQfFOdTj6/qqaqq6f/76
-        +h3AY8wyPApkPY5EfdetRe33keJuI+rIeqBFJN0w+LDnNmNRd32yXpGxqQPN
-        c2AMznawE1CEbLrr1W1e0zmkGLLLQgr9jCE1NV0pIoOsjTRyDGn9TiiGRf8C
-        9Z4ylJtcr4pY6YpQohpyT/O2J+t8N6nkMYyfE7BZi6MwXG80FNcM/RThB3tR
-        R3uyETEsT03/YzPHbOpowo/iprvNdTUOhFRuIGWkE6Zy1yK91glDinp+gd+d
-        DI/qTM7nULIxaCa4dNFmc7jCUPJbkQ6FdF9zHRApoOas9k6K7gEzImsEGFiL
-        8F1hvDmy6vMMre7+mG2VLdtyuvu2lTdGnnTmEMxb5e7+gjXHXmZ+fMxajrVR
-        clIj1lx6aZX87Eg6n3GyhOVOYfkE6yPMPsIKTtGUXGCmkaHG+eseO4uf3rId
-        nljxk/9ZsHNqKbMtSp5eieqcYcAXkq912lUevwmoC4ZBP6oFYSWIhfF74OhG
-        R2rR5p7cOez2xfEVYSh6UvJ4JQyU4uTam1EnrvFVYZjDPWblDx7mYdGDMl+a
-        hkTvi+Q98lyzO9KZmQPkv5BhYcqsNQHzmCZZPAxAH2zSJRQSxJAf9MhW6tMZ
-        Zt8JpnXE7P8Lpn0u8xIGyDPMRdLmrPANg28PcLmLoc9nUhROpCj0Usz0Th3S
-        KdxPCtH8k4kMUzsmw108JL1B+FX63WtbSHkoexj2MIJRMjHm4TpubIEpjOPm
-        FvoVbIVbClmF24lRUCgqTChzNKlwR+GSwsBv73s6jzkFAAA=
+        H4sIAAAAAAAA/6VTW08TQRT+ZnvfFtiiaLkoKqiAygJKQpQYlQSzSYUETBPD
+        07ad1qHbWbMzJeATv8VnH/SJRBPT+OiPMp5ZGm7yILgP5/LN+c45e87Mr9/f
+        fgB4glmGx76sR6Go77q1sP0hVNxthB1Z97UIpRv4H/fcZiTqbpms12Rsal/z
+        DBiDs+3v+BQhm+56dZvXdAYJhvSykEI/Z0hMTVcKSCFtI4kMQ1K/F4phsXyJ
+        es8YSk2uV0WkdEUoUQ24p3nbk3W+G1fyGMbPCdisRWEQrDcaimuGPooo+3th
+        R3uyETIsT01fsJljNnU0UQ6jprvNdTXyhVSuL2WoY6Zy10K91gkCinpxid+d
+        DI7qTM5nULQxaCa4dNlmM7jKUCy3Qh0I6b7h2ieST81Z7Z0E3QNmRM4IMLAW
+        4bvCeHNk1ecZWt39MdsqWbbldPdtK2uMLOnUIZi1St39BWuOvUr9/JS2HGuj
+        6CRGrLnk0ir56ZFkNuWkCcucwrIxliPMPsLyTsGUXGCmkaHG+eseO4uf3rId
+        nFjx0/9ZsHNqKbMtSp5cCeucYaAsJF/rtKs8eutTFwyD5bDmBxU/EsbvgaMb
+        HalFm3ty57Dbl8dXhKHgScmjlcBXipNrb4adqMZXhWEO95iVv3iYh0UPynxJ
+        GhK9L5L3yXPN7kinZg6Q/UqGhSmS6RjMYppk4TAAOdiki8jHiCE/7JGtxOcz
+        zNwJpnXE7PsHpn0usx8D5BnmImlzlv+OwXcHuNLF0JczKfInUuR7KWZ6pw7p
+        BB7EhWj+8USGqR2T4R4ekd4g/Br97vUtJDyUPAx7GMEomRjzcAM3t8AUxnFr
+        C30KtsJthbTCndjIKxQUJpQ5mlS4q9CvMPAH6p7bvDkFAAA=
         """
     )
 
     private val lazyListStateStub = bytecodeStub(
         filename = "LazyListState.kt",
         filepath = "androidx/compose/foundation/lazy",
-        checksum = 0xb9a80c68,
+        checksum = 0x4e68cddf,
         source = """
                     package androidx.compose.foundation.lazy
 
@@ -117,52 +117,52 @@
                         val layoutInfo: LazyListLayoutInfo get() = object : LazyListLayoutInfo {}
                     }
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGI2Bijg0uSST8xLKcrPTKnQS87PLcgvTtVL
-        yy/NS0ksyczPAzLzhdhCUotLvEuUGLQYAJ1f4slDAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uSST8xLKcrPTKnQS87PLcgvTtVL
+        yy/NS0ksyczPAzLzhdhCUotLvEuUGLQYAAC6oXVDAAAA
         """,
         """
         androidx/compose/foundation/lazy/LazyListLayoutInfo.class:
-        H4sIAAAAAAAAAJ1OTU/CQBB9s9WC9auoJPgnLKCePHkxaVJjIokXTku7NQtl
-        17BbAp74XR4MZ3+UcYrxDziTvHnzkffm6/vjE8ANuoRraYqF1cUqye38zTqV
-        lLY2hfTamqSS7+skY8i085lc29qnprQtECGeyqXkC/OaPE2mKvctBIRONrO+
-        0iZ5VF6yirwjiPkyYDtqIGwABJrxfKWbrs+sGBC62007Ej0RiZhZ2dtuhqJP
-        zXJIuM3+8Sd7s1X8txh56dXVzBOika0XuXrQlSJcPtfG67l60U5PKnVvjPU7
-        WReyOfbwGwLnOzzDBdcBC+9zhmMEKVop2ikOEDHFYYojHI9BDic4HUM4xA6d
-        H5nueFN1AQAA
+        H4sIAAAAAAAA/51OTU/CQBB9syiF+lVUEvwTFlBOnryYNKkxkcRLT0u7mIWy
+        a9gtAU/8Lg+Gsz/KOMX4B5xJ3rz5yHvz9f3xCeAWXcKNNMXS6mId53bxZp2K
+        p7YyhfTamriU75s4ZUi186nc2MonZmoDECGayZXkC/MaP01mKvcBGoROOre+
+        1CZ+VF6yirwjiMWqwXZUQ7sGEGjO87Wuuz6zYkDo7ratUPREKCJm095uOxR9
+        qpdDwij9x5/szVbR32LspVfXc08Ix7Za5upBl4pw9VwZrxfqRTs9KdW9Mdbv
+        ZV2TzXGA3xC42OM5LrkOWPiQs5mhkSBI0ErQRsgURwmOcZKBHE5xlkE4RA6d
+        H25NYfx1AQAA
         """,
         """
         androidx/compose/foundation/lazy/LazyListState$layoutInfo$1.class:
-        H4sIAAAAAAAAAKVSS2/TQBD+xknr1rikLY8mvKEpanuomwLiUEBCFUiWDJUo
-        yiWnjb1Nt3F2kb2uWk75S5yQOKCc+VGI2YB43Apcvpn5PK+dz1++fvoM4CHu
-        E3aFzgqjstMoNaN3ppTRoal0JqwyOsrF+7MoYUhUaQ+ssLKdizNT2VgfmnbH
-        BxEWj8WJ4Ew9iPb7xzK1PmqEB+dum/xs6GOGMPtEaWWfEWrrG90QPuYC1DFP
-        qNsjVRKeJv+x8C5hKRkamysdvZJWcJVgzhud1Pge5GDWAQg0ZP5UuWibvaxD
-        WJmM54PJOPCa3iZNxnNBczLe8bbJfd4hPDr/Zr/ezNO3/u5BPlqEhYH8rQnh
-        8frGP00PcR03WMM/JmwNLZ97z2SS0EiUlq+rUV8Wb0U/Z2Y5ManIu6JQLv5B
-        hrHWstjLRVlKFqnxQqe5KZUe8JWPTEYIDkxVpPKlctmtN5W2aiS7qlRc/lxr
-        Y6d7lujAY7n5N5iKAKc/29vsRU4UtjObHxF8YMfDHafXlLyAu4zh9wSOQrZ1
-        3GMMmPOcpGhhdcpew020p/W3sMa2wxkLXHWxh1qMRozFGEtYZheXYlzGlR6o
-        xFWs9OCVzm1+A4nVJzVAAwAA
+        H4sIAAAAAAAA/6VSS2/TQBD+xknrxqSkLY8mvB8BtT3UTQFxKCChCiRLhkoU
+        5ZLTxt6m2zi7yF5XLaf8JU5IHFDO/CjErEE8bgUu38x8ntfO5y9fP30G8BD3
+        CTtCp7lR6UmYmMk7U8jwwJQ6FVYZHWbi/WkYM8SqsPtWWNnNxKkpbaQPTLfn
+        gwhLR+JYcKYehXvDI5lYHzXCgzO3jX829DFHmH+itLLPCLW19X4TPhYC1NEg
+        1O2hKghP4/9YeIewHI+NzZQOX0kruEow502Oa3wPctBwAAKNmT9RLtpiL+0R
+        VmfTRjCbBl7b26DZdCFoz6bb3ha5z9uER2ff7Nebefrm3z3IR4ewOJK/NSE8
+        Xlv/p+lNXMU11vCPCZtjy+feNakktGKl5etyMpT5WzHMmFmJTSKyvsiVi3+Q
+        zUhrme9moigki9R6oZPMFEqP+MqHJiUE+6bME/lSuezOm1JbNZF9VSguf661
+        sdWeBXrwWG7+DSoR4PRne5O90InCdm7jI4IP7Hi4xThfkedwm7H5PYGjJts6
+        7jAGzHlOUnRwt2Kv4Dq6Vf0N3GPb44xFrjo/QC1CK8JShGWssIsLES7i0gBU
+        4DJWB/AK57a/AQF0+xNAAwAA
         """,
         """
         androidx/compose/foundation/lazy/LazyListState.class:
-        H4sIAAAAAAAAAJ1TS08UQRD+evbJ7AKzKLo8FBVUQGUWlGiCMVESkkkGSMBs
-        YjjN7vZis7M9ZrqXgCd+i2cPeiLRxGw8+qOM1cOGlxyAOdTj6/qqqqum//z9
-        8QvAC8wxzAWyEUeisefWo/anSHG3GXVkI9Aikm4YfN53fRK+UHpTB5rnwBic
-        nWA3oEO57a7Xdnhd55BiyL4WUug3DKnpmWoRGWRtpJFjSOuPQjFU/KuVWmIo
-        b3O9ImKlq0KJWsg9zduebPC9pIjHMHFBwGY9jsJwvdlUXDP0U4Qf7Ecd7clm
-        xPByeubyfZwQqZlJP4q33R2ua3EgpHIDKSOdkJS7Fum1ThhS1NLVLjkVHpeY
-        ms+hZGPIjOz5NVrM4SZDyW9FOhTSXeU6oPiAWrLauylaNzMiawQYWIvwPWG8
-        ClmNeYZW92DctsqWbTndA9vKGyNPOnME5q1y92DBqrB3md9fspZjbZSc1KhV
-        Sb9aIT87ms5nnCxhuTNYPsH6CLOPsYJTNCUXmGlkuHnxfsfP42fXaoendrp4
-        zY06Z1Yx16K86eWowRkGfSH5Wqdd4/H7gBpgGPKjehBWg1gYvweObXSkFm3u
-        yd2jRt+e/BMMRU9KHi+HgVKcXHsz6sR1viIMc6THrP7HwzwsejfmS9N86BmR
-        fEyea9ZGOjN7iPx3MixMm40mYB4zJItHAeiDTbqEQoIY8tMe2Up9PcfsO8W0
-        jpn9l2DaFzIHMEieYS6SNmeFnxj6cIgbXQx/O5eicCpFoZditnfqkE7hSVKI
-        5p9MZITaMRke4RnpDcJv0XVvbyHloexhxMMoxsjEuIc7uLsFpjCBe1voV7AV
-        7itkFR4kRkGhqDCpzNGUwkOFAYXBf29R2u4bBQAA
+        H4sIAAAAAAAA/51TS08UQRD+evY9u8gsii4PRQUVUJkFJZpgTJSEZJIREjCb
+        GE6zu73Y7GyPme4l4Inf4tmDnkg0MRuP/ihj9bDhJQdgDvX4ur6q6qrpP39/
+        /ALwHHMMc4FsxpFo7rqNqPMpUtxtRV3ZDLSIpBsGn/dcn4QvlN7QgeY5MAZn
+        O9gJ6FBuuWv1bd7QOaQYsq+EFPo1Q2p6plZCBlkbaeQY0vqjUAxV/3Kllhgq
+        W1yviFjpmlCiHnJP844nm3w3KeIxTJwTsNGIozBca7UU1wwDFOEHe1FXe7IV
+        MbyYnrl4H8dEambSj+Itd5vrehwIqdxAykgnJOWuRnq1G4YUtXS5S06FRyWm
+        5nMo2xgyI3t2hRZzuMFQ9tuRDoV033EdUHxALVmdnRStmxlRMAIMrE34rjBe
+        lazmPEO7tz9uWxXLtpzevm3ljZEnnTkE81alt79gVdnbzO8vWcux1stOatSq
+        pl+ukJ8dTeczTpaw3Cksn2AFwuwjrOiUTMkFZhoZbp2/3/Gz+Om12uGJnS5e
+        caPOqVXMtSlvejlqcoZBX0i+2u3Uefw+oAYYhvyoEYS1IBbG74Nj612pRYd7
+        cuew0TfH/wRDyZOSx8thoBQn196IunGDrwjDHOkza//xMA+L3o350jQfekYk
+        H5HnmrWRzsweIP+dDAvTJLMJmMcMydJhAAqwSZdRTBBDftInW6mvZ5iFE0zr
+        iDlwAaZ9LvMaBskzzEXS5qz4E0MfDnC9h+FvZ1IUT6Qo9lPM9k8d0ik8TgrR
+        /JOJjFA7JsNDPCW9TvhNuu6tTaQ8VDyMeBjFGJkY93AbdzbBFCZwdxMDCrbC
+        PYWswv3EKCqUFCaVOZpSeKBwTWHwHwU6zXobBQAA
         """
     )
 
diff --git a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt
index 6b70cb7..0eb8d9a 100644
--- a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt
+++ b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt
@@ -23,6 +23,7 @@
 import com.android.tools.lint.checks.infrastructure.TestFile
 import com.android.tools.lint.detector.api.Detector
 import com.android.tools.lint.detector.api.Issue
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -216,6 +217,7 @@
     override fun getIssues(): MutableList<Issue> =
         mutableListOf(NonLambdaOffsetModifierDetector.UseOfNonLambdaOverload)
 
+    @Ignore("b/309832115")
     @Test
     fun lambdaOffset_simpleUsage_shouldNotWarn() {
         lint().files(
@@ -251,6 +253,7 @@
             .expectClean()
     }
 
+    @Ignore("b/309832115")
     @Test
     fun lambdaOffset_withStateUsages_shouldNotWarn() {
         lint().files(
@@ -300,6 +303,7 @@
             .expectClean()
     }
 
+    @Ignore("b/309832115")
     @Test
     fun lambdaOffset_withAnimatableUsage_shouldNotWarn() {
         lint().files(
@@ -354,6 +358,7 @@
             .expectClean()
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingVariableDp_shouldNotWarn() {
         lint().files(
@@ -397,6 +402,7 @@
             .expectClean()
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingPassedStaticArguments_shouldNotWarn() {
         lint().files(
@@ -433,6 +439,7 @@
 
     // State tests
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateLocalVariable_shouldWarn() {
         lint().files(
@@ -479,6 +486,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingDelegatedStateVariable_shouldWarn() {
         lint().files(
@@ -526,6 +534,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateReceiver_shouldWarn() {
         lint().files(
@@ -584,6 +593,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingTopLevelStateVariables_shouldWarn() {
         lint().files(
@@ -630,6 +640,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingClassPropertiesState_shouldWarn() {
         lint().files(
@@ -678,6 +689,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingLambdaMethodWithState_shouldWarn() {
         lint().files(
@@ -724,6 +736,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateArgumentsHoisted_shouldWarn() {
         lint().files(
@@ -769,6 +782,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateVariableWithSecondaryMethodCallNoStateInSignature_shouldWarn() {
         lint().files(
@@ -821,6 +835,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateVariableWithSecondaryMethodCallStateInSignature_shouldWarn() {
         lint().files(
@@ -874,6 +889,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingDelegatedStateVariableWithComplexExpression_shouldWarn() {
         lint().files(
@@ -923,6 +939,7 @@
 
     // Animatable tests
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableArgumentsLocalVariable_shouldWarn() {
         lint().files(
@@ -968,6 +985,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableArgumentsHoisted_shouldWarn() {
         lint().files(
@@ -1012,6 +1030,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableReceiver_shouldWarn() {
         lint().files(
@@ -1071,6 +1090,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingLambdaMethodWithAnimatable_shouldWarn() {
         lint().files(
@@ -1118,6 +1138,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingTopLevelAnimatableVariables_shouldWarn() {
         lint().files(
@@ -1165,6 +1186,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingClassPropertiesAnimatable_shouldWarn() {
         lint().files(
@@ -1214,6 +1236,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableVariableWithComplexExpression_shouldWarn() {
         lint().files(
@@ -1259,6 +1282,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_animatableVariableWithSecondaryMethodCallNoStateInSignature_shouldWarn() {
         lint().files(
@@ -1311,6 +1335,7 @@
             )
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableArgumentsWithMethodCallStateInSignature_shouldWarn() {
         lint().files(
@@ -1365,6 +1390,7 @@
 
     // Non modifier related tests
 
+    @Ignore("b/309832115")
     @Test
     fun nonModifierOffset_bytecode_shouldNotWarn() {
         lint().files(
@@ -1389,6 +1415,7 @@
             .expectClean()
     }
 
+    @Ignore("b/309832115")
     @Test
     fun nonModifierOffsetKotlin_shouldNotWarn() {
         lint().files(
diff --git a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/UnrememberedMutableInteractionSourceDetectorTest.kt b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/UnrememberedMutableInteractionSourceDetectorTest.kt
index c59797b..a1a3bf9 100644
--- a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/UnrememberedMutableInteractionSourceDetectorTest.kt
+++ b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/UnrememberedMutableInteractionSourceDetectorTest.kt
@@ -32,7 +32,7 @@
     private val InteractionSourceStub: TestFile = bytecodeStub(
         filename = "InteractionSource.kt",
         filepath = "androidx/compose/foundation/interaction",
-        checksum = 0x7b8a9d44,
+        checksum = 0xac2a176d,
         source = """
         package androidx.compose.foundation.interaction
 
@@ -46,54 +46,54 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgsuNST8xLKcrPTKnQS87PLcgvTtVL
-        yy/NS0ksyczP08vMK0ktSkwGsYWEPRGc4PzSouRU7xIuNS4JDP1FpXklmbmp
-        QlxBqbmpuUmpRUB1fFwsJanFJUJsIUDSu0SJQYsBAEnB5baQAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuNST8xLKcrPTKnQS87PLcgvTtVL
+        yy/NS0ksyczP08vMK0ktSkwGsYWEPRGc4PzSouRU7xIubi6WktTiEiHmeO8S
+        JQYtBgD0QcfwZQAAAA==
         """,
         """
         androidx/compose/foundation/interaction/InteractionSource.class:
-        H4sIAAAAAAAA/52OP0/DMBDF3znQhPAvhVYqX4K0FQvqxIIUqQgJJJZMbuIi
-        N4mNYqfq2M/VAXXmQyGcdGBg4yw9/+5Ouve+vnefAO4wJNxzldda5ps409WH
-        NiJe6kbl3EqtYqmsqHnWcfLLr7qpM+GDCNGKr3lccvUePy9WIrM+PEJ/Xmhb
-        ShU/CcvdLT4jsGrtOVNqJWgFBCrcfCPbbuwonxCG+20QshELWeRoOdpvp2xM
-        7XJKmM3/ndYlcIaDP/PbwhLCAz/KUhBuXhplZSXepJGLUjwopW1nYHouBo5w
-        KIbrTq8wcP/EHT92r5fCS+AnCBKcIHSI0wRnOE9BBhe4TMEMIoP+DyYeb+yF
+        H4sIAAAAAAAA/52OP0/DMBDF3znQtOFfCq1UvgRuKxbUiQUpUhESSCyZ3MRF
+        bhIbxW7VsZ+LAXXmQyGcdGBg4yw9/+5Ouve+vj8+AdxiSLgTOq+Nyrc8M9W7
+        sZIvzVrnwimjudJO1iJrOfnlF7OuMxmCCPFKbAQvhX7jT4uVzFyIgNCfF8aV
+        SvNH6YS/JWYEVm0Cb0qN9BoBgQo/36qmG3vKJ4ThfteN2IhFLPa0HO13Uzam
+        ZjklzOb/TusTeMPBn/lN4QjRgR9UKQnXz2vtVCVflVWLUt5rbVxrYDs+Bo5w
+        KIarVi8x8P/EHz/2r5MiSBAm6CboIfKIkwSnOEtBFue4SMEsYov+D8H/p5CF
         AQAA
         """,
         """
         androidx/compose/foundation/interaction/InteractionSourceKt.class:
-        H4sIAAAAAAAA/61R30sbQRD+5qIXPW2NP5vE/s6Lvnim+GaRtkrhaJpCW4SS
-        p01uK5vc7crdXvAxf1LfBAXJc/8ocTYKPoSCYPdh5pvZb77Znfl7fXEFYA8N
-        wr7QcWZUfBb2THpqchn+NoWOhVVGh0pbmYneBEf3+Icpsp78YssgQqUvhiJM
-        hD4Jv3X7ssfZEqH6tbCim8ipKsLR1nbroU3/pbJPaLRMdhL2pe1mQuk8FFob
-        O1HIw7ax7SJJmHX02E5RepqUMUfw3yut7AGhtLV9vIgACwHmsUj48NgWZTwl
-        LLcGxiaKWdIKLhb8eC8dlnhP5MycMyDQwAGPL8+UQ7uM4iZhdTzyg/Eo8Kpe
-        3a+MR3Vvl9zVO8Kn/zHutankzsASZg5NzDtdaikt20XaldlPp0DY/F5oq1LW
-        Gqpccerj/X4Iwa3EZ+WotTvq8RQRTXiYwe3Pa5iFz/FLjhrs3Vm4xPyvczwZ
-        Y+nPhPSKrc+eB4bXd7jsBoY3E/sCb9k3OVthueUOShFWIqxGWMN6hA08i1BF
-        rQPKUcdmB16O2RzPbwCz5fAqMwMAAA==
+        H4sIAAAAAAAA/61R308TQRD+5gpXevwqAtoWRbAv8OJR4xvGqBCSi7UmakhM
+        n7a9lWx7t0vu9hoe+yf5ZqIJ6bN/lHG2kPDQkJDAPsx8M/vNN7szf//9vgTw
+        Gk3CodBxZlR8EfZNem5yGf4whY6FVUaHSluZif4URzf4qymyvvxoyyBCdSBG
+        IkyEPgs/9wayz9kSofapsKKXyJkqwvHefvuuTW9TOSQ02yY7CwfS9jKhdB4K
+        rY2dKuRhx9hOkSTMOr5vpyg9T8pYIPhvlFb2LaG0t3+6hACLASpYIry7b4sy
+        Vghr7aGxiWKWtIKLBT/eS0cl3hM5U3EGBBo64PHlhXLogFHcIqxPxn4wGQde
+        zWv41cm44R2Qu3pF+PAQ496YSb4cWsLckYl5p6ttpWWnSHsy++YUCFtfCm1V
+        ylojlStOvb/ZDyG4kjhRjlq/pp7OENGChzlc/byOefgcb3PUZO/O4h9Uvv/C
+        8gSrP6ek52x99sACdq5x2Q0Mu1P7DC/YtzhbZbm1LkoRHkVYj7CBzQiP8SRC
+        DfUuKEcDW114OeZzPP0PDZ9NFzMDAAA=
         """,
         """
         androidx/compose/foundation/interaction/MutableInteractionSource.class:
-        H4sIAAAAAAAA/6VQvU7DMBi8L4E2hL8WApSXIG3VBXUBBqRIRUggsXRyExe5
-        SWyUOFXHPhcD6sxDIb6UgYEOlRh8Pp/1ne/8+fX+AWCAC8KN0ElhVLIIY5O/
-        mVKGU1PpRFhldKi0lYWI1/yhsmKSyehXejZVEcsmiNCaibkIM6Ffw8fJTMa2
-        CZdwva33BtNdQnuUGpspflpawVNiSHDyucvRqQavBhAoZX2h6lOXWdIjBKul
-        5zsdp17etLNa9p0u1Xd9wt3ov5U5x3Brk03TwR/xKrUE/4ffq0wSLp8qbVUu
-        X1SpOMSt1sau3csGF8EOF2/U/ZmfrTHAOe891vn34I3hRtiL4EfYxwFTHEY4
-        wvEYVKKF9hhOiZMSp9/lIS6TDgIAAA==
+        H4sIAAAAAAAA/6VQvU7DMBi8L4E2DX8tBCgvQdqKBXUBBqRIRUggsWRyExe5
+        SW3UOFXHPhcD6sxDIb6EgYEOlRh8Pp/1ne/8+fX+AeAK54QbodO5UekyTMzs
+        zRQynJhSp8Iqo0OlrZyLpOYPpRXjXEa/0rMp54lsggjtqViIMBf6NXwcT2Vi
+        m3AJ19t6bzDdJXRGmbG54qelFTwlhgRntnA5OlXQqgAEylhfqurUY5b2CcF6
+        5flO16mWN+muVwOnR9XdgHA3+m9lzjHc2mTTdPBHvMwswf/h9yqXhIunUls1
+        ky+qUBziVmtja/eiwUWww8UbVX/mpzUGOOO9zzr/HrwYboRWBD/CHvaZ4iDC
+        IY5iUIE2OjGcAscFTr4BtDhpnA4CAAA=
         """,
         """
         androidx/compose/foundation/interaction/MutableInteractionSourceImpl.class:
-        H4sIAAAAAAAA/61Sy04bMRQ91yGPTgMESiG0PLa0i06KugNVvIQ0UgpSi7Jh
-        5cy4xWTGRjMexDLf0j/oColFFXXJR1VcTyp1wRIWPjrn3Ieur33/9+43gE/Y
-        JBxJk+RWJzdhbLMrW6jwuy1NIp22JtTGqVzGFf9SOjlMVfTf+mbLPFZRdpU2
-        QYTOpbyWYSrNj/B0eKli10SNsPfU/k3UCY1dbbT7TKhtvRu00UQrwAxeEGbc
-        hS4Ix/3nuMYOYaE/si7VnKec5HLJnsiua7wu8tDyAAKN2L/RXvWYJR8Jm5Nx
-        EIiuqM5k3BLdyXhb9Oig/udnQ3SET9smHDx5VB5p6ZH5YeR4G4c2UYT5vjbq
-        pMyGKj/zHQiLfRvLdCBz7fU/M5hWHmsvVr+WxulMDXShObpvjHXVSAV6ELxs
-        foTpzf32Gd+wCisN1N/fIvjFROAtY6MyA6wxtqcJeMnMx9crXMVG9QEJsxyb
-        O0ctwnyEToQFLDLFqwhLeH0OKrCMFY4XaBfoFmg9AJ+La3K9AgAA
+        H4sIAAAAAAAA/61Sy04bMRQ91yEPpqEEyiO0ULa0i06KugOhFhDSSGkrFZQN
+        K2fGUJMZG814EMt8S/+AFRILFLHsR6FeT5C66JIufHTOuQ9dX/v34909gE/Y
+        JBxKk+RWJ9dhbLNLW6jwzJYmkU5bE2rjVC7jin8tnRymKvprHdsyj1WUXaZN
+        EKFzIa9kmEpzHn4fXqjYNVEjfH5u/ybqhMauNtrtEWpb7wZtNNEKMINZwoz7
+        qQvCUf9/XGOHsNAfWZdqzlNOcrlkT2RXNV4XeZj1AAKN2L/WXvWYJR8Jm5Nx
+        EIiuqM5k3BLdyXhb9Gi//vCrITrCp20T9p89Ko+09I/5YeR4Gwc2UYT5vjbq
+        W5kNVX7iOxAW+zaW6UDm2usnM5hWHmkv1n6UxulMDXShOfrFGOuqkQr0IHjZ
+        /AjTm/vtM75mFVYaqL+/RXDDROANY6MyA6wztqcJeMHMxzcqXMPb6gMS5jj2
+        8hS1CPMROhEWsMgUryIsYfkUVGAFqxwv0C7QLdD6A/UGq929AgAA
         """
     )
 
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index 73fdc49..8633904 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -31,16 +31,16 @@
   }
 
   public final class BasicMarqueeKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeDelayMillis();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeIterations();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static float getDefaultMarqueeVelocity();
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeDelayMillis;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeIterations;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final float DefaultMarqueeVelocity;
+    method public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
+    method public static int getDefaultMarqueeDelayMillis();
+    method public static int getDefaultMarqueeIterations();
+    method public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
+    method public static float getDefaultMarqueeVelocity();
+    property public static final int DefaultMarqueeDelayMillis;
+    property public static final int DefaultMarqueeIterations;
+    property public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
+    property public static final float DefaultMarqueeVelocity;
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class BasicTooltipDefaults {
@@ -147,11 +147,11 @@
   }
 
   @androidx.compose.runtime.Stable public interface Indication {
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public default androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
-  public interface IndicationInstance {
-    method public void drawIndication(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
+  @Deprecated public interface IndicationInstance {
+    method @Deprecated public void drawIndication(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
   }
 
   public final class IndicationKt {
@@ -160,6 +160,12 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> LocalIndication;
   }
 
+  @androidx.compose.runtime.Stable public interface IndicationNodeFactory extends androidx.compose.foundation.Indication {
+    method public androidx.compose.ui.node.DelegatableNode create(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method public boolean equals(Object? other);
+    method public int hashCode();
+  }
+
   @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
   }
 
@@ -167,24 +173,24 @@
     method public static androidx.compose.ui.Modifier magnifier(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> sourceCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset>? magnifierCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.DpSize,kotlin.Unit>? onSizeChanged, optional float zoom, optional long size, optional float cornerRadius, optional float elevation, optional boolean clip);
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
+  @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
     field public static final androidx.compose.foundation.MarqueeAnimationMode.Companion Companion;
   }
 
   public static final class MarqueeAnimationMode.Companion {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public int getImmediately();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public int getWhileFocused();
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final int Immediately;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final int WhileFocused;
+    method public int getImmediately();
+    method public int getWhileFocused();
+    property public final int Immediately;
+    property public final int WhileFocused;
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
+  @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
+    method public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
     field public static final androidx.compose.foundation.MarqueeSpacing.Companion Companion;
   }
 
   public static final class MarqueeSpacing.Companion {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
+    method public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
   }
 
   public enum MutatePriority {
@@ -1181,8 +1187,8 @@
   }
 
   public final class PagerKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerLayoutInfo {
@@ -1193,6 +1199,7 @@
     method public int getPageSize();
     method public int getPageSpacing();
     method public boolean getReverseLayout();
+    method public androidx.compose.foundation.gestures.snapping.SnapPosition getSnapPosition();
     method public int getViewportEndOffset();
     method public long getViewportSize();
     method public int getViewportStartOffset();
@@ -1204,6 +1211,7 @@
     property public abstract int pageSize;
     property public abstract int pageSpacing;
     property public abstract boolean reverseLayout;
+    property public abstract androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition;
     property public abstract int viewportEndOffset;
     property public abstract long viewportSize;
     property public abstract int viewportStartOffset;
@@ -1254,6 +1262,7 @@
   }
 
   public final class PagerStateKt {
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.pager.PagerState PagerState(optional int currentPage, optional float currentPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
   }
 
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index 4bc8b44..3f5571d 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -31,16 +31,16 @@
   }
 
   public final class BasicMarqueeKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeDelayMillis();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeIterations();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static float getDefaultMarqueeVelocity();
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeDelayMillis;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeIterations;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static final float DefaultMarqueeVelocity;
+    method public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
+    method public static int getDefaultMarqueeDelayMillis();
+    method public static int getDefaultMarqueeIterations();
+    method public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
+    method public static float getDefaultMarqueeVelocity();
+    property public static final int DefaultMarqueeDelayMillis;
+    property public static final int DefaultMarqueeIterations;
+    property public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
+    property public static final float DefaultMarqueeVelocity;
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class BasicTooltipDefaults {
@@ -147,11 +147,11 @@
   }
 
   @androidx.compose.runtime.Stable public interface Indication {
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public default androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
   }
 
-  public interface IndicationInstance {
-    method public void drawIndication(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
+  @Deprecated public interface IndicationInstance {
+    method @Deprecated public void drawIndication(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
   }
 
   public final class IndicationKt {
@@ -160,6 +160,12 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> LocalIndication;
   }
 
+  @androidx.compose.runtime.Stable public interface IndicationNodeFactory extends androidx.compose.foundation.Indication {
+    method public androidx.compose.ui.node.DelegatableNode create(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method public boolean equals(Object? other);
+    method public int hashCode();
+  }
+
   @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
   }
 
@@ -167,24 +173,24 @@
     method public static androidx.compose.ui.Modifier magnifier(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> sourceCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset>? magnifierCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.DpSize,kotlin.Unit>? onSizeChanged, optional float zoom, optional long size, optional float cornerRadius, optional float elevation, optional boolean clip);
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
+  @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
     field public static final androidx.compose.foundation.MarqueeAnimationMode.Companion Companion;
   }
 
   public static final class MarqueeAnimationMode.Companion {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public int getImmediately();
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public int getWhileFocused();
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final int Immediately;
-    property @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final int WhileFocused;
+    method public int getImmediately();
+    method public int getWhileFocused();
+    property public final int Immediately;
+    property public final int WhileFocused;
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
+  @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
+    method public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
     field public static final androidx.compose.foundation.MarqueeSpacing.Companion Companion;
   }
 
   public static final class MarqueeSpacing.Companion {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
+    method public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
   }
 
   public enum MutatePriority {
@@ -1183,8 +1189,8 @@
   }
 
   public final class PagerKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerLayoutInfo {
@@ -1195,6 +1201,7 @@
     method public int getPageSize();
     method public int getPageSpacing();
     method public boolean getReverseLayout();
+    method public androidx.compose.foundation.gestures.snapping.SnapPosition getSnapPosition();
     method public int getViewportEndOffset();
     method public long getViewportSize();
     method public int getViewportStartOffset();
@@ -1206,6 +1213,7 @@
     property public abstract int pageSize;
     property public abstract int pageSpacing;
     property public abstract boolean reverseLayout;
+    property public abstract androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition;
     property public abstract int viewportEndOffset;
     property public abstract long viewportSize;
     property public abstract int viewportStartOffset;
@@ -1256,6 +1264,7 @@
   }
 
   public final class PagerStateKt {
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.pager.PagerState PagerState(optional int currentPage, optional float currentPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
     method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
   }
 
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyBenchmarkCommon.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyBenchmarkCommon.kt
index dd07ebf..91f72a39 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyBenchmarkCommon.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyBenchmarkCommon.kt
@@ -24,6 +24,7 @@
 import androidx.compose.testutils.ComposeTestCase
 import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
 import androidx.compose.testutils.doFramesUntilNoChangesPending
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.platform.ViewRootForTest
 
@@ -106,14 +107,7 @@
                 }
                 assertNoPendingRecompositionMeasureOrLayout()
             }
-            getTestCase().toggle()
-            if (hasPendingChanges()) {
-                recompose()
-            }
-            if (hasPendingMeasureOrLayout()) {
-                measure()
-                layout()
-            }
+            performToggle(getTestCase())
             runWithTimingDisabled {
                 assertNoPendingRecompositionMeasureOrLayout()
                 getTestCase().afterToggle()
@@ -123,6 +117,19 @@
     }
 }
 
+// we extract this function so it is easier to differentiate this work  in the traces from the work
+// we are not measuring, like beforeToggle() and afterToggle().
+@OptIn(ExperimentalComposeUiApi::class)
+private fun ComposeExecutionControl.performToggle(testCase: LazyBenchmarkTestCase) {
+    testCase.toggle()
+    if (hasPendingChanges()) {
+        recompose()
+    }
+    if (hasPendingMeasureOrLayout()) {
+        getViewRoot().measureAndLayoutForTest()
+    }
+}
+
 private fun ComposeExecutionControl.assertNoPendingRecompositionMeasureOrLayout() {
     if (hasPendingChanges() || hasPendingMeasureOrLayout()) {
         throw AssertionError("Expected no pending changes but there were some.")
@@ -130,9 +137,12 @@
 }
 
 private fun ComposeExecutionControl.hasPendingMeasureOrLayout(): Boolean {
-    return (getHostView() as ViewRootForTest).hasPendingMeasureOrLayout
+    return getViewRoot().hasPendingMeasureOrLayout
 }
 
+private fun ComposeExecutionControl.getViewRoot(): ViewRootForTest =
+    getHostView() as ViewRootForTest
+
 // TODO(b/169852102 use existing public constructs instead)
 internal fun ComposeBenchmarkRule.toggleStateBenchmarkDraw(
     caseFactory: () -> LazyBenchmarkTestCase
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt
index ca748ac..1f68d41 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt
@@ -46,7 +46,6 @@
 import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
 import org.junit.Assume
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -60,7 +59,6 @@
     @get:Rule
     val benchmarkRule = ComposeBenchmarkRule()
 
-    @Ignore("b/311256618")
     @Test
     fun scrollProgrammatically_noNewItems() {
         benchmarkRule.toggleStateBenchmark {
@@ -83,7 +81,6 @@
         }
     }
 
-    @Ignore("b/311256618")
     @Test
     fun scrollProgrammatically_noNewItems_withoutKeys() {
         benchmarkRule.toggleStateBenchmark {
@@ -108,7 +105,6 @@
         }
     }
 
-    @Ignore("b/311256618")
     @Test
     fun scrollViaPointerInput_noNewItems() {
         benchmarkRule.toggleStateBenchmark {
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt
index c5122ee..11a55c8 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt
@@ -20,6 +20,7 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxHeight
@@ -37,6 +38,7 @@
 import androidx.compose.integration.demos.common.ComposableDemo
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -44,25 +46,75 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 
+@OptIn(ExperimentalFoundationApi::class)
 val Carrousel = listOf(
     ComposableDemo("Horizontal") { HorizontalCarrouselDemo() },
     ComposableDemo("Vertical") { VerticalCarrouselDemo() },
     ComposableDemo("3 pages per viewport") { HorizontalCustomPageSizeDemo() },
     ComposableDemo("Max Scroll = 3 pages") {
         HorizontalCustomPageSizeWithCustomMaxScrollDemo()
-    },
+    }
+)
+
+@OptIn(ExperimentalFoundationApi::class)
+val SnapPositionDemos = listOf(
+    ComposableDemo("Snap Position - Start") { HorizontalCarrouselDemo(SnapPosition.Start) },
+    ComposableDemo("Snap Position - Center") { HorizontalCarrouselDemo(SnapPosition.Center) },
+    ComposableDemo("Snap Position - End") { HorizontalCarrouselDemo(SnapPosition.End) },
+    ComposableDemo("Snap Position - Custom") { HorizontalCarrouselDemoWithCustomSnapPosition() },
 )
 
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
-private fun HorizontalCarrouselDemo() {
+private fun HorizontalCarrouselDemoWithCustomSnapPosition() {
+    val pagerState = rememberPagerState { PagesCount }
+
+    val snapPosition = remember {
+        SnapPosition { layoutSize, itemSize, beforeContentPadding, afterContentPadding, pageIndex ->
+            val availableLayoutSpace = layoutSize - beforeContentPadding - afterContentPadding
+            when (pageIndex) {
+                0 -> 0
+                PagesCount - 2 -> availableLayoutSpace - itemSize
+                else -> availableLayoutSpace / 2 - itemSize / 2
+            }
+        }
+    }
+
+    val pageSize = remember {
+        object : PageSize {
+            override fun Density.calculateMainAxisPageSize(
+                availableSpace: Int,
+                pageSpacing: Int
+            ): Int {
+                return (availableSpace + pageSpacing) / 2
+            }
+        }
+    }
+
+    Column(modifier = Modifier.fillMaxSize()) {
+        HorizontalPager(
+            modifier = Modifier,
+            state = pagerState,
+            pageSize = pageSize,
+            snapPosition = snapPosition
+        ) {
+            CarrouselItem(it, Orientation.Vertical)
+        }
+        PagerControls(Modifier.weight(0.1f), pagerState)
+    }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+private fun HorizontalCarrouselDemo(snapPosition: SnapPosition = SnapPosition.Start) {
     val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier,
             state = pagerState,
-            pageSize = PageSize.Fixed(200.dp)
+            pageSize = PageSize.Fixed(100.dp),
+            snapPosition = snapPosition
         ) {
             CarrouselItem(it, Orientation.Vertical)
         }
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt
index c0e3211d..f56d4e1 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt
@@ -67,7 +67,8 @@
 val PagerDemos = listOf(
     DemoCategory("Simple", SimplePager),
     DemoCategory("Carrousel", Carrousel),
-    DemoCategory("State Interactions", PagerStateInteractions)
+    DemoCategory("State Interactions", PagerStateInteractions),
+    DemoCategory("Snap Position", SnapPositionDemos),
 )
 
 @OptIn(ExperimentalFoundationApi::class)
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/BrushDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/BrushDemo.kt
index 1405a4a..32edcc8 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/BrushDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/BrushDemo.kt
@@ -34,8 +34,13 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.geometry.center
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RadialGradientShader
+import androidx.compose.ui.graphics.Shader
+import androidx.compose.ui.graphics.ShaderBrush
 import androidx.compose.ui.graphics.Shadow
 import androidx.compose.ui.graphics.TileMode
 import androidx.compose.ui.text.ExperimentalTextApi
@@ -206,14 +211,22 @@
             repeatMode = RepeatMode.Reverse
         )
     )
+    val brush = remember {
+        // postpone the state read to shader creation time which happens during draw.
+        ShaderBrush { size ->
+            RadialGradientShader(
+                center = size.center,
+                radius = radius,
+                colors = RainbowColors,
+                colorStops = RainbowStops,
+                tileMode = TileMode.Mirror
+            )
+        }
+    }
     Text(
         text = loremIpsum(wordCount = 29),
         style = TextStyle(
-            brush = Brush.radialGradient(
-                *RainbowStops.zip(RainbowColors).toTypedArray(),
-                radius = radius,
-                tileMode = TileMode.Mirror
-            ),
+            brush = brush,
             fontSize = 30.sp
         )
     )
@@ -264,3 +277,9 @@
     Color(0xff2aa8f2)
 )
 private val RainbowStops = listOf(0f, 0.2f, 0.4f, 0.6f, 0.8f, 1f)
+
+private fun ShaderBrush(block: (Size) -> Shader): ShaderBrush {
+    return object : ShaderBrush() {
+        override fun createShader(size: Size): Shader = block(size)
+    }
+}
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt
index ce2ce25..6ab2353 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/IndicationSamples.kt
@@ -26,7 +26,6 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.material.Text
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
@@ -40,10 +39,10 @@
         Text(
             text = "Click me and my neighbour will indicate as well!",
             modifier = Modifier
-                // clickable will dispatch events using MutableInteractionSource and show ripple
+                // clickable will dispatch events using MutableInteractionSource
                 .clickable(
                     interactionSource = interactionSource,
-                    indication = rememberRipple()
+                    indication = LocalIndication.current
                 ) {
                     /**do something */
                 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/BasicMarqueeTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/BasicMarqueeTest.kt
index ed67719..9cc7e7a 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/BasicMarqueeTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/BasicMarqueeTest.kt
@@ -922,6 +922,7 @@
             focusManager = LocalFocusManager.current
             TestMarqueeContent(
                 Modifier
+                    .focusable() // extra focusable for initial focus.
                     .basicMarqueeWithTestParams(animationMode = WhileFocused)
                     .focusRequester(focusRequester)
                     .focusable()
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt
index 56d0bec..4c72289 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt
@@ -81,7 +81,9 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
 import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Correspondence
 import com.google.common.truth.Truth.assertThat
+import kotlin.reflect.KClass
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 import org.junit.After
@@ -97,6 +99,11 @@
     @get:Rule
     val rule = createComposeRule()
 
+    private val InstanceOf = Correspondence.from<Any, KClass<*>>(
+        { obj, clazz -> clazz?.isInstance(obj) ?: false },
+        "is an instance of"
+    )
+
     @Before
     fun before() {
         isDebugInspectorInfoEnabled = true
@@ -1054,22 +1061,19 @@
         val focusRequester = FocusRequester()
         lateinit var focusManager: FocusManager
         lateinit var inputModeManager: InputModeManager
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             focusManager = LocalFocusManager.current
             inputModeManager = LocalInputModeManager.current
-                Box {
-                    BasicText(
-                        "ClickableText",
-                        modifier = Modifier
-                            .testTag("myClickable")
-                            .focusRequester(focusRequester)
-                            .clickable(
-                                interactionSource = interactionSource,
-                                indication = null
-                            ) {}
-                    )
-                }
+            Box {
+                BasicText(
+                    "ClickableText",
+                    modifier = Modifier
+                        .testTag("myClickable")
+                        .focusRequester(focusRequester)
+                        .clickable(interactionSource = interactionSource, indication = null) {}
+                )
+            }
         }
         rule.runOnIdle {
             @OptIn(ExperimentalComposeUiApi::class)
@@ -1092,8 +1096,9 @@
 
         // Keyboard mode, so we should now be focused and see an interaction
         rule.runOnIdle {
-            assertThat(interactions).hasSize(1)
-            assertThat(interactions.first()).isInstanceOf(FocusInteraction.Focus::class.java)
+            assertThat(interactions)
+                .comparingElementsUsing(InstanceOf)
+                .containsExactly(FocusInteraction.Focus::class)
         }
 
         rule.runOnIdle {
@@ -1101,12 +1106,12 @@
         }
 
         rule.runOnIdle {
-            assertThat(interactions).hasSize(2)
-            assertThat(interactions.first()).isInstanceOf(FocusInteraction.Focus::class.java)
-            assertThat(interactions[1])
-                .isInstanceOf(FocusInteraction.Unfocus::class.java)
-            assertThat((interactions[1] as FocusInteraction.Unfocus).focus)
-                .isEqualTo(interactions[0])
+            // TODO(b/308811852): Simplify the other assertions in FocusableTest, ClickableTest and
+            //  CombinedClickable by using InstanceOf (like we do here).
+            assertThat(interactions)
+                .comparingElementsUsing(InstanceOf)
+                .containsExactly(FocusInteraction.Focus::class, FocusInteraction.Unfocus::class)
+                .inOrder()
         }
     }
 
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt
index 3c6d481..0defe94 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/CombinedClickableTest.kt
@@ -1298,7 +1298,7 @@
         val focusRequester = FocusRequester()
         lateinit var focusManager: FocusManager
         lateinit var inputModeManager: InputModeManager
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             focusManager = LocalFocusManager.current
             inputModeManager = LocalInputModeManager.current
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt
index 46b4931..80b1504 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt
@@ -97,7 +97,7 @@
 
     @Test
     fun focusable_defaultSemantics() {
-        rule.setContent {
+        rule.setFocusableContent {
             Box {
                 BasicText(
                     "focusableText",
@@ -115,7 +115,7 @@
 
     @Test
     fun focusable_disabledSemantics() {
-        rule.setContent {
+        rule.setFocusableContent {
             Box {
                 BasicText(
                     "focusableText",
@@ -133,7 +133,7 @@
     @Test
     fun focusable_focusAcquire() {
         val (focusRequester, otherFocusRequester) = FocusRequester.createRefs()
-        rule.setContent {
+        rule.setFocusableContent {
             Box {
                 BasicText(
                     "focusableText",
@@ -176,7 +176,7 @@
 
         lateinit var scope: CoroutineScope
 
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             Box {
                 BasicText(
@@ -236,7 +236,7 @@
 
         lateinit var scope: CoroutineScope
 
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             Box {
                 if (emitFocusableText) {
@@ -284,7 +284,6 @@
         }
     }
 
-    @OptIn(ExperimentalFoundationApi::class)
     @Test
     fun focusable_pins_whenItIsFocused() {
         // Arrange.
@@ -296,7 +295,7 @@
                 return PinnedHandle {}
             }
         }
-        rule.setContent {
+        rule.setFocusableContent {
             CompositionLocalProvider(LocalPinnableContainer provides pinnableContainer) {
                 Box(
                     Modifier
@@ -318,7 +317,6 @@
         }
     }
 
-    @OptIn(ExperimentalFoundationApi::class)
     @Test
     fun focusable_unpins_whenItIsUnfocused() {
         // Arrange.
@@ -330,7 +328,7 @@
                 return PinnedHandle { onUnpinInvoked = true }
             }
         }
-        rule.setContent {
+        rule.setFocusableContent {
             CompositionLocalProvider(LocalPinnableContainer provides pinnableContainer) {
                 Box(
                     Modifier
@@ -386,7 +384,7 @@
         }
         val focusRequester = FocusRequester()
 
-        rule.setContent {
+        rule.setFocusableContent {
             with(rule.density) {
                 Box(
                     Modifier
@@ -422,7 +420,7 @@
         lateinit var state: LazyListState
         lateinit var coroutineScope: CoroutineScope
         var items by mutableStateOf((1..20).toList())
-        rule.setContent {
+        rule.setFocusableContent {
             state = rememberLazyListState()
             coroutineScope = rememberCoroutineScope()
             LazyRow(
@@ -457,7 +455,7 @@
         // Arrange.
         var hasFocus = false
         var itemVisible by mutableStateOf(true)
-        rule.setContent {
+        rule.setFocusableContent {
             SubcomposeLayout(
                 modifier = Modifier
                     .requiredSize(100.dp)
@@ -490,7 +488,6 @@
         }
     }
 
-    @OptIn(ExperimentalFoundationApi::class)
     @Test
     fun focusable_updatePinnableContainer_staysPinned() {
         // Arrange.
@@ -510,7 +507,7 @@
             }
         }
         var pinnableContainer by mutableStateOf<PinnableContainer>(pinnableContainer1)
-        rule.setContent {
+        rule.setFocusableContent {
             CompositionLocalProvider(LocalPinnableContainer provides pinnableContainer) {
                 Box(
                     Modifier
@@ -544,7 +541,7 @@
         val focusRequester = FocusRequester()
         lateinit var state: FocusState
         var key by mutableStateOf(0)
-        rule.setContent {
+        rule.setFocusableContent {
             ReusableContent(key) {
                 BasicText(
                     "focusableText",
@@ -594,7 +591,7 @@
             )
         }
 
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             if (moveContent) {
                 Box(Modifier.size(5.dp)) {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FoundationTestUtils.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FoundationTestUtils.kt
new file mode 100644
index 0000000..990aaec
--- /dev/null
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FoundationTestUtils.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.compose.foundation
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.unit.dp
+
+/**
+ * This function adds a parent composable which has size.
+ * [View.requestFocus()][android.view.View.requestFocus] will not take focus if the view has no
+ * size.
+ *
+ * @param extraItemForInitialFocus Includes an extra item that takes focus initially. This is
+ * useful in cases where we need tests that could be affected by initial focus. Eg. When there is
+ * only one focusable item and we clear focus, that item could end up being focused on again by the
+ * initial focus logic.
+ */
+internal fun ComposeContentTestRule.setFocusableContent(
+    extraItemForInitialFocus: Boolean = true,
+    content: @Composable () -> Unit
+) {
+    setContent {
+        if (extraItemForInitialFocus) {
+            Row {
+                Box(modifier = Modifier.requiredSize(10.dp, 10.dp).focusable())
+                Box { content() }
+            }
+        } else {
+            Box(modifier = Modifier.requiredSize(100.dp, 100.dp)) { content() }
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/IndicationTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/IndicationTest.kt
index 6de2d3d..cba8964 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/IndicationTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/IndicationTest.kt
@@ -16,32 +16,35 @@
 
 package androidx.compose.foundation
 
-import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.InteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.foundation.interaction.collectIsPressedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DrawModifierNode
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -68,90 +71,118 @@
     }
 
     @Test
-    fun indication_receivesInitialState() {
-        val dispatcher = MutableInteractionSource()
-        val countDownLatch = CountDownLatch(1)
-        val indication = makeIndication {
-            countDownLatch.countDown()
-        }
-        rule.setContent {
-            Box(Modifier.testTag(testTag).size(100.dp).indication(dispatcher, indication))
-        }
-        assertThat(countDownLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
-    }
-
-    @Test
-    fun indication_click_receivesStateUpdates() {
-        // indication should be called 3 times: 0 indication, press, and after click 0 again
-        val countDownLatch = CountDownLatch(3)
-        val interactions = mutableStateListOf<Interaction>()
-
+    fun indication_drawIsCalled() {
         val interactionSource = MutableInteractionSource()
-
-        val indication = makeIndication {
-            interactions.lastOrNull() // value read
+        val countDownLatch = CountDownLatch(1)
+        val indication = TestPressIndication {
             countDownLatch.countDown()
         }
-
-        var scope: CoroutineScope? = null
-
         rule.setContent {
-            scope = rememberCoroutineScope()
             Box(
                 Modifier
                     .testTag(testTag)
                     .size(100.dp)
-                    .clickable(
-                        interactionSource = interactionSource,
-                        indication = indication,
-                    ) {}
-            )
+                    .indication(interactionSource, indication))
         }
-
-        scope!!.launch {
-            interactionSource.interactions.collect { interactions.add(it) }
-        }
-
-        assertThat(countDownLatch.count).isEqualTo(2)
-        rule.onNodeWithTag(testTag)
-            .assertExists()
-            .performTouchInput {
-                down(center)
-            }
-
-        rule.runOnIdle {
-            assertThat(countDownLatch.count).isEqualTo(1)
-        }
-
-        rule.onNodeWithTag(testTag)
-            .assertExists()
-            .performTouchInput {
-                up()
-            }
         assertThat(countDownLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
     }
 
-    private fun makeIndication(onDraw: () -> Unit): Indication {
-        return object : Indication {
-            @Composable
-            override fun rememberUpdatedInstance(
-                interactionSource: InteractionSource
-            ): IndicationInstance {
-                return remember(interactionSource) {
-                    object : IndicationInstance {
-                        override fun ContentDrawScope.drawIndication() {
-                            onDraw()
-                        }
-                    }
-                }
+    @Test
+    fun indicationNodeFactory_drawIsCalled() {
+        val interactionSource = MutableInteractionSource()
+        val countDownLatch = CountDownLatch(1)
+        val indication = TestPressIndicationNodeFactory(onCreate = null, onDraw = {
+            countDownLatch.countDown()
+        })
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(testTag)
+                    .size(100.dp)
+                    .indication(interactionSource, indication))
+        }
+        assertThat(countDownLatch.await(1000, TimeUnit.MILLISECONDS)).isTrue()
+    }
+
+    @Test
+    fun indication_receivesUpdates() {
+        // Draw should be called 3 times: initial draw, press, and release
+        var drawCalls = 0
+        val press = PressInteraction.Press(Offset.Zero)
+        val release = PressInteraction.Release(press)
+
+        val interactionSource = MutableInteractionSource()
+
+        val indication = TestPressIndication {
+            drawCalls++
+        }
+
+        rule.setContent {
+            Box(Modifier.testTag(testTag).size(100.dp).indication(interactionSource, indication))
+        }
+
+        rule.runOnIdle {
+            assertThat(drawCalls).isEqualTo(1)
+            runBlocking {
+                interactionSource.emit(press)
             }
         }
+
+        rule.runOnIdle {
+            assertThat(drawCalls).isEqualTo(2)
+            runBlocking {
+                interactionSource.emit(release)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(drawCalls).isEqualTo(3)
+        }
     }
 
     @Test
-    fun testInspectorValue() {
+    fun indicationNodeFactory_receivesUpdates() {
+        // Draw should be called 3 times: initial draw, press, and release
+        var drawCalls = 0
+        val press = PressInteraction.Press(Offset.Zero)
+        val release = PressInteraction.Release(press)
+
+        val interactionSource = MutableInteractionSource()
+
+        val indication = TestPressIndicationNodeFactory(
+            onDraw = {
+                drawCalls++
+            },
+            onCreate = null
+        )
+
+        rule.setContent {
+            Box(Modifier.testTag(testTag).size(100.dp).indication(interactionSource, indication))
+        }
+
+        rule.runOnIdle {
+            assertThat(drawCalls).isEqualTo(1)
+            runBlocking {
+                interactionSource.emit(press)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(drawCalls).isEqualTo(2)
+            runBlocking {
+                interactionSource.emit(release)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(drawCalls).isEqualTo(3)
+        }
+    }
+
+    @Test
+    fun indication_testInspectorValue() {
         val state = MutableInteractionSource()
-        val indication = makeIndication {}
+        val indication = TestPressIndication()
         rule.setContent {
             val modifier = Modifier.indication(state, indication) as InspectableValue
             assertThat(modifier.nameFallback).isEqualTo("indication")
@@ -162,4 +193,249 @@
             )
         }
     }
+
+    @Test
+    fun indicationNodeFactory_testInspectorValue() {
+        val state = MutableInteractionSource()
+        val indication = TestPressIndicationNodeFactory(null, null)
+        rule.setContent {
+            val modifier = Modifier.indication(state, indication) as InspectableValue
+            assertThat(modifier.nameFallback).isEqualTo("indication")
+            assertThat(modifier.valueOverride).isNull()
+            assertThat(modifier.inspectableElements.map { it.name }.asIterable()).containsExactly(
+                "indication",
+                "interactionSource"
+            )
+        }
+    }
+
+    @Test
+    fun indicationNodeFactory_newInteractionSource() {
+        var interactionSource by mutableStateOf(MutableInteractionSource())
+        var createCalls = 0
+        var drawCalls = 0
+        val indication = TestPressIndicationNodeFactory(
+            onCreate = {
+                createCalls++
+            },
+            onDraw = {
+                drawCalls++
+            }
+        )
+
+        rule.setContent {
+            Box(
+                Modifier.testTag(testTag).size(100.dp).indication(interactionSource, indication)
+            )
+        }
+
+        rule.runOnIdle {
+            assertThat(createCalls).isEqualTo(1)
+            assertThat(drawCalls).isEqualTo(1)
+            // Create a new interaction source
+            interactionSource = MutableInteractionSource()
+        }
+
+        rule.runOnIdle {
+            // New instance should be created
+            assertThat(createCalls).isEqualTo(2)
+            // The new node should be drawn
+            assertThat(drawCalls).isEqualTo(2)
+        }
+    }
+
+    @Test
+    fun indicationNodeFactory_reuse_sameIndicationInstance() {
+        val interactionSource = MutableInteractionSource()
+        var createCalls = 0
+        val onCreate: () -> Unit = {
+            createCalls++
+        }
+        val indication = TestPressIndicationNodeFactory(
+            onCreate = onCreate,
+            onDraw = null
+        )
+
+        var state by mutableStateOf(false)
+
+        rule.setContent {
+            // state read to force recomposition
+            @Suppress("UNUSED_VARIABLE")
+            val readState = state
+            Box(
+                Modifier.testTag(testTag).size(100.dp).indication(interactionSource, indication)
+            )
+        }
+
+        rule.runOnIdle {
+            assertThat(createCalls).isEqualTo(1)
+            // force recomposition
+            state = !state
+        }
+
+        rule.runOnIdle {
+            // We should still reuse the old instance
+            assertThat(createCalls).isEqualTo(1)
+        }
+    }
+
+    @Test
+    fun indicationNodeFactory_reuse_differentIndicationInstance_comparesEqual() {
+        val interactionSource = MutableInteractionSource()
+        var createCalls = 0
+        val onCreate: () -> Unit = {
+            createCalls++
+        }
+        var indication by mutableStateOf(TestPressIndicationNodeFactory(
+            onCreate = onCreate,
+            onDraw = null
+        ))
+
+        rule.setContent {
+            Box(
+                Modifier.testTag(testTag).size(100.dp).indication(interactionSource, indication)
+            )
+        }
+
+        rule.runOnIdle {
+            assertThat(createCalls).isEqualTo(1)
+            // Create a new indication instance that should compare equal
+            indication = TestPressIndicationNodeFactory(onCreate = onCreate, onDraw = null)
+        }
+
+        rule.runOnIdle {
+            // We should still reuse the old instance
+            assertThat(createCalls).isEqualTo(1)
+        }
+    }
+
+    @Test
+    fun indicationNodeFactory_recreation() {
+        val interactionSource = MutableInteractionSource()
+        var createCalls = 0
+        var drawnNode = 0
+        var indication by mutableStateOf(TestPressIndicationNodeFactory(
+            onCreate = {
+                createCalls++
+            },
+            onDraw = {
+                 drawnNode = 1
+            }
+        ))
+
+        rule.setContent {
+            Box(
+                Modifier.testTag(testTag).size(100.dp).indication(interactionSource, indication)
+            )
+        }
+
+        rule.runOnIdle {
+            assertThat(createCalls).isEqualTo(1)
+            assertThat(drawnNode).isEqualTo(1)
+            // Reset drawn node
+            drawnNode = 0
+            // Create a new indication instance that should not compare equal
+            indication = TestPressIndicationNodeFactory(
+                onCreate = {
+                    createCalls++
+                },
+                onDraw = {
+                    drawnNode = 2
+                }
+            )
+        }
+
+        rule.runOnIdle {
+            // New instance that doesn't compare equal, so we should create again
+            assertThat(createCalls).isEqualTo(2)
+            // The new node should be drawn
+            assertThat(drawnNode).isEqualTo(2)
+        }
+    }
+}
+
+/**
+ * Simple [Indication] that draws a black overlay for pressed state. [rememberUpdatedInstance]
+ * is deprecated, but this exists to test the backwards compat path for older indication
+ * implementations.
+ *
+ * @param onDraw lambda executed when draw is called for the created instance
+ */
+@Suppress("DEPRECATION_ERROR")
+private class TestPressIndication(val onDraw: () -> Unit = {}) : Indication {
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
+        val isPressed = interactionSource.collectIsPressedAsState()
+        return remember(interactionSource, isPressed) {
+            object : IndicationInstance {
+                override fun ContentDrawScope.drawIndication() {
+                    onDraw()
+                    drawContent()
+                    if (isPressed.value) {
+                        drawRect(color = Color.Black.copy(alpha = 0.3f), size = size)
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Simple [IndicationNodeFactory] that draws a black overlay for pressed state.
+ *
+ * @param onDraw lambda executed when draw is called for the created node
+ * @param onCreate lambda executed when [create] is called
+ */
+private class TestPressIndicationNodeFactory(
+    val onCreate: (() -> Unit)?,
+    val onDraw: (() -> Unit)?
+) : IndicationNodeFactory {
+    override fun create(interactionSource: InteractionSource): DelegatableNode {
+        onCreate?.invoke()
+        return object : Modifier.Node(), DrawModifierNode {
+            private var isPressed by mutableStateOf(false)
+
+            override fun onAttach() {
+                coroutineScope.launch {
+                    val pressInteractions = mutableListOf<PressInteraction.Press>()
+                    interactionSource.interactions.collect { interaction ->
+                        when (interaction) {
+                            is PressInteraction.Press ->
+                                pressInteractions.add(interaction)
+                            is PressInteraction.Release ->
+                                pressInteractions.remove(interaction.press)
+                            is PressInteraction.Cancel ->
+                                pressInteractions.remove(interaction.press)
+                        }
+                        isPressed = pressInteractions.isNotEmpty()
+                    }
+                }
+            }
+
+            override fun ContentDrawScope.draw() {
+                onDraw?.invoke()
+                drawContent()
+                if (isPressed) {
+                    drawRect(color = Color.Black.copy(alpha = 0.3f), size = size)
+                }
+            }
+        }
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is TestPressIndicationNodeFactory) return false
+
+        if (onDraw != other.onDraw) return false
+        if (onCreate != other.onCreate) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = onDraw.hashCode()
+        result = 31 * result + onCreate.hashCode()
+        return result
+    }
 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
index e05e7d7..e51bd1f 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
@@ -252,6 +252,29 @@
         }
     }
 
+    @OptIn(ExperimentalTestApi::class)
+    @Test
+    fun scrollable_horizontalScroll_mouseWheel_badMotionEvent() {
+        var total = 0f
+        val controller = ScrollableState(
+            consumeScrollDelta = {
+                total += it
+                it
+            }
+        )
+        setScrollableContent {
+            Modifier.scrollable(
+                state = controller,
+                orientation = Orientation.Horizontal
+            )
+        }
+        rule.onNodeWithTag(scrollableBoxTag).performMouseInput {
+            this.scroll(Float.NaN, ScrollWheel.Horizontal)
+        }
+
+        assertThat(total).isEqualTo(0)
+    }
+
     /*
      * Note: For keyboard scrolling to work (that is, scrolling based on the page up/down keys),
      * at least one child within the scrollable must be focusable. (This matches the behavior in
@@ -513,6 +536,29 @@
         }
     }
 
+    @OptIn(ExperimentalTestApi::class)
+    @Test
+    fun scrollable_verticalScroll_mouseWheel_badMotionEvent() {
+        var total = 0f
+        val controller = ScrollableState(
+            consumeScrollDelta = {
+                total += it
+                it
+            }
+        )
+        setScrollableContent {
+            Modifier.scrollable(
+                state = controller,
+                orientation = Orientation.Vertical
+            )
+        }
+        rule.onNodeWithTag(scrollableBoxTag).performMouseInput {
+            this.scroll(Float.NaN, ScrollWheel.Vertical)
+        }
+
+        assertThat(total).isEqualTo(0)
+    }
+
     /*
      * Note: For keyboard scrolling to work (that is, scrolling based on the page up/down keys),
      * at least one child within the scrollable must be focusable. (This matches the behavior in
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt
index fc52c37e..7a9fa96 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt
@@ -19,7 +19,9 @@
 import androidx.compose.animation.core.FloatSpringSpec
 import androidx.compose.foundation.AutoTestFrameClock
 import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.gestures.scrollBy
 import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.width
@@ -68,11 +70,18 @@
         }
     }
 
-    private fun testScroll(spacingPx: Int = 0, assertBlock: suspend () -> Unit) {
+    private fun testScroll(
+        spacingPx: Int = 0,
+        containerSizePx: Int = itemSizePx * 3,
+        afterContentPaddingPx: Int = 0,
+        assertBlock: suspend () -> Unit
+    ) {
         rule.setContent {
             state = rememberLazyGridState()
             scope = rememberCoroutineScope()
-            TestContent(with(rule.density) { spacingPx.toDp() })
+            with(rule.density) {
+                TestContent(spacingPx.toDp(), containerSizePx.toDp(), afterContentPaddingPx.toDp())
+            }
         }
         runBlocking {
             assertBlock()
@@ -297,6 +306,85 @@
     }
 
     @Test
+    fun canScrollForwardAndBackward_afterSmallScrollFromStart() = testScroll(
+        containerSizePx = (itemSizePx * 1.5f).roundToInt()
+    ) {
+        val delta = (itemSizePx / 3f).roundToInt()
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            // small enough scroll to not cause any new items to be composed or old ones disposed.
+            state.scrollBy(delta.toFloat())
+        }
+        rule.runOnIdle {
+            assertThat(state.firstVisibleItemScrollOffset).isEqualTo(delta)
+            assertThat(state.canScrollForward).isTrue()
+            assertThat(state.canScrollBackward).isTrue()
+        }
+        // and scroll back to start
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            state.scrollBy(-delta.toFloat())
+        }
+        rule.runOnIdle {
+            assertThat(state.canScrollForward).isTrue()
+            assertThat(state.canScrollBackward).isFalse()
+        }
+    }
+
+    @Test
+    fun canScrollForwardAndBackward_afterSmallScrollFromEnd() = testScroll(
+        containerSizePx = (itemSizePx * 1.5f).roundToInt()
+    ) {
+        val delta = -(itemSizePx / 3f).roundToInt()
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            // scroll to the end of the list.
+            state.scrollToItem(itemsCount)
+            // small enough scroll to not cause any new items to be composed or old ones disposed.
+            state.scrollBy(delta.toFloat())
+        }
+        rule.runOnIdle {
+            assertThat(state.canScrollForward).isTrue()
+            assertThat(state.canScrollBackward).isTrue()
+        }
+        // and scroll back to the end
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            state.scrollBy(-delta.toFloat())
+        }
+        rule.runOnIdle {
+            assertThat(state.canScrollForward).isFalse()
+            assertThat(state.canScrollBackward).isTrue()
+        }
+    }
+
+    @Test
+    fun canScrollForwardAndBackward_afterSmallScrollFromEnd_withContentPadding() = testScroll(
+        containerSizePx = (itemSizePx * 1.5f).roundToInt(),
+        afterContentPaddingPx = 2,
+    ) {
+        val delta = -(itemSizePx / 3f).roundToInt()
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            // scroll to the end of the list.
+            state.scrollToItem(itemsCount)
+
+            assertThat(state.canScrollForward).isFalse()
+            assertThat(state.canScrollBackward).isTrue()
+
+            // small enough scroll to not cause any new items to be composed or old ones disposed.
+            state.scrollBy(delta.toFloat())
+        }
+        rule.runOnIdle {
+            assertThat(state.canScrollForward).isTrue()
+            assertThat(state.canScrollBackward).isTrue()
+        }
+        // and scroll back to the end
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            state.scrollBy(-delta.toFloat())
+        }
+        rule.runOnIdle {
+            assertThat(state.canScrollForward).isFalse()
+            assertThat(state.canScrollBackward).isTrue()
+        }
+    }
+
+    @Test
     fun animatePerFrameForwardWithSpacing() = testScroll(spacingPx = 10) {
         assertSpringAnimation(toIndex = 16, spacingPx = 10)
     }
@@ -375,12 +463,13 @@
     }
 
     @Composable
-    private fun TestContent(spacingDp: Dp) {
+    private fun TestContent(spacingDp: Dp, containerSizeDp: Dp, afterContentPaddingDp: Dp) {
         if (vertical) {
             LazyVerticalGrid(
                 GridCells.Fixed(2),
                 Modifier.height(containerSizeDp),
                 state,
+                contentPadding = PaddingValues(bottom = afterContentPaddingDp),
                 verticalArrangement = Arrangement.spacedBy(spacingDp)
             ) {
                 items(itemsCount) {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/list/LazyListHeadersTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/list/LazyListHeadersTest.kt
index 881dd61..587e98b 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/list/LazyListHeadersTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/list/LazyListHeadersTest.kt
@@ -19,6 +19,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.ScrollableDefaults
+import androidx.compose.foundation.gestures.scrollBy
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Spacer
@@ -456,6 +457,48 @@
         rule.onNodeWithTag("0")
             .assertTopPositionInRootIsEqualTo(itemIndexDp * 3 / 2)
     }
+
+    @Test
+    fun lazyColumnShowsHeader_withoutBeyondBoundsItemCount2() {
+        val firstHeaderTag = "firstHeaderTag"
+        val secondHeaderTag = "secondHeaderTag"
+        val itemSizeDp = with(rule.density) { 100.toDp() }
+        val scrollDistance = 20
+        val scrollDistanceDp = with(rule.density) { scrollDistance.toDp() }
+        val state = LazyListState()
+
+        rule.setContent {
+            LazyColumn(Modifier.height(itemSizeDp * 3.5f), state) {
+                stickyHeader {
+                    Spacer(
+                        Modifier.height(itemSizeDp).fillParentMaxWidth()
+                            .testTag(firstHeaderTag)
+                    )
+                }
+                stickyHeader {
+                    Spacer(
+                        Modifier.height(itemSizeDp).fillParentMaxWidth()
+                            .testTag(secondHeaderTag)
+                    )
+                }
+
+                items(100) {
+                    Spacer(Modifier.height(itemSizeDp).fillParentMaxWidth().testTag(it.toString()))
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            runBlocking { state.scrollBy(scrollDistance.toFloat()) }
+        }
+
+        rule.onNodeWithTag(firstHeaderTag)
+            .assertTopPositionInRootIsEqualTo(-scrollDistanceDp)
+        rule.onNodeWithTag(secondHeaderTag)
+            .assertTopPositionInRootIsEqualTo(itemSizeDp - scrollDistanceDp)
+        rule.onNodeWithTag("0")
+            .assertTopPositionInRootIsEqualTo(itemSizeDp * 2 - scrollDistanceDp)
+    }
 }
 
 @Composable
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
index bce771a..614d0d4 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
@@ -24,6 +24,7 @@
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.fillMaxHeight
@@ -126,6 +127,7 @@
         reverseLayout: Boolean = config.reverseLayout,
         snapPositionalThreshold: Float = 0.5f,
         key: ((index: Int) -> Any)? = null,
+        snapPosition: SnapPosition = SnapPosition.Start,
         pageContent: @Composable PagerScope.(page: Int) -> Unit = { Page(index = it) }
     ) {
 
@@ -164,6 +166,7 @@
                         pageSpacing = pageSpacing,
                         contentPadding = contentPadding,
                         pageContent = pageContent,
+                        snapPosition = snapPosition,
                         key = key
                     )
                 }
@@ -286,6 +289,7 @@
         flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
         pageSpacing: Dp = 0.dp,
         key: ((index: Int) -> Any)? = null,
+        snapPosition: SnapPosition = config.snapPosition,
         pageContent: @Composable PagerScope.(pager: Int) -> Unit
     ) {
         if (vertical) {
@@ -300,6 +304,7 @@
                 flingBehavior = flingBehavior,
                 pageSpacing = pageSpacing,
                 key = key,
+                snapPosition = snapPosition,
                 pageContent = pageContent
             )
         } else {
@@ -314,6 +319,7 @@
                 flingBehavior = flingBehavior,
                 pageSpacing = pageSpacing,
                 key = key,
+                snapPosition = snapPosition,
                 pageContent = pageContent
             )
         }
@@ -360,13 +366,15 @@
     }
 }
 
+@OptIn(ExperimentalFoundationApi::class)
 class ParamConfig(
     val orientation: Orientation,
     val reverseLayout: Boolean = false,
     val layoutDirection: LayoutDirection = LayoutDirection.Ltr,
     val pageSpacing: Dp = 0.dp,
     val mainAxisContentPadding: PaddingValues = PaddingValues(0.dp),
-    val beyondBoundsPageCount: Int = 0
+    val beyondBoundsPageCount: Int = 0,
+    val snapPosition: SnapPosition = SnapPosition.Start
 ) {
     override fun toString(): String {
         return "orientation=$orientation " +
@@ -374,7 +382,8 @@
             "layoutDirection=$layoutDirection " +
             "pageSpacing=$pageSpacing " +
             "mainAxisContentPadding=$mainAxisContentPadding " +
-            "beyondBoundsPageCount=$beyondBoundsPageCount"
+            "beyondBoundsPageCount=$beyondBoundsPageCount" +
+            "snapPosition=$snapPosition"
     }
 }
 
@@ -382,6 +391,7 @@
 internal const val DefaultPageCount = 20
 internal const val DefaultAnimationRepetition = 2
 internal val TestOrientation = listOf(Orientation.Vertical, Orientation.Horizontal)
+@OptIn(ExperimentalFoundationApi::class)
 internal val AllOrientationsParams = mutableListOf<ParamConfig>().apply {
     for (orientation in TestOrientation) {
         add(ParamConfig(orientation = orientation))
@@ -390,6 +400,8 @@
 internal val TestReverseLayout = listOf(false, true)
 internal val TestLayoutDirection = listOf(LayoutDirection.Rtl, LayoutDirection.Ltr)
 internal val TestPageSpacing = listOf(0.dp, 8.dp)
+@OptIn(ExperimentalFoundationApi::class)
+internal val TestSnapPosition = listOf(SnapPosition.Start, SnapPosition.Center, SnapPosition.End)
 internal fun testContentPaddings(orientation: Orientation) = listOf(
     PaddingValues(0.dp),
     if (orientation == Orientation.Vertical)
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt
index e45bcbd..18e67ca 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt
@@ -497,7 +497,7 @@
     fun totalPaddingLargerParentSize_initialState() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState() { 4 }
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -965,12 +965,6 @@
         rule.waitForIdle()
     }
 
-    private fun PagerState.scrollBy(offset: Float) {
-        runBlocking(Dispatchers.Main + AutoTestFrameClock()) {
-            animateScrollBy(offset, snap())
-        }
-    }
-
     private fun PagerState.runScrollToPage(page: Int) {
         runBlocking(Dispatchers.Main + AutoTestFrameClock()) {
             scrollToPage(page)
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt
index d4ca45f..a55a2a4 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt
@@ -129,10 +129,10 @@
     @Test
     fun scrollableState_isScrollableWhenChangingPages() {
         val states = mutableMapOf<Int, ScrollState>()
-        val pagerState = PagerStateImpl(
-            initialPage = 0,
-            initialPageOffsetFraction = 0.0f,
-            updatedPageCount = { 2 })
+        val pagerState = PagerState(
+            currentPage = 0,
+            currentPageOffsetFraction = 0.0f,
+            pageCount = { 2 })
         rule.setContent {
             HorizontalPager(
                 state = pagerState,
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
index 2dd2726..0350d3b 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
@@ -305,10 +305,13 @@
         }
 
         // Assert: Inner list won't consume scroll and pager moved
-        assertThat(abs(pagerState.currentPageOffsetFraction - 0.4f)).isLessThan(0.001f)
-        assertThat(lazyListState.firstVisibleItemScrollOffset).isEqualTo(firstLazyListItemOffset)
-        assertThat(lazyListState.firstVisibleItemIndex).isEqualTo(firstLazyListItem)
-
+        rule.runOnIdle {
+            assertThat(abs(pagerState.currentPageOffsetFraction - 0.4f)).isLessThan(0.001f)
+            assertThat(
+                lazyListState.firstVisibleItemScrollOffset
+            ).isEqualTo(firstLazyListItemOffset)
+            assertThat(lazyListState.firstVisibleItemIndex).isEqualTo(firstLazyListItem)
+        }
         rule.onNodeWithTag(TestTag).performTouchInput {
             moveBy(
                 if (vertical) Offset(x = 0f, y = -forwardDelta / 2)
@@ -317,9 +320,13 @@
         }
 
         // assert: pager moved, but list is still at 0 after direction change
-        assertThat(abs(pagerState.currentPageOffsetFraction - 0.2f)).isLessThan(0.001f)
-        assertThat(lazyListState.firstVisibleItemScrollOffset).isEqualTo(firstLazyListItemOffset)
-        assertThat(lazyListState.firstVisibleItemIndex).isEqualTo(firstLazyListItem)
+        rule.runOnIdle {
+            assertThat(abs(pagerState.currentPageOffsetFraction - 0.2f)).isLessThan(0.001f)
+            assertThat(
+                lazyListState.firstVisibleItemScrollOffset
+            ).isEqualTo(firstLazyListItemOffset)
+            assertThat(lazyListState.firstVisibleItemIndex).isEqualTo(firstLazyListItem)
+        }
 
         rule.onNodeWithTag(TestTag).performTouchInput {
             up()
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt
index 3de9193..762f095 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt
@@ -312,10 +312,10 @@
     @Test
     fun unpinnedWhenPagerStateChanges() {
         var state by mutableStateOf(
-            PagerStateImpl(
-                initialPage = 2,
-                initialPageOffsetFraction = 0f,
-                updatedPageCount = { 100 })
+            PagerState(
+                currentPage = 2,
+                currentPageOffsetFraction = 0f,
+                pageCount = { 100 })
         )
         // Arrange.
         rule.setContent {
@@ -349,10 +349,10 @@
 
         rule.runOnIdle {
             assertThat(composed).contains(2)
-            state = PagerStateImpl(
-                initialPage = 0,
-                initialPageOffsetFraction = 0f,
-                updatedPageCount = { 100 })
+            state = PagerState(
+                currentPage = 0,
+                currentPageOffsetFraction = 0f,
+                pageCount = { 100 })
         }
 
         rule.waitUntil {
@@ -367,10 +367,10 @@
     @Test
     fun pinAfterPagerStateChange() {
         var state by mutableStateOf(
-            PagerStateImpl(
-                initialPage = 0,
-                initialPageOffsetFraction = 0f,
-                updatedPageCount = { 100 })
+            PagerState(
+                currentPage = 0,
+                currentPageOffsetFraction = 0f,
+                pageCount = { 100 })
         )
         // Arrange.
         rule.setContent {
@@ -387,10 +387,10 @@
         }
 
         rule.runOnIdle {
-            state = PagerStateImpl(
-                initialPage = 0,
-                initialPageOffsetFraction = 0f,
-                updatedPageCount = { 100 })
+            state = PagerState(
+                currentPage = 0,
+                currentPageOffsetFraction = 0f,
+                pageCount = { 100 })
         }
 
         rule.runOnIdle {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt
index 61dae64..b31df33 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt
@@ -297,7 +297,7 @@
             )
             up()
         }
-        rule.mainClock.advanceTimeUntil { pagerState.isScrollInProgress == false }
+        rule.mainClock.advanceTimeUntil { !pagerState.isScrollInProgress }
 
         // Assert
         rule.onNodeWithTag("0").assertIsDisplayed()
@@ -326,7 +326,7 @@
             )
             up()
         }
-        rule.mainClock.advanceTimeUntil { pagerState.isScrollInProgress == false }
+        rule.mainClock.advanceTimeUntil { !pagerState.isScrollInProgress }
 
         // Assert
         rule.onNodeWithTag("${DefaultPageCount - 1}").assertIsDisplayed()
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerSnapPositionTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerSnapPositionTest.kt
new file mode 100644
index 0000000..9600200
--- /dev/null
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerSnapPositionTest.kt
@@ -0,0 +1,544 @@
+/*
+ * Copyright 2022 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.compose.foundation.pager
+
+import androidx.compose.foundation.AutoTestFrameClock
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.gestures.snapping.SnapPosition
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.test.performTouchInput
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertTrue
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@OptIn(ExperimentalFoundationApi::class)
+@LargeTest
+@RunWith(Parameterized::class)
+class PagerSnapPositionTest(val config: ParamConfig) : BasePagerTest(config) {
+
+    @Test
+    fun scrollToPage_shouldPlacePagesCorrectly() = runBlocking {
+        // Arrange
+        createPager(modifier = Modifier.fillMaxSize())
+
+        // Act and Assert
+        repeat(DefaultAnimationRepetition) {
+            assertThat(pagerState.currentPage).isEqualTo(it)
+            val nextPage = pagerState.currentPage + 1
+            withContext(Dispatchers.Main + AutoTestFrameClock()) {
+                pagerState.scrollToPage(nextPage)
+            }
+            rule.mainClock.advanceTimeUntil { pagerState.currentPage == nextPage }
+            confirmPageIsInCorrectPosition(pagerState.currentPage)
+        }
+    }
+
+    @SdkSuppress(maxSdkVersion = 32) // b/269176638
+    @Test
+    fun scrollToPage_usedOffset_shouldPlacePagesCorrectly() = runBlocking {
+        // Arrange
+
+        suspend fun scrollToPageWithOffset(page: Int, offset: Float) {
+            withContext(Dispatchers.Main + AutoTestFrameClock()) {
+                pagerState.scrollToPage(page, offset)
+            }
+        }
+
+        // Arrange
+        createPager(modifier = Modifier.fillMaxSize())
+
+        // Act
+        scrollToPageWithOffset(10, 0.5f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 10, pageOffset = 0.5f)
+
+        // Act
+        scrollToPageWithOffset(4, 0.2f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 4, pageOffset = 0.2f)
+
+        // Act
+        scrollToPageWithOffset(12, -0.4f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 12, pageOffset = -0.4f)
+
+        // Act
+        scrollToPageWithOffset(DefaultPageCount - 1, 0.5f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, DefaultPageCount - 1)
+
+        // Act
+        scrollToPageWithOffset(0, -0.5f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 0)
+    }
+
+    @Test
+    fun animateScrollToPage_shouldPlacePagesCorrectly() = runBlocking {
+        // Arrange
+
+        createPager(modifier = Modifier.fillMaxSize())
+
+        // Act and Assert
+        repeat(DefaultAnimationRepetition) {
+            assertThat(pagerState.currentPage).isEqualTo(it)
+            val nextPage = pagerState.currentPage + 1
+            withContext(Dispatchers.Main + AutoTestFrameClock()) {
+                pagerState.animateScrollToPage(nextPage)
+            }
+            rule.waitForIdle()
+            assertTrue { pagerState.currentPage == nextPage }
+            confirmPageIsInCorrectPosition(pagerState.currentPage)
+        }
+    }
+
+    @Test
+    fun animateScrollToPage_usedOffset_shouldPlacePagesCorrectly() = runBlocking {
+        // Arrange
+
+        suspend fun animateScrollToPageWithOffset(page: Int, offset: Float) {
+            withContext(Dispatchers.Main + AutoTestFrameClock()) {
+                pagerState.animateScrollToPage(page, offset)
+            }
+            rule.waitForIdle()
+        }
+
+        // Arrange
+        createPager(modifier = Modifier.fillMaxSize())
+
+        // Act
+        animateScrollToPageWithOffset(10, 0.49f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 10, pageOffset = 0.49f)
+
+        // Act
+        animateScrollToPageWithOffset(4, 0.2f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 4, pageOffset = 0.2f)
+
+        // Act
+        animateScrollToPageWithOffset(12, -0.4f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 12, pageOffset = -0.4f)
+
+        // Act
+        animateScrollToPageWithOffset(DefaultPageCount - 1, 0.5f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, DefaultPageCount - 1)
+
+        // Act
+        animateScrollToPageWithOffset(0, -0.5f)
+
+        // Assert
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 0)
+    }
+
+    @Test
+    fun animateScrollToPage_moveToSamePageWithOffset_shouldScroll() = runBlocking {
+        // Arrange
+        createPager(initialPage = 5, modifier = Modifier.fillMaxSize())
+
+        // Act
+        assertThat(pagerState.currentPage).isEqualTo(5)
+
+        withContext(Dispatchers.Main + AutoTestFrameClock()) {
+            pagerState.animateScrollToPage(5, 0.4f)
+        }
+
+        // Assert
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(5) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isWithin(0.01f).of(0.4f) }
+    }
+
+    @Test
+    fun currentPage_shouldChangeWhenClosestPageToSnappedPositionChanges() {
+        // Arrange
+
+        createPager(modifier = Modifier.fillMaxSize())
+        var previousCurrentPage = pagerState.currentPage
+
+        // Act
+        // Move less than half an item
+        val firstDelta = (pagerSize * 0.4f) * scrollForwardSign
+        onPager().performTouchInput {
+            down(layoutStart)
+            if (vertical) {
+                moveBy(Offset(0f, firstDelta))
+            } else {
+                moveBy(Offset(firstDelta, 0f))
+            }
+        }
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isEqualTo(previousCurrentPage)
+        }
+        // Release pointer
+        onPager().performTouchInput { up() }
+
+        rule.runOnIdle {
+            previousCurrentPage = pagerState.currentPage
+        }
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
+
+        // Arrange
+        // Pass closest to snap position threshold (over half an item)
+        val secondDelta = (pagerSize * 0.6f) * scrollForwardSign
+
+        // Act
+        onPager().performTouchInput {
+            down(layoutStart)
+            if (vertical) {
+                moveBy(Offset(0f, secondDelta))
+            } else {
+                moveBy(Offset(secondDelta, 0f))
+            }
+        }
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isEqualTo(previousCurrentPage + 1)
+        }
+
+        onPager().performTouchInput { up() }
+        rule.waitForIdle()
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
+    }
+
+    @Test
+    fun targetPage_performScrollBelowMinThreshold_shouldNotShowNextPage() {
+        // Arrange
+        createPager(
+            modifier = Modifier.fillMaxSize(),
+            snappingPage = PagerSnapDistance.atMost(3)
+        )
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+
+        rule.mainClock.autoAdvance = false
+        // Act
+        // Moving less than threshold
+        val forwardDelta =
+            scrollForwardSign.toFloat() * with(rule.density) { DefaultPositionThreshold.toPx() / 2 }
+
+        var previousTargetPage = pagerState.targetPage
+
+        onPager().performTouchInput {
+            down(layoutStart)
+            moveBy(Offset(forwardDelta, forwardDelta))
+        }
+
+        // Assert
+        assertThat(pagerState.targetPage).isEqualTo(previousTargetPage)
+
+        // Reset
+        rule.mainClock.autoAdvance = true
+        onPager().performTouchInput { up() }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+
+        // Act
+        // Moving more than threshold
+        val backwardDelta = scrollForwardSign.toFloat() * with(rule.density) {
+            -DefaultPositionThreshold.toPx() / 2
+        }
+
+        previousTargetPage = pagerState.targetPage
+
+        onPager().performTouchInput {
+            down(layoutStart)
+            moveBy(Offset(backwardDelta, backwardDelta))
+        }
+
+        // Assert
+        assertThat(pagerState.targetPage).isEqualTo(previousTargetPage)
+    }
+
+    @Test
+    fun targetPage_performScroll_shouldShowNextPage() {
+        // Arrange
+        createPager(
+            modifier = Modifier.fillMaxSize(),
+            snappingPage = PagerSnapDistance.atMost(3)
+        )
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+
+        rule.mainClock.autoAdvance = false
+        // Act
+        // Moving forward
+        val forwardDelta = pagerSize * 0.4f * scrollForwardSign.toFloat()
+        onPager().performTouchInput {
+            down(layoutStart)
+            moveBy(Offset(forwardDelta, forwardDelta))
+        }
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage + 1)
+            assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
+        }
+
+        // Reset
+        rule.mainClock.autoAdvance = true
+        onPager().performTouchInput { up() }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+        rule.runOnIdle {
+            scope.launch {
+                pagerState.scrollToPage(5)
+            }
+        }
+
+        rule.mainClock.autoAdvance = false
+        // Act
+        // Moving backward
+        val backwardDelta = -pagerSize * 0.4f * scrollForwardSign.toFloat()
+        onPager().performTouchInput {
+            down(layoutEnd)
+            moveBy(Offset(backwardDelta, backwardDelta))
+        }
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage - 1)
+            assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
+        }
+
+        rule.mainClock.autoAdvance = true
+        onPager().performTouchInput { up() }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+    }
+
+    @Test
+    fun targetPage_performingFling_shouldGoToPredictedPage() {
+        // Arrange
+
+        createPager(
+            modifier = Modifier.fillMaxSize(),
+            snappingPage = PagerSnapDistance.atMost(3)
+        )
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+
+        rule.mainClock.autoAdvance = false
+        // Act
+        // Moving forward
+        var previousTarget = pagerState.targetPage
+        val forwardDelta = pagerSize * scrollForwardSign.toFloat()
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(20000f, forwardDelta)
+        }
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != previousTarget }
+        var flingOriginIndex = pagerState.firstVisiblePage
+        // Assert
+        assertThat(pagerState.targetPage).isEqualTo(flingOriginIndex + 3)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
+
+        rule.mainClock.autoAdvance = true
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+        rule.mainClock.autoAdvance = false
+        // Act
+        // Moving backward
+        previousTarget = pagerState.targetPage
+        val backwardDelta = -pagerSize * scrollForwardSign.toFloat()
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(20000f, backwardDelta)
+        }
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != previousTarget }
+
+        // Assert
+        flingOriginIndex = pagerState.firstVisiblePage + 1
+        assertThat(pagerState.targetPage).isEqualTo(flingOriginIndex - 3)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
+
+        rule.mainClock.autoAdvance = true
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+    }
+
+    @Test
+    fun targetPage_valueAfterScrollingAfterMidpoint() {
+        createPager(initialPage = 5, modifier = Modifier.fillMaxSize())
+
+        var previousCurrentPage = pagerState.currentPage
+
+        val forwardDelta = (pagerSize * 0.7f) * scrollForwardSign
+        onPager().performTouchInput {
+            down(layoutStart)
+            if (vertical) {
+                moveBy(Offset(0f, forwardDelta))
+            } else {
+                moveBy(Offset(forwardDelta, 0f))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isNotEqualTo(previousCurrentPage)
+            assertThat(pagerState.targetPage).isEqualTo(previousCurrentPage + 1)
+        }
+
+        onPager().performTouchInput { up() }
+
+        rule.runOnIdle {
+            previousCurrentPage = pagerState.currentPage
+        }
+
+        val backwardDelta = (pagerSize * 0.7f) * scrollForwardSign * -1
+        onPager().performTouchInput {
+            down(layoutEnd)
+            if (vertical) {
+                moveBy(Offset(0f, backwardDelta))
+            } else {
+                moveBy(Offset(backwardDelta, 0f))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isNotEqualTo(previousCurrentPage)
+            assertThat(pagerState.targetPage).isEqualTo(previousCurrentPage - 1)
+        }
+
+        onPager().performTouchInput { up() }
+    }
+
+    @Test
+    fun targetPage_valueAfterScrollingForwardAndBackward() {
+        createPager(initialPage = 5, modifier = Modifier.fillMaxSize())
+
+        val startCurrentPage = pagerState.currentPage
+
+        val forwardDelta = (pagerSize * 0.8f) * scrollForwardSign
+        onPager().performTouchInput {
+            down(layoutStart)
+            if (vertical) {
+                moveBy(Offset(0f, forwardDelta))
+            } else {
+                moveBy(Offset(forwardDelta, 0f))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isNotEqualTo(startCurrentPage)
+            assertThat(pagerState.targetPage).isEqualTo(startCurrentPage + 1)
+        }
+
+        val backwardDelta = (pagerSize * 0.2f) * scrollForwardSign * -1
+        onPager().performTouchInput {
+            if (vertical) {
+                moveBy(Offset(0f, backwardDelta))
+            } else {
+                moveBy(Offset(backwardDelta, 0f))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isNotEqualTo(startCurrentPage)
+            assertThat(pagerState.targetPage).isEqualTo(startCurrentPage)
+        }
+
+        onPager().performTouchInput { up() }
+    }
+
+    @Test
+    fun currentPageOffset_shouldReflectScrollingOfCurrentPage() {
+        // Arrange
+        createPager(initialPage = DefaultPageCount / 2, modifier = Modifier.fillMaxSize())
+
+        // No offset initially
+        rule.runOnIdle {
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.01f).of(0f)
+        }
+
+        // Act
+        // Moving forward
+        onPager().performTouchInput {
+            down(layoutStart)
+            if (vertical) {
+                moveBy(Offset(0f, scrollForwardSign * pagerSize / 4f))
+            } else {
+                moveBy(Offset(scrollForwardSign * pagerSize / 4f, 0f))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.1f).of(0.25f)
+        }
+
+        onPager().performTouchInput { up() }
+        rule.waitForIdle()
+
+        // Reset
+        rule.runOnIdle {
+            scope.launch {
+                pagerState.scrollToPage(DefaultPageCount / 2)
+            }
+        }
+
+        // No offset initially (again)
+        rule.runOnIdle {
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.01f).of(0f)
+        }
+
+        // Act
+        // Moving backward
+        onPager().performTouchInput {
+            down(layoutStart)
+            if (vertical) {
+                moveBy(Offset(0f, -scrollForwardSign * pagerSize / 4f))
+            } else {
+                moveBy(Offset(-scrollForwardSign * pagerSize / 4f, 0f))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.1f).of(-0.25f)
+        }
+    }
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun params() = mutableListOf<ParamConfig>().apply {
+            for (orientation in TestOrientation) {
+                for (snapPosition in TestSnapPosition) {
+                    // skip start since it's being tested in PagerStateTest already.
+                    if (snapPosition == SnapPosition.Start) continue
+                    add(
+                        ParamConfig(
+                            orientation = orientation,
+                            snapPosition = snapPosition
+                        )
+                    )
+                }
+            }
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateNonGestureScrollingTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateNonGestureScrollingTest.kt
index ff647ba..b94c526 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateNonGestureScrollingTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateNonGestureScrollingTest.kt
@@ -18,8 +18,11 @@
 
 import androidx.compose.foundation.AutoTestFrameClock
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.gestures.snapping.SnapPosition
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.mutableStateOf
@@ -30,9 +33,15 @@
 import androidx.compose.ui.test.assertIsDisplayed
 import androidx.compose.ui.test.junit4.StateRestorationTester
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.test.swipeLeft
+import androidx.compose.ui.test.swipeUp
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastMaxBy
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth
+import kotlin.math.abs
 import kotlin.test.assertFalse
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
@@ -50,7 +59,7 @@
     @Test
     fun pagerStateNotAttached_shouldReturnDefaultValues_andChangeAfterAttached() = runBlocking {
         // Arrange
-        val state = PagerStateImpl(5, 0.2f) { DefaultPageCount }
+        val state = PagerState(5, 0.2f) { DefaultPageCount }
 
         Truth.assertThat(state.currentPage).isEqualTo(5)
         Truth.assertThat(state.currentPageOffsetFraction).isEqualTo(0.2f)
@@ -85,6 +94,42 @@
     }
 
     @Test
+    fun pageSizeIsZero_offsetFractionShouldNotBeNan() {
+        // Arrange
+        val zeroPageSize = object : PageSize {
+            override fun Density.calculateMainAxisPageSize(
+                availableSpace: Int,
+                pageSpacing: Int
+            ): Int {
+                return 0
+            }
+        }
+
+        rule.setContent {
+            pagerState = rememberPagerState {
+                DefaultPageCount
+            }
+            HorizontalOrVerticalPager(
+                state = pagerState,
+                modifier = Modifier
+                    .size(0.dp)
+                    .testTag(PagerTestTag)
+                    .onSizeChanged { pagerSize = if (vertical) it.height else it.width },
+                pageSize = zeroPageSize,
+                reverseLayout = config.reverseLayout,
+                pageSpacing = config.pageSpacing,
+                contentPadding = config.mainAxisContentPadding,
+            ) {
+                Page(index = it)
+            }
+        }
+
+        rule.runOnIdle {
+            Truth.assertThat(pagerState.currentPageOffsetFraction).isNotNaN()
+        }
+    }
+
+    @Test
     fun initialPageOnPagerState_shouldDisplayThatPageFirst() {
         // Arrange
 
@@ -117,12 +162,7 @@
         // Act
         rule.runOnIdle {
             scope.launch {
-                state.scrollToPage(5)
-            }
-            runBlocking {
-                state.scroll {
-                    scrollBy(50f)
-                }
+                state.scrollToPage(5, 0.2f)
             }
         }
 
@@ -176,7 +216,11 @@
                 dataset.value.size
             }, pageContent = {
                 val item = dataset.value[it]
-                Box(modifier = Modifier.fillMaxSize().testTag(item.item))
+                Box(
+                    modifier = Modifier
+                        .fillMaxSize()
+                        .testTag(item.item)
+                )
             })
 
         Truth.assertThat(dataset.value[pagerState.currentPage].item).isEqualTo("B")
@@ -373,6 +417,126 @@
         Truth.assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage)
     }
 
+    @Test
+    fun currentPage_shouldUpdateWithSnapPositionInLayout() {
+        // snap position is 200dp from edge of Pager
+        val customSnapPosition = SnapPosition { _, _, _, _, _ ->
+            with(rule.density) {
+                200.dp.roundToPx()
+            }
+        }
+
+        createPager(
+            modifier = Modifier.fillMaxSize(),
+            snapPosition = customSnapPosition,
+            pageSize = { PageSize.Fixed(100.dp) }
+        )
+
+        onPager().performTouchInput {
+            swipeLeft()
+            swipeLeft()
+            swipeLeft()
+        }
+
+        with(pagerState.layoutInfo) {
+            val viewPortSize = if (vertical) viewportSize.height else viewportSize.width
+            Truth.assertThat(pagerState.currentPage).isEqualTo(visiblePagesInfo.fastMaxBy {
+                -abs(
+                    calculateDistanceToDesiredSnapPosition(
+                        mainAxisViewPortSize = viewPortSize,
+                        beforeContentPadding = beforeContentPadding,
+                        afterContentPadding = afterContentPadding,
+                        itemSize = pageSize,
+                        itemOffset = it.offset,
+                        itemIndex = it.index,
+                        snapPosition = customSnapPosition
+                    )
+                )
+            }?.index)
+        }
+    }
+
+    @Test
+    fun snapPositionInLayout_startToStart_currentPageShouldBeCloserToStartOfLayout() {
+        createPager(
+            modifier = Modifier.fillMaxSize(),
+            snapPosition = SnapPosition.Start,
+            pageSize = { PageSize.Fixed(100.dp) }
+        )
+
+        onPager().performTouchInput {
+            if (vertical) {
+                swipeUp()
+            } else {
+                swipeLeft()
+            }
+        }
+
+        rule.runOnIdle {
+            // check we moved
+            Truth.assertThat(pagerState.firstVisiblePage).isNotEqualTo(0)
+
+            Truth.assertThat(pagerState.currentPage)
+                .isEqualTo(pagerState.layoutInfo.visiblePagesInfo.first().index)
+
+            // offset should be zero
+            Truth.assertThat(pagerState.layoutInfo.visiblePagesInfo.first().offset)
+                .isEqualTo(0)
+        }
+    }
+
+    @Test
+    fun snapPositionInLayout_centerToCenter_currentPageShouldBeCloserToMiddleOfLayout() {
+        createPager(
+            modifier = Modifier.size(50.dp),
+            snapPosition = SnapPosition.Center,
+            pageSize = { PageSize.Fixed(10.dp) }
+        )
+
+        onPager().performTouchInput {
+            if (vertical) {
+                swipeUp()
+            } else {
+                swipeLeft()
+            }
+        }
+
+        rule.runOnIdle {
+            // find page whose offset is closest to the centre
+            val candidatePage = pagerState.layoutInfo.visiblePagesInfo.fastMaxBy {
+                -(abs(it.offset - pagerSize / 2))
+            }
+
+            // check we moved
+            Truth.assertThat(pagerState.firstVisiblePage).isNotEqualTo(0)
+            Truth.assertThat(pagerState.currentPage).isEqualTo(candidatePage?.index)
+        }
+    }
+
+    @Test
+    fun snapPositionInLayout_endToEnd_currentPageShouldBeCloserToEndOfLayout() {
+        createPager(
+            modifier = Modifier.size(50.dp),
+            snapPosition = SnapPosition.End,
+            pageSize = { PageSize.Fixed(10.dp) }
+        )
+
+        onPager().performTouchInput {
+            if (vertical) {
+                swipeUp()
+            } else {
+                swipeLeft()
+            }
+        }
+
+        rule.runOnIdle {
+            // check we moved
+            Truth.assertThat(pagerState.firstVisiblePage).isNotEqualTo(0)
+            Truth.assertThat(pagerState.currentPage)
+                .isEqualTo(pagerState.layoutInfo.visiblePagesInfo.last().index)
+        }
+    }
+
     companion object {
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
index a4e73f5..6aabc08 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
@@ -166,7 +167,7 @@
     fun pageCount_readBeforeCompositionIsAccurate() {
         // Arrange
         val pageCount = mutableStateOf(2)
-        val state = PagerStateImpl(0, 0f) { pageCount.value }
+        val state = PagerState(0, 0f) { pageCount.value }
         assertThat(state.pageCount).isEqualTo(pageCount.value)
         rule.setContent {
             HorizontalOrVerticalPager(
@@ -193,7 +194,7 @@
         // Arrange
         var recomposeCount = 0
         val pageCount = mutableStateOf(2)
-        val state = PagerStateImpl(0, 0f) { pageCount.value }
+        val state = PagerState(0, 0f) { pageCount.value }
         assertThat(state.pageCount).isEqualTo(pageCount.value)
 
         rule.setContent {
@@ -225,7 +226,7 @@
     fun pageCountDecreased_currentPageIsAdjustedAccordingly() {
         // Arrange
         val pageCount = mutableStateOf(5)
-        val state = PagerStateImpl(0, 0f) { pageCount.value }
+        val state = PagerState(0, 0f) { pageCount.value }
         assertThat(state.pageCount).isEqualTo(pageCount.value)
 
         rule.setContent {
@@ -318,7 +319,7 @@
     fun pagerStateChange_flingBehaviorShouldRecreate() {
         var previousFlingBehavior: SnapFlingBehavior? = null
         var latestFlingBehavior: SnapFlingBehavior? = null
-        val stateHolder = mutableStateOf(PagerStateImpl(0, 0.0f) { 10 })
+        val stateHolder = mutableStateOf(PagerState(0, 0.0f) { 10 })
         rule.setContent {
             HorizontalOrVerticalPager(
                 modifier = Modifier
@@ -338,7 +339,7 @@
         }
 
         rule.runOnIdle {
-            stateHolder.value = PagerStateImpl(0, 0.0f) { 20 }
+            stateHolder.value = PagerState(0, 0.0f) { 20 }
         }
 
         rule.waitForIdle()
@@ -358,6 +359,131 @@
         confirmPageIsInCorrectPosition(0, pageToVerifyPosition = 2)
     }
 
+    @Test
+    fun snapPositionChanges_shouldReLayoutPages() {
+        val snapPosition = mutableStateOf(SnapPosition.Start)
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                modifier = Modifier
+                    .fillMaxSize()
+                    .testTag(PagerTestTag)
+                    .onSizeChanged { pagerSize = if (vertical) it.height else it.width },
+                state = rememberPagerState(initialPage = 5) {
+                    40
+                }.also {
+                    pagerState = it
+                },
+                pageSize = PageSize.Fixed(250.dp), // make sure pages bleed in the layout
+                snapPosition = snapPosition.value
+            ) {
+                Page(index = it)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.first().index).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.first().offset).isEqualTo(0)
+        }
+
+        rule.runOnUiThread {
+            snapPosition.value = SnapPosition.End
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().index).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().offset)
+                .isEqualTo(pagerSize - pageSize)
+        }
+    }
+
+    @Test
+    fun pagerSizeChanges_shouldReLayoutPagesAccordingToSnapPosition() {
+        val pagerSizeDp = mutableStateOf(500.dp)
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                modifier = Modifier
+                    .mainAxisSize(pagerSizeDp.value)
+                    .testTag(PagerTestTag)
+                    .onSizeChanged { pagerSize = if (vertical) it.height else it.width },
+                state = rememberPagerState(initialPage = 5) {
+                    40
+                }.also {
+                    pagerState = it
+                },
+                pageSize = PageSize.Fixed(100.dp),
+                snapPosition = SnapPosition.Center // snap position that depends on pager size
+            ) {
+                Page(index = it)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isEqualTo(5)
+            val page = pagerState.layoutInfo.visiblePagesInfo.first { it.index == 5 }
+            // page is centered
+            assertThat(page.offset).isEqualTo(pagerSize / 2 - pageSize / 2)
+        }
+
+        val previousPagerSize = pagerSize
+        rule.runOnUiThread {
+            pagerSizeDp.value = 300.dp
+        }
+
+        // make sure we continue in the same place
+        rule.runOnIdle {
+            assertThat(pagerSize).isNotEqualTo(previousPagerSize) // make sure pager size changed
+            assertThat(pagerState.currentPage).isEqualTo(5)
+            val page = pagerState.layoutInfo.visiblePagesInfo.first { it.index == 5 }
+            // page is centered
+            assertThat(page.offset).isEqualTo(pagerSize / 2 - pageSize / 2)
+        }
+    }
+
+    @Test
+    fun pageSizeChanges_shouldReLayoutPagesAccordingToSnapPosition() {
+        val pageSizeDp = mutableStateOf(PageSize.Fixed(200.dp))
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                modifier = Modifier
+                    .fillMaxSize()
+                    .testTag(PagerTestTag)
+                    .onSizeChanged { pagerSize = if (vertical) it.height else it.width },
+                state = rememberPagerState(initialPage = 5) {
+                    40
+                }.also {
+                    pagerState = it
+                },
+                pageSize = pageSizeDp.value,
+                snapPosition = SnapPosition.End // snap position that depends on page size
+            ) {
+                Page(index = it)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(pagerState.currentPage).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().index).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().offset)
+                .isEqualTo(pagerSize - pageSize)
+        }
+
+        val previousPageSize = pageSize
+        rule.runOnUiThread {
+            pageSizeDp.value = PageSize.Fixed(250.dp)
+        }
+
+        // make sure we continue in the same place
+        rule.runOnIdle {
+            assertThat(pageSize).isNotEqualTo(previousPageSize) // make sure page size changed
+            assertThat(pagerState.currentPage).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().index).isEqualTo(5)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().offset)
+                .isEqualTo(pagerSize - pageSize)
+        }
+    }
+
     companion object {
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt
index 5b384af..74078e3 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt
@@ -26,6 +26,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.setFocusableContent
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.runtime.getValue
@@ -548,7 +549,7 @@
         lateinit var focusManager: FocusManager
         lateinit var inputModeManager: InputModeManager
 
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             focusManager = LocalFocusManager.current
             inputModeManager = LocalInputModeManager.current
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt
index 4174820..312e6b5 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt
@@ -29,6 +29,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.setFocusableContent
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.runtime.getValue
@@ -640,7 +641,7 @@
         lateinit var focusManager: FocusManager
         lateinit var inputModeManager: InputModeManager
 
-        rule.setContent {
+        rule.setFocusableContent {
             scope = rememberCoroutineScope()
             focusManager = LocalFocusManager.current
             inputModeManager = LocalInputModeManager.current
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextBrushTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextBrushTest.kt
new file mode 100644
index 0000000..7dc136e
--- /dev/null
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/BasicTextBrushTest.kt
@@ -0,0 +1,173 @@
+/*
+ * 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.compose.foundation.text
+
+import android.os.Build
+import androidx.compose.foundation.background
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertContainsColor
+import androidx.compose.testutils.assertDoesNotContainColor
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.LinearGradientShader
+import androidx.compose.ui.graphics.Shader
+import androidx.compose.ui.graphics.ShaderBrush
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class BasicTextBrushTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    private val TAG = "TAG"
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun toggleSolidColorBrush() {
+        val colorState = mutableStateOf<Brush>(SolidColor(Color.Red))
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                BasicText(
+                    text = "Hello",
+                    style = TextStyle(
+                        brush = colorState.value,
+                        fontFamily = TEST_FONT_FAMILY,
+                        fontSize = 20.sp
+                    ),
+                    modifier = Modifier
+                        .background(Color.Black)
+                        .testTag(TAG)
+                )
+            }
+        }
+
+        with(rule.onNodeWithTag(TAG).captureToImage()) {
+            assertContainsColor(Color.Black)
+            assertContainsColor(Color.Red)
+            assertDoesNotContainColor(Color.Blue)
+        }
+
+        colorState.value = SolidColor(Color.Blue)
+
+        with(rule.onNodeWithTag(TAG).captureToImage()) {
+            assertContainsColor(Color.Black)
+            assertContainsColor(Color.Blue)
+            assertDoesNotContainColor(Color.Red)
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun togglePredefinedShaderBrush() {
+        val brushState = mutableStateOf(Brush.horizontalGradient(listOf(Color.Red, Color.Red)))
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                BasicText(
+                    text = "Hello",
+                    style = TextStyle(
+                        brush = brushState.value,
+                        fontFamily = TEST_FONT_FAMILY,
+                        fontSize = 20.sp
+                    ),
+                    modifier = Modifier
+                        .background(Color.Black)
+                        .testTag(TAG)
+                )
+            }
+        }
+
+        with(rule.onNodeWithTag(TAG).captureToImage()) {
+            assertContainsColor(Color.Black)
+            assertContainsColor(Color.Red)
+            assertDoesNotContainColor(Color.Blue)
+        }
+
+        brushState.value = Brush.horizontalGradient(listOf(Color.Blue, Color.Blue))
+
+        with(rule.onNodeWithTag(TAG).captureToImage()) {
+            assertContainsColor(Color.Black)
+            assertContainsColor(Color.Blue)
+            assertDoesNotContainColor(Color.Red)
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun toggleCustomShaderBrush() {
+        var color by mutableStateOf(Color.Red)
+        val brush = object : ShaderBrush() {
+            override fun createShader(size: Size): Shader {
+                return LinearGradientShader(
+                    Offset.Zero,
+                    Offset(200f, 200f),
+                    listOf(color, color),
+                )
+            }
+        }
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                BasicText(
+                    text = "Hello",
+                    style = TextStyle(
+                        brush = brush,
+                        fontFamily = TEST_FONT_FAMILY,
+                        fontSize = 20.sp
+                    ),
+                    modifier = Modifier
+                        .background(Color.Black)
+                        .testTag(TAG)
+                )
+            }
+        }
+
+        with(rule.onNodeWithTag(TAG).captureToImage()) {
+            assertContainsColor(Color.Black)
+            assertContainsColor(Color.Red)
+            assertDoesNotContainColor(Color.Blue)
+        }
+
+        color = Color.Blue
+
+        with(rule.onNodeWithTag(TAG).captureToImage()) {
+            assertContainsColor(Color.Black)
+            assertContainsColor(Color.Blue)
+            assertDoesNotContainColor(Color.Red)
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
index 6860c1a..489b3e2 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
@@ -19,6 +19,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.setFocusableContent
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -370,7 +371,7 @@
         lateinit var textLayoutResult: TextLayoutResult
         val focusRequester = FocusRequester()
 
-        setContent {
+        setContent(extraItemForInitialFocus = false) {
             CoreTextField(
                 value = value,
                 modifier = Modifier.focusRequester(focusRequester),
@@ -400,7 +401,7 @@
         lateinit var textLayoutResult: TextLayoutResult
         val focusRequester = FocusRequester()
 
-        setContent {
+        setContent(extraItemForInitialFocus = false) {
             Box(Modifier.offset { offset }) {
                 CoreTextField(
                     value = value,
@@ -440,7 +441,7 @@
         var value by mutableStateOf(TextFieldValue(""))
         lateinit var textLayoutResult: TextLayoutResult
 
-        setContent {
+        setContent(extraItemForInitialFocus = false) {
             CoreTextField(
                 value = value,
                 modifier = Modifier.testTag(tag),
@@ -494,7 +495,7 @@
         val focusRequester = FocusRequester()
         val matrix = Matrix()
 
-        setContent {
+        setContent(extraItemForInitialFocus = false) {
             Box(Modifier.offset { offset }) {
                 CoreTextField(value = value,
                     modifier = Modifier.focusRequester(focusRequester),
@@ -539,8 +540,11 @@
         }
     }
 
-    private fun setContent(content: @Composable () -> Unit) {
-        rule.setContent {
+    private fun setContent(
+        extraItemForInitialFocus: Boolean = true,
+        content: @Composable () -> Unit
+    ) {
+        rule.setFocusableContent(extraItemForInitialFocus) {
             focusManager = LocalFocusManager.current
             CompositionLocalProvider(
                 LocalTextInputService provides textInputService,
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/FontScalingScreenshotTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/FontScalingScreenshotTest.kt
index c7eae7a..f83cf84 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/FontScalingScreenshotTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/FontScalingScreenshotTest.kt
@@ -24,7 +24,6 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.testutils.assertAgainstGolden
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.captureToImage
@@ -41,7 +40,6 @@
 import androidx.compose.ui.text.style.LineHeightStyle
 import androidx.compose.ui.text.style.LineHeightStyle.Alignment
 import androidx.compose.ui.text.style.LineHeightStyle.Trim
-import androidx.compose.ui.unit.DisableNonLinearFontScalingInCompose
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.em
 import androidx.compose.ui.unit.sp
@@ -58,7 +56,6 @@
 @MediumTest
 @RunWith(AndroidJUnit4::class)
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
-@OptIn(ExperimentalComposeUiApi::class)
 class FontScalingScreenshotTest {
     @get:Rule
     val rule = createAndroidComposeRule<ComponentActivity>()
@@ -71,7 +68,6 @@
     @After
     fun teardown() {
         AndroidFontScaleHelper.resetSystemFontScale(rule.activityRule.scenario)
-        DisableNonLinearFontScalingInCompose = false
     }
 
     @Test
@@ -184,40 +180,6 @@
             .assertAgainstGolden(screenshotRule, "fontScaling2x_drawText")
     }
 
-    @Test
-    fun fontScaling2x_DisableNonLinearFontScalingFlag_lineHeightDoubleSp() {
-        DisableNonLinearFontScalingInCompose = true
-        AndroidFontScaleHelper.setSystemFontScale(2f, rule.activityRule.scenario)
-        rule.waitForIdle()
-
-        rule.setContent {
-            TestLayout(lineHeight = 28.sp)
-        }
-        rule.onNodeWithTag(containerTag)
-            .captureToImage()
-            .assertAgainstGolden(
-                screenshotRule,
-                "fontScaling2x_DisableNonLinearFontScalingFlag_lineHeightDoubleSp"
-            )
-    }
-
-    @Test
-    fun fontScaling2x_DisableNonLinearFontScalingFlag_drawText() {
-        DisableNonLinearFontScalingInCompose = true
-        AndroidFontScaleHelper.setSystemFontScale(2f, rule.activityRule.scenario)
-        rule.waitForIdle()
-
-        rule.setContent {
-            TestDrawTextLayout()
-        }
-        rule.onNodeWithTag(containerTag)
-            .captureToImage()
-            .assertAgainstGolden(
-                screenshotRule,
-                "fontScaling2x_DisableNonLinearFontScalingFlag_drawText"
-            )
-    }
-
     @Composable
     private fun TestLayout(
         lineHeight: TextUnit,
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2ImmIntegrationTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2ImmIntegrationTest.kt
index ce06e74..d6aedab 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2ImmIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2ImmIntegrationTest.kt
@@ -17,6 +17,10 @@
 package androidx.compose.foundation.text2
 
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.focusable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.foundation.text2.input.InputTransformation
 import androidx.compose.foundation.text2.input.TextFieldBuffer
@@ -44,6 +48,7 @@
 import androidx.compose.ui.test.requestFocus
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.SmallTest
@@ -95,14 +100,14 @@
     @Test
     fun stopsBeingTextEditor_whenFocusLost() {
         val state = TextFieldState()
-        var focusManager: FocusManager? = null
+        lateinit var focusManager: FocusManager
         inputMethodInterceptor.setTextFieldTestContent {
             focusManager = LocalFocusManager.current
             BasicTextField2(state, Modifier.testTag(Tag))
         }
         requestFocus(Tag)
         rule.runOnIdle {
-            focusManager!!.clearFocus()
+            focusManager.clearFocus()
         }
         inputMethodInterceptor.assertNoSessionActive()
     }
@@ -215,6 +220,7 @@
 
             commitText("hello", 1)
 
+            @Suppress("SpellCheckingInspection")
             assertThat(state.text.toString()).isEqualTo("helloworld")
         }
 
@@ -408,6 +414,12 @@
         override val isWindowFocused = true
     }
     this.setContent {
-        CompositionLocalProvider(LocalWindowInfo provides windowInfo, content)
+        CompositionLocalProvider(LocalWindowInfo provides windowInfo) {
+            Row {
+                // Extra focusable that takes initial focus when focus is cleared.
+                Box(Modifier.size(10.dp).focusable())
+                Box { content() }
+            }
+        }
     }
 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2Test.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2Test.kt
index fc37758..29b37de 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2Test.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/BasicTextField2Test.kt
@@ -46,11 +46,14 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.platform.ClipboardManager
+import androidx.compose.ui.platform.LocalClipboardManager
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalSoftwareKeyboardController
 import androidx.compose.ui.platform.LocalWindowInfo
 import androidx.compose.ui.platform.WindowInfo
 import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsProperties.TextSelectionRange
 import androidx.compose.ui.semantics.getOrNull
 import androidx.compose.ui.test.ExperimentalTestApi
@@ -59,9 +62,11 @@
 import androidx.compose.ui.test.assertIsNotFocused
 import androidx.compose.ui.test.assertTextEquals
 import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.longClick
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performKeyInput
+import androidx.compose.ui.test.performSemanticsAction
 import androidx.compose.ui.test.performTextInput
 import androidx.compose.ui.test.performTextInputSelection
 import androidx.compose.ui.test.performTextReplacement
@@ -1150,6 +1155,36 @@
         }
     }
 
+    // Regression test for b/311834126
+    @Test
+    fun whenPastingTextThatIncreasesEndOffset_noCrashAndCursorAtEndOfPastedText() {
+        val longText = "Text".repeat(4)
+        val shortText = "Text".repeat(2)
+
+        lateinit var tfs: TextFieldState
+        lateinit var clipboardManager: ClipboardManager
+        inputMethodInterceptor.setTextFieldTestContent {
+            tfs = rememberTextFieldState(shortText)
+            clipboardManager = LocalClipboardManager.current
+            BasicTextField2(
+                state = tfs,
+                modifier = Modifier.testTag(Tag),
+            )
+        }
+        clipboardManager.setText(AnnotatedString(longText))
+        rule.waitForIdle()
+
+        val node = rule.onNodeWithTag(Tag)
+        node.performTouchInput { longClick(center) }
+        rule.waitForIdle()
+
+        node.performSemanticsAction(SemanticsActions.PasteText) { it() }
+        rule.waitForIdle()
+
+        assertThat(tfs.text.toString()).isEqualTo(longText)
+        assertThat(tfs.text.selectionInChars).isEqualTo(TextRange(longText.length))
+    }
+
     private fun requestFocus(tag: String) =
         rule.onNodeWithTag(tag).requestFocus()
 
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
index 51379d4..122622c 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
@@ -66,7 +66,10 @@
 import androidx.compose.ui.graphics.Shadow
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.toPixelMap
+import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.ClipboardManager
+import androidx.compose.ui.platform.LocalClipboardManager
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalFocusManager
 import androidx.compose.ui.platform.LocalFontFamilyResolver
@@ -93,9 +96,11 @@
 import androidx.compose.ui.test.isNotFocused
 import androidx.compose.ui.test.junit4.StateRestorationTester
 import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.longClick
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performImeAction
+import androidx.compose.ui.test.performKeyInput
 import androidx.compose.ui.test.performSemanticsAction
 import androidx.compose.ui.test.performTextClearance
 import androidx.compose.ui.test.performTextInput
@@ -1479,6 +1484,40 @@
         assertThat(actual).isEqualTo(TextRange(0))
     }
 
+    // Regression test for b/311834126
+    @Test
+    fun whenPastingTextThatIncreasesEndOffset_noCrashAndCursorAtEndOfPastedText() {
+        val longText = "Text".repeat(4)
+        val shortText = "Text".repeat(2)
+
+        var tfv by mutableStateOf(TextFieldValue(shortText))
+        lateinit var clipboardManager: ClipboardManager
+        rule.setTextFieldTestContent {
+            clipboardManager = LocalClipboardManager.current
+            BasicTextField(
+                value = tfv,
+                onValueChange = { tfv = it },
+                modifier = Modifier.testTag(Tag)
+            )
+        }
+        clipboardManager.setText(AnnotatedString(longText))
+        rule.waitForIdle()
+
+        val node = rule.onNodeWithTag(Tag)
+        node.performTouchInput { longClick(center) }
+        rule.waitForIdle()
+
+        node.performSemanticsAction(SemanticsActions.PasteText) { it() }
+        rule.waitForIdle()
+
+        val expectedTfv = TextFieldValue(
+            text = longText,
+            selection = TextRange(longText.length)
+        )
+        assertThat(tfv.text).isEqualTo(expectedTfv.text)
+        assertThat(tfv.selection).isEqualTo(expectedTfv.selection)
+    }
+
     @Test
     fun decorationBoxIntrinsics() {
         var size: IntSize? = null
@@ -1556,6 +1595,57 @@
 
         rule.onNodeWithTag(decorationTag, true).assertDoesNotExist()
     }
+
+    // Regression test for b/311007530
+    @OptIn(ExperimentalTestApi::class)
+    @Test
+    fun whenToggleReadOnly_onEditedTextField_noChangeNorCrash() {
+        val tag = "tag"
+
+        val text = "text"
+        val tfv = TextFieldValue(
+            text = text,
+            selection = TextRange(text.length)
+        )
+
+        val textAfterBackspace = text.run { substring(0, length - 1) }
+        val tfvAfterBackspace = TextFieldValue(
+            text = textAfterBackspace,
+            selection = TextRange(textAfterBackspace.length),
+        )
+
+        var value by mutableStateOf(tfv)
+        var readOnly by mutableStateOf(false)
+        rule.setTextFieldTestContent {
+            BasicTextField(
+                value = value,
+                onValueChange = { value = it },
+                readOnly = readOnly,
+                modifier = Modifier.testTag(tag),
+            )
+        }
+        val node = rule.onNodeWithTag(tag)
+        // gain focus and place cursor at end of text
+        node.performTouchInput { click(centerRight - Offset(5f, 0f)) }
+        rule.waitForIdle()
+        assertThat(value.text).isEqualTo(tfv.text)
+        assertThat(value.selection).isEqualTo(tfv.selection)
+
+        node.performKeyInput { keyDown(Key.Backspace) }
+        rule.waitForIdle()
+        assertThat(value.text).isEqualTo(tfvAfterBackspace.text)
+        assertThat(value.selection).isEqualTo(tfvAfterBackspace.selection)
+
+        rule.runOnUiThread { readOnly = true }
+        rule.waitForIdle()
+        assertThat(value.text).isEqualTo(tfvAfterBackspace.text)
+        assertThat(value.selection).isEqualTo(tfvAfterBackspace.selection)
+
+        rule.runOnUiThread { readOnly = false }
+        rule.waitForIdle()
+        assertThat(value.text).isEqualTo(tfvAfterBackspace.text)
+        assertThat(value.selection).isEqualTo(tfvAfterBackspace.selection)
+    }
 }
 
 private fun SemanticsNodeInteraction.assertEditableTextEquals(
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt
index 766c37e..f83f030 100644
--- a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt
+++ b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt
@@ -16,11 +16,11 @@
 
 package androidx.compose.foundation.text
 
-import androidx.compose.ui.text.input.AndroidImeOptions
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.ImeOptions
 import androidx.compose.ui.text.input.KeyboardCapitalization
 import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.PlatformImeOptions
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -31,7 +31,7 @@
 
     @Test
     fun test_toImeOption() {
-        val platformImeOptions = AndroidImeOptions("privateImeOptions")
+        val platformImeOptions = PlatformImeOptions("privateImeOptions")
 
         val keyboardOptions = KeyboardOptions(
             keyboardType = KeyboardType.Number,
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
index 012152c..591b4d6 100644
--- a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.foundation.text.HandleState
 import androidx.compose.foundation.text.InternalFoundationTextApi
+import androidx.compose.foundation.text.TextDelegate
 import androidx.compose.foundation.text.TextFieldState
 import androidx.compose.foundation.text.TextLayoutResultProxy
 import androidx.compose.ui.focus.FocusRequester
@@ -63,6 +64,7 @@
 @RunWith(JUnit4::class)
 class TextFieldSelectionManagerTest {
     private val text = "Hello World"
+    private val textAnnotatedString = AnnotatedString(text)
     private val density = Density(density = 1f)
     private val offsetMapping = OffsetMapping.Identity
     private val maxLines = 2
@@ -100,7 +102,7 @@
 
         whenever(layoutResult.layoutInput).thenReturn(
             TextLayoutInput(
-                text = AnnotatedString(text),
+                text = textAnnotatedString,
                 style = TextStyle.Default,
                 placeholders = mock(),
                 maxLines = maxLines,
@@ -135,8 +137,12 @@
 
         whenever(layoutResultProxy.value).thenReturn(layoutResult)
 
+        val textDelegate = mock<TextDelegate> {
+            on { this.text }.thenReturn(textAnnotatedString)
+        }
+
         state = TextFieldState(
-            textDelegate = mock(),
+            textDelegate = textDelegate,
             recomposeScope = mock(),
             keyboardController = null
         )
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt
index 4b3e83b..03f9dbe 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalFoundationApi::class)
-
 package androidx.compose.foundation
 
 import androidx.compose.animation.core.Animatable
@@ -71,27 +69,17 @@
 import kotlinx.coroutines.withContext
 
 // From https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/widget/TextView.java;l=736;drc=6d97d6d7215fef247d1a90e05545cac3676f9212
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@ExperimentalFoundationApi
-@get:ExperimentalFoundationApi
+@Suppress("MayBeConstant")
 val DefaultMarqueeIterations: Int = 3
 
 // From https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/widget/TextView.java;l=13979;drc=6d97d6d7215fef247d1a90e05545cac3676f9212
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@ExperimentalFoundationApi
-@get:ExperimentalFoundationApi
+@Suppress("MayBeConstant")
 val DefaultMarqueeDelayMillis: Int = 1_200
 
 // From https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/widget/TextView.java;l=14088;drc=6d97d6d7215fef247d1a90e05545cac3676f9212
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@ExperimentalFoundationApi
-@get:ExperimentalFoundationApi
 val DefaultMarqueeSpacing: MarqueeSpacing = MarqueeSpacing.fractionOfContainer(1f / 3f)
 
 // From https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/widget/TextView.java;l=13980;drc=6d97d6d7215fef247d1a90e05545cac3676f9212
-@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-@ExperimentalFoundationApi
-@get:ExperimentalFoundationApi
 val DefaultMarqueeVelocity: Dp = 30.dp
 
 /**
@@ -132,12 +120,8 @@
  * @param spacing A [MarqueeSpacing] that specifies how much space to leave at the end of the
  * content before showing the beginning again.
  * @param velocity The speed of the animation in dps / second.
- *
- * Note: this modifier and corresponding APIs are experimental pending some refinements in the API
- * surface, mostly related to customisation params.
  */
 @Stable
-@ExperimentalFoundationApi
 fun Modifier.basicMarquee(
     iterations: Int = DefaultMarqueeIterations,
     animationMode: MarqueeAnimationMode = Immediately,
@@ -433,7 +417,6 @@
 }
 
 /** Specifies when the [basicMarquee] animation runs. */
-@ExperimentalFoundationApi
 @JvmInline
 value class MarqueeAnimationMode private constructor(private val value: Int) {
 
@@ -448,17 +431,11 @@
          * Starts animating immediately (accounting for any initial delay), irrespective of focus
          * state.
          */
-        @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-        @ExperimentalFoundationApi
-        @get:ExperimentalFoundationApi
         val Immediately = MarqueeAnimationMode(0)
 
         /**
          * Only animates while the marquee has focus or a node in the marquee's content has focus.
          */
-        @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
-        @ExperimentalFoundationApi
-        @get:ExperimentalFoundationApi
         val WhileFocused = MarqueeAnimationMode(1)
     }
 }
@@ -466,14 +443,12 @@
 /**
  * A [MarqueeSpacing] with a fixed size.
  */
-@ExperimentalFoundationApi
 fun MarqueeSpacing(spacing: Dp): MarqueeSpacing = MarqueeSpacing { _, _ -> spacing.roundToPx() }
 
 /**
  * Defines a [calculateSpacing] method that determines the space after the end of [basicMarquee]
  * content before drawing the content again.
  */
-@ExperimentalFoundationApi
 @Stable
 fun interface MarqueeSpacing {
     /**
@@ -490,7 +465,6 @@
      * @return The space in pixels between the end of the content and the beginning of the content
      * when wrapping.
      */
-    @ExperimentalFoundationApi
     fun Density.calculateSpacing(
         contentWidth: Int,
         containerWidth: Int
@@ -500,7 +474,6 @@
         /**
          * A [MarqueeSpacing] that is a fraction of the container's width.
          */
-        @ExperimentalFoundationApi
         fun fractionOfContainer(fraction: Float): MarqueeSpacing = MarqueeSpacing { _, width ->
             (fraction * width).roundToInt()
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
index de6e3e6..aed5624 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
@@ -16,13 +16,13 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.HoverInteraction
+import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.InteractionSource
-import androidx.compose.foundation.interaction.collectIsFocusedAsState
-import androidx.compose.foundation.interaction.collectIsHoveredAsState
-import androidx.compose.foundation.interaction.collectIsPressedAsState
+import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.Modifier
@@ -30,15 +30,22 @@
 import androidx.compose.ui.draw.DrawModifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DelegatingNode
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.invalidateDraw
+import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.platform.debugInspectorInfo
+import kotlinx.coroutines.launch
 
 /**
  * Indication represents visual effects that occur when certain interactions happens. For
  * example: showing a ripple effect when a component is pressed, or a highlight when a component
  * is focused.
  *
- * An instance of Indication is a factory that is required to produce [IndicationInstance]s on
- * demand for each component that uses an [indication] modifier using [rememberUpdatedInstance].
+ * To implement your own Indication, see [IndicationNodeFactory] - an optimized [Indication] that
+ * allows for more efficient implementations than the deprecated [rememberUpdatedInstance].
  *
  * Indication is typically provided throughout the hierarchy through [LocalIndication] - you can
  * provide a custom Indication to [LocalIndication] to change the default [Indication] used for
@@ -62,8 +69,66 @@
      * @return an [IndicationInstance] that represents the stream of [Interaction]s emitted by
      * [interactionSource]
      */
+    @Suppress("DEPRECATION_ERROR")
+    @Deprecated(RememberUpdatedInstanceDeprecationMessage, level = DeprecationLevel.ERROR)
     @Composable
-    fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance
+    fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance =
+        NoIndicationInstance
+}
+
+/**
+ * IndicationNodeFactory is an Indication that creates [Modifier.Node] instances to render visual
+ * effects that occur when certain interactions happens. For example: showing a ripple effect
+ * when a component is pressed, or a highlight when a component is focused.
+ *
+ * An instance of IndicationNodeFactory is responsible for creating individual nodes on demand for
+ * each component that needs to render indication. IndicationNodeFactory instances should be very
+ * simple - they just hold the relevant configuration properties needed to create the node instances
+ * that are responsible for drawing visual effects.
+ *
+ * IndicationNodeFactory is conceptually similar to [ModifierNodeElement] - it is designed to be
+ * able to be created outside of composition, and re-used in multiple places.
+ *
+ * Indication is typically provided throughout the hierarchy through [LocalIndication] - you can
+ * provide a custom Indication to [LocalIndication] to change the default [Indication] used for
+ * components such as [clickable].
+ */
+@Stable
+interface IndicationNodeFactory : Indication {
+    /**
+     * Creates a node that will be applied to a specific component and render indication for the
+     * provided [interactionSource]. This method will be re-invoked for a given layout node if a new
+     * [interactionSource] is provided or if [hashCode] or [equals] change for this
+     * IndicationNodeFactory over time, allowing a new node to be created using the new properties
+     * in this IndicationNodeFactory. If you instead want to gracefully update the existing node
+     * over time, consider replacing those properties with [androidx.compose.runtime.State]
+     * properties, so when the value of the State changes, [equals] and [hashCode] remain the
+     * same, and the same node instance can just query the updated state value.
+     *
+     * The returned [DelegatableNode] should implement [DrawModifierNode], or delegate to a node
+     * that implements [DrawModifierNode], so that it can draw visual effects. Inside
+     * [DrawModifierNode.draw], make sure to call [ContentDrawScope.drawContent] to render the
+     * component in addition to any visual effects.
+     *
+     * @param interactionSource the [InteractionSource] representing the stream of
+     * [Interaction]s the returned node should render visual effects for
+     * @return a [DelegatableNode] that renders visual effects for the provided [interactionSource]
+     * by also implementing / delegating to a [DrawModifierNode]
+     */
+    fun create(interactionSource: InteractionSource): DelegatableNode
+
+    /**
+     * Require hashCode() to be implemented. Using a data class is sufficient. Singletons and
+     * instances with no properties may implement this function by returning an arbitrary constant.
+     */
+    override fun hashCode(): Int
+
+    /**
+     * Require equals() to be implemented. Using a data class is sufficient. Singletons may
+     * implement this function with referential equality (`this === other`). Instances with no
+     * properties may implement this function by checking the type of the other object.
+     */
+    override fun equals(other: Any?): Boolean
 }
 
 /**
@@ -74,6 +139,7 @@
  * [Indication.rememberUpdatedInstance] - they should be used in-place and not re-used between
  * different [indication] modifiers.
  */
+@Deprecated(IndicationInstanceDeprecationMessage, level = DeprecationLevel.ERROR)
 interface IndicationInstance {
 
     /**
@@ -104,76 +170,173 @@
 fun Modifier.indication(
     interactionSource: InteractionSource,
     indication: Indication?
-) = composed(
-    factory = {
-        val resolvedIndication = indication ?: NoIndication
-        val instance = resolvedIndication.rememberUpdatedInstance(interactionSource)
-        remember(instance) {
-            IndicationModifier(instance)
-        }
-    },
-    inspectorInfo = debugInspectorInfo {
-        name = "indication"
-        properties["indication"] = indication
-        properties["interactionSource"] = interactionSource
+): Modifier {
+    if (indication == null) return this
+    // Fast path - ideally we should never break into the composed path below.
+    if (indication is IndicationNodeFactory) {
+        return this.then(IndicationModifierElement(interactionSource, indication))
     }
-)
+    // In the future we might want to remove this as a forcing function to migrate away from the
+    // error-deprecated rememberUpdatedInstance
+    return composed(
+        factory = {
+            @Suppress("DEPRECATION_ERROR")
+            val instance = indication.rememberUpdatedInstance(interactionSource)
+            remember(instance) {
+                IndicationModifier(instance)
+            }
+        },
+        inspectorInfo = debugInspectorInfo {
+            name = "indication"
+            properties["interactionSource"] = interactionSource
+            properties["indication"] = indication
+        }
+    )
+}
 
 /**
  * CompositionLocal that provides an [Indication] through the hierarchy. This [Indication] will
  * be used by default to draw visual effects for interactions such as press and drag in components
  * such as [clickable].
  *
- * By default this will provide [DefaultDebugIndication].
+ * By default this will provide a debug indication, this should always be replaced.
  */
 val LocalIndication = staticCompositionLocalOf<Indication> {
     DefaultDebugIndication
 }
 
-private object NoIndication : Indication {
-    private object NoIndicationInstance : IndicationInstance {
-        override fun ContentDrawScope.drawIndication() {
-            drawContent()
-        }
-    }
-
-    @Composable
-    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
-        return NoIndicationInstance
+/**
+ * Empty [IndicationInstance] for backwards compatibility - this is not expected to be used.
+ */
+@Suppress("DEPRECATION_ERROR")
+private object NoIndicationInstance : IndicationInstance {
+    override fun ContentDrawScope.drawIndication() {
+        drawContent()
     }
 }
 
 /**
  * Simple default [Indication] that draws a rectangular overlay when pressed.
  */
-private object DefaultDebugIndication : Indication {
+private object DefaultDebugIndication : IndicationNodeFactory {
 
-    private class DefaultDebugIndicationInstance(
-        private val isPressed: State<Boolean>,
-        private val isHovered: State<Boolean>,
-        private val isFocused: State<Boolean>,
-    ) : IndicationInstance {
-        override fun ContentDrawScope.drawIndication() {
+    override fun create(interactionSource: InteractionSource): DelegatableNode =
+        DefaultDebugIndicationInstance(interactionSource)
+
+    override fun hashCode(): Int = -1
+
+    override fun equals(other: Any?) = other === this
+
+    private class DefaultDebugIndicationInstance(private val interactionSource: InteractionSource) :
+        Modifier.Node(), DrawModifierNode {
+        private var isPressed = false
+        private var isHovered = false
+        private var isFocused = false
+        override fun onAttach() {
+            coroutineScope.launch {
+                var pressCount = 0
+                var hoverCount = 0
+                var focusCount = 0
+                interactionSource.interactions.collect { interaction ->
+                    when (interaction) {
+                        is PressInteraction.Press -> pressCount++
+                        is PressInteraction.Release -> pressCount--
+                        is PressInteraction.Cancel -> pressCount--
+                        is HoverInteraction.Enter -> hoverCount++
+                        is HoverInteraction.Exit -> hoverCount--
+                        is FocusInteraction.Focus -> focusCount++
+                        is FocusInteraction.Unfocus -> focusCount--
+                    }
+                    val pressed = pressCount > 0
+                    val hovered = hoverCount > 0
+                    val focused = focusCount > 0
+                    var invalidateNeeded = false
+                    if (isPressed != pressed) {
+                        isPressed = pressed
+                        invalidateNeeded = true
+                    }
+                    if (isHovered != hovered) {
+                        isHovered = hovered
+                        invalidateNeeded = true
+                    }
+                    if (isFocused != focused) {
+                        isFocused = focused
+                        invalidateNeeded = true
+                    }
+                    if (invalidateNeeded) invalidateDraw()
+                }
+            }
+        }
+
+        override fun ContentDrawScope.draw() {
             drawContent()
-            if (isPressed.value) {
+            if (isPressed) {
                 drawRect(color = Color.Black.copy(alpha = 0.3f), size = size)
-            } else if (isHovered.value || isFocused.value) {
+            } else if (isHovered || isFocused) {
                 drawRect(color = Color.Black.copy(alpha = 0.1f), size = size)
             }
         }
     }
+}
 
-    @Composable
-    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
-        val isPressed = interactionSource.collectIsPressedAsState()
-        val isHovered = interactionSource.collectIsHoveredAsState()
-        val isFocused = interactionSource.collectIsFocusedAsState()
-        return remember(interactionSource) {
-            DefaultDebugIndicationInstance(isPressed, isHovered, isFocused)
-        }
+/**
+ * ModifierNodeElement to create [IndicationNodeFactory] instances. More complicated modifiers such
+ * as [clickable] should manually delegate to the node returned by [IndicationNodeFactory]
+ * internally.
+ */
+private class IndicationModifierElement(
+    private val interactionSource: InteractionSource,
+    private val indication: IndicationNodeFactory
+) : ModifierNodeElement<IndicationModifierNode>() {
+    override fun create(): IndicationModifierNode {
+        return IndicationModifierNode(indication.create(interactionSource))
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        name = "indication"
+        properties["interactionSource"] = interactionSource
+        properties["indication"] = indication
+    }
+
+    override fun update(node: IndicationModifierNode) {
+        node.update(indication.create(interactionSource))
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is IndicationModifierElement) return false
+
+        if (interactionSource != other.interactionSource) return false
+        if (indication != other.indication) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = interactionSource.hashCode()
+        result = 31 * result + indication.hashCode()
+        return result
     }
 }
 
+/**
+ * Wrapper [DelegatableNode] that allows us to replace the wrapped node fully when a new node is
+ * provided.
+ */
+private class IndicationModifierNode(private var indicationNode: DelegatableNode) :
+    DelegatingNode() {
+    init {
+        delegate(indicationNode)
+    }
+
+    fun update(indicationNode: DelegatableNode) {
+        undelegate(this.indicationNode)
+        this.indicationNode = indicationNode
+        delegate(indicationNode)
+    }
+}
+
+@Suppress("DEPRECATION_ERROR")
 private class IndicationModifier(
     val indicationInstance: IndicationInstance
 ) : DrawModifier {
@@ -184,3 +347,15 @@
         }
     }
 }
+
+private const val RememberUpdatedInstanceDeprecationMessage = "rememberUpdatedInstance has been " +
+    "deprecated - implementers should instead implement IndicationNodeFactory#create for " +
+    "improved performance and efficiency. Callers should check if the Indication is an " +
+    "IndicationNodeFactory, and call that API instead. For a migration guide and background " +
+    "information, please visit developer.android.com"
+
+private const val IndicationInstanceDeprecationMessage = "IndicationInstance has been deprecated " +
+    "along with the rememberUpdatedInstance that returns it. Indication implementations should " +
+    "instead use Modifier.Node APIs, and should be returned from " +
+    "IndicationNodeFactory#create. For a migration guide and background information, " +
+    "please visit developer.android.com"
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
index f4825f2..9e63e595d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
@@ -58,7 +58,7 @@
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.semantics.verticalScrollAxisRange
 import androidx.compose.ui.unit.Constraints
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 import kotlinx.coroutines.launch
 
 /**
@@ -142,7 +142,7 @@
         val newValue = absolute.coerceIn(0f, maxValue.toFloat())
         val changed = absolute != newValue
         val consumed = newValue - value
-        val consumedInt = consumed.roundToInt()
+        val consumedInt = consumed.fastRoundToInt()
         value += consumedInt
         accumulator = consumed - consumedInt
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
index a18c651..4c6d370 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
@@ -34,7 +34,7 @@
 import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntOffset
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 internal class LazyItemScopeImpl : LazyItemScope {
 
@@ -151,7 +151,7 @@
     ): MeasureResult {
         val width = widthState?.let {
             if (it.value != Constraints.Infinity) {
-                (it.value * fraction).roundToInt()
+                (it.value * fraction).fastRoundToInt()
             } else {
                 Constraints.Infinity
             }
@@ -159,7 +159,7 @@
 
         val height = heightState?.let {
             if (it.value != Constraints.Infinity) {
-                (it.value * fraction).roundToInt()
+                (it.value * fraction).fastRoundToInt()
             } else {
                 Constraints.Infinity
             }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
index 9c84637..d13fe34 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
@@ -30,9 +30,9 @@
 import androidx.compose.ui.util.fastFirstOrNull
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachReversed
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.abs
 import kotlin.math.min
-import kotlin.math.roundToInt
 import kotlin.math.sign
 import kotlinx.coroutines.CoroutineScope
 
@@ -112,7 +112,7 @@
         }
 
         // represents the real amount of scroll we applied as a result of this measure pass.
-        var scrollDelta = scrollToBeConsumed.roundToInt()
+        var scrollDelta = scrollToBeConsumed.fastRoundToInt()
 
         // applying the whole requested scroll offset. we will figure out if we can't consume
         // all of it later
@@ -237,8 +237,8 @@
         // scrollToBeConsumed if there were not enough items to fill the offered space or it
         // can be larger if items were resized, or if, for example, we were previously
         // displaying the item 15, but now we have only 10 items in total in the data set.
-        val consumedScroll = if (scrollToBeConsumed.roundToInt().sign == scrollDelta.sign &&
-            abs(scrollToBeConsumed.roundToInt()) >= abs(scrollDelta)
+        val consumedScroll = if (scrollToBeConsumed.fastRoundToInt().sign == scrollDelta.sign &&
+            abs(scrollToBeConsumed.fastRoundToInt()) >= abs(scrollDelta)
         ) {
             scrollDelta.toFloat()
         } else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt
index f484426..c01b0c9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt
@@ -19,9 +19,7 @@
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.util.fastFirst
 import androidx.compose.ui.util.fastForEach
-import androidx.compose.ui.util.fastLastOrNull
 
 /**
  * The result of the measure pass for lazy list layout.
@@ -86,8 +84,12 @@
         ) {
             return false
         }
-        val first = visibleItemsInfo.fastFirst { !it.nonScrollableItem }
-        val last = visibleItemsInfo.fastLastOrNull { !it.nonScrollableItem }!!
+        val first = visibleItemsInfo.first()
+        val last = visibleItemsInfo.last()
+        if (first.nonScrollableItem || last.nonScrollableItem) {
+            // non scrollable items like headers require special handling in the measurement.
+            return false
+        }
         val canApply = if (delta < 0) {
             // scrolling forward
             val deltaToFirstItemChange =
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
index 2c0b800..350c24b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
@@ -54,8 +54,8 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.abs
-import kotlin.math.roundToInt
 import kotlin.ranges.IntRange
 import kotlin.ranges.until
 import kotlinx.coroutines.CoroutineScope
@@ -326,7 +326,7 @@
         if (abs(scrollToBeConsumed) > 0.5f) {
             val layoutInfo = layoutInfoState.value
             val preScrollToBeConsumed = scrollToBeConsumed
-            val intDelta = scrollToBeConsumed.roundToInt()
+            val intDelta = scrollToBeConsumed.fastRoundToInt()
             val postLookaheadInfo = postLookaheadLayoutInfo
             var scrolledWithoutRemeasure = layoutInfo.tryToApplyScrollWithoutRemeasure(
                 delta = intDelta,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
index 26f0514..daf2c45 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
@@ -359,6 +359,7 @@
             spanLayoutProvider = spanLayoutProvider,
             pinnedItems = pinnedItems,
             coroutineScope = coroutineScope,
+            placementScopeInvalidator = state.placementScopeInvalidator,
             layout = { width, height, placement ->
                 layout(
                     containerConstraints.constrainWidth(width + totalHorizontalPadding),
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
index 19d1f00..0d50108 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.lazy.grid
 
+import androidx.collection.mutableScatterMapOf
 import androidx.compose.foundation.lazy.layout.LazyLayoutAnimation
 import androidx.compose.foundation.lazy.layout.LazyLayoutAnimationSpecsNode
 import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
@@ -33,7 +34,7 @@
  */
 internal class LazyGridItemPlacementAnimator {
     // state containing relevant info for active items.
-    private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
+    private val keyToItemInfoMap = mutableScatterMapOf<Any, ItemInfo>()
 
     // snapshot of the key to index map used for the last measuring.
     private var keyIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
@@ -84,7 +85,7 @@
         }
 
         // first add all items we had in the previous run
-        movingAwayKeys.addAll(keyToItemInfoMap.keys)
+        keyToItemInfoMap.forEachKey { movingAwayKeys.add(it) }
         // iterate through the items which are visible (without animated offsets)
         positionedItems.fastForEach { item ->
             // remove items we have in the current one as they are still visible.
@@ -167,7 +168,7 @@
         movingAwayKeys.forEach { key ->
             // found an item which was in our map previously but is not a part of the
             // positionedItems now
-            val itemInfo = keyToItemInfoMap.getValue(key)
+            val itemInfo = keyToItemInfoMap[key]!!
             val newIndex = keyIndexMap.getIndex(key)
 
             if (newIndex == -1) {
@@ -181,6 +182,7 @@
                         Constraints.fixedHeight(itemInfo.crossAxisSize)
                     }
                 )
+                item.nonScrollableItem = true
                 // check if we have any active placement animation on the item
                 val inProgress =
                     itemInfo.animations.any { it?.isPlacementAnimationInProgress == true }
@@ -211,7 +213,7 @@
             }
             val mainAxisOffset = 0 - accumulatedOffset - item.mainAxisSize
 
-            val itemInfo = keyToItemInfoMap.getValue(item.key)
+            val itemInfo = keyToItemInfoMap[item.key]!!
 
             item.position(
                 mainAxisOffset = mainAxisOffset,
@@ -237,7 +239,7 @@
             }
             val mainAxisOffset = mainAxisLayoutSize + accumulatedOffset
 
-            val itemInfo = keyToItemInfoMap.getValue(item.key)
+            val itemInfo = keyToItemInfoMap[item.key]!!
             item.position(
                 mainAxisOffset = mainAxisOffset,
                 crossAxisOffset = itemInfo.crossAxisOffset,
@@ -269,7 +271,7 @@
     private fun initializeAnimation(
         item: LazyGridMeasuredItem,
         mainAxisOffset: Int,
-        itemInfo: ItemInfo = keyToItemInfoMap.getValue(item.key)
+        itemInfo: ItemInfo = keyToItemInfoMap[item.key]!!
     ) {
         val firstPlaceableOffset = item.offset
 
@@ -290,7 +292,7 @@
     }
 
     private fun startAnimationsIfNeeded(item: LazyGridMeasuredItem) {
-        val itemInfo = keyToItemInfoMap.getValue(item.key)
+        val itemInfo = keyToItemInfoMap[item.key]!!
         itemInfo.animations.forEach { animation ->
             if (animation != null) {
                 val newTarget = item.offset
@@ -305,8 +307,13 @@
         }
     }
 
-    fun getAnimation(key: Any, placeableIndex: Int): LazyLayoutAnimation? =
-        keyToItemInfoMap[key]?.animations?.get(placeableIndex)
+    fun getAnimation(key: Any, placeableIndex: Int): LazyLayoutAnimation? {
+        return if (keyToItemInfoMap.isEmpty()) {
+            null
+        } else {
+            keyToItemInfoMap[key]?.animations?.get(placeableIndex)
+        }
+    }
 
     private val LazyGridMeasuredItem.hasAnimations: Boolean
         get() {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
index f69ead7..9e08bf66 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
@@ -19,6 +19,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.lazy.layout.ObservableScopeInvalidator
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.unit.Constraints
@@ -29,10 +30,10 @@
 import androidx.compose.ui.util.fastFilter
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachReversed
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.compose.ui.util.fastSumBy
 import kotlin.math.abs
 import kotlin.math.min
-import kotlin.math.roundToInt
 import kotlin.math.sign
 import kotlinx.coroutines.CoroutineScope
 
@@ -62,6 +63,7 @@
     spanLayoutProvider: LazyGridSpanLayoutProvider,
     pinnedItems: List<Int>,
     coroutineScope: CoroutineScope,
+    placementScopeInvalidator: ObservableScopeInvalidator,
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): LazyGridMeasureResult {
     require(beforeContentPadding >= 0) { "negative beforeContentPadding" }
@@ -81,14 +83,15 @@
             reverseLayout = reverseLayout,
             orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
             afterContentPadding = afterContentPadding,
-            mainAxisItemSpacing = spaceBetweenLines
+            mainAxisItemSpacing = spaceBetweenLines,
+            remeasureNeeded = false
         )
     } else {
         var currentFirstLineIndex = firstVisibleLineIndex
         var currentFirstLineScrollOffset = firstVisibleLineScrollOffset
 
         // represents the real amount of scroll we applied as a result of this measure pass.
-        var scrollDelta = scrollToBeConsumed.roundToInt()
+        var scrollDelta = scrollToBeConsumed.fastRoundToInt()
 
         // applying the whole requested scroll offset. we will figure out if we can't consume
         // all of it later
@@ -137,10 +140,23 @@
         val maxMainAxis = (maxOffset + afterContentPadding).coerceAtLeast(0)
         var currentMainAxisOffset = -currentFirstLineScrollOffset
 
+        // will be set to true if we composed some items only to know their size and apply scroll,
+        // while in the end this item will not end up in the visible viewport. we will need an
+        // extra remeasure in order to dispose such items.
+        var remeasureNeeded = false
+
         // first we need to skip lines we already composed while composing backward
-        visibleLines.fastForEach {
-            index++
-            currentMainAxisOffset += it.mainAxisSizeWithSpacings
+        var indexInVisibleLines = 0
+        while (indexInVisibleLines < visibleLines.size) {
+            if (currentMainAxisOffset >= maxMainAxis) {
+                // this item is out of the bounds and will not be visible.
+                visibleLines.removeAt(indexInVisibleLines)
+                remeasureNeeded = true
+            } else {
+                index++
+                currentMainAxisOffset += visibleLines[indexInVisibleLines].mainAxisSizeWithSpacings
+                indexInVisibleLines++
+            }
         }
 
         // then composing visible lines forward until we fill the whole viewport.
@@ -159,9 +175,10 @@
             currentMainAxisOffset += measuredLine.mainAxisSizeWithSpacings
             if (currentMainAxisOffset <= minOffset &&
                 measuredLine.items.last().index != itemsCount - 1) {
-                // this line is offscreen and will not be placed. advance firstVisibleLineIndex
+                // this line is offscreen and will not be visible. advance firstVisibleLineIndex
                 currentFirstLineIndex = index + 1
                 currentFirstLineScrollOffset -= measuredLine.mainAxisSizeWithSpacings
+                remeasureNeeded = true
             } else {
                 visibleLines.add(measuredLine)
             }
@@ -195,8 +212,8 @@
         // scrollToBeConsumed if there were not enough lines to fill the offered space or it
         // can be larger if lines were resized, or if, for example, we were previously
         // displaying the line 15, but now we have only 10 lines in total in the data set.
-        val consumedScroll = if (scrollToBeConsumed.roundToInt().sign == scrollDelta.sign &&
-            abs(scrollToBeConsumed.roundToInt()) >= abs(scrollDelta)
+        val consumedScroll = if (scrollToBeConsumed.fastRoundToInt().sign == scrollDelta.sign &&
+            abs(scrollToBeConsumed.fastRoundToInt()) >= abs(scrollDelta)
         ) {
             scrollDelta.toFloat()
         } else {
@@ -285,6 +302,8 @@
             consumedScroll = consumedScroll,
             measureResult = layout(layoutWidth, layoutHeight) {
                 positionedItems.fastForEach { it.place(this) }
+                // we attach it during the placement so LazyGridState can trigger re-placement
+                placementScopeInvalidator.attachToScope()
             },
             viewportStartOffset = -beforeContentPadding,
             viewportEndOffset = mainAxisAvailableSize + afterContentPadding,
@@ -299,7 +318,8 @@
             reverseLayout = reverseLayout,
             orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
             afterContentPadding = afterContentPadding,
-            mainAxisItemSpacing = spaceBetweenLines
+            mainAxisItemSpacing = spaceBetweenLines,
+            remeasureNeeded = remeasureNeeded
         )
     }
 }
@@ -390,7 +410,7 @@
             } else {
                 absoluteOffset
             }
-            positionedItems.addAll(
+            positionedItems.addAllFromArray(
                 line.position(relativeOffset, layoutWidth, layoutHeight)
             )
         }
@@ -405,7 +425,7 @@
 
         currentMainAxis = firstLineScrollOffset
         lines.fastForEach {
-            positionedItems.addAll(it.position(currentMainAxis, layoutWidth, layoutHeight))
+            positionedItems.addAllFromArray(it.position(currentMainAxis, layoutWidth, layoutHeight))
             currentMainAxis += it.mainAxisSizeWithSpacings
         }
 
@@ -417,3 +437,10 @@
     }
     return positionedItems
 }
+
+// Faster version of addAll that does not create a list for each array
+private fun <T> MutableList<T>.addAllFromArray(arr: Array<T>) {
+    for (item in arr) {
+        add(item)
+    }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasureResult.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasureResult.kt
index 00dfd71..49a5139 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasureResult.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasureResult.kt
@@ -16,30 +16,32 @@
 
 package androidx.compose.foundation.lazy.grid
 
-import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.snapping.offsetOnMainAxis
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.util.fastForEach
 
 /**
  * The result of the measure pass for lazy list layout.
  */
-@OptIn(ExperimentalFoundationApi::class)
 internal class LazyGridMeasureResult(
     // properties defining the scroll position:
     /** The new first visible line of items.*/
     val firstVisibleLine: LazyGridMeasuredLine?,
     /** The new value for [LazyGridState.firstVisibleItemScrollOffset].*/
-    val firstVisibleLineScrollOffset: Int,
+    var firstVisibleLineScrollOffset: Int,
     /** True if there is some space available to continue scrolling in the forward direction.*/
-    val canScrollForward: Boolean,
+    var canScrollForward: Boolean,
     /** The amount of scroll consumed during the measure pass.*/
-    val consumedScroll: Float,
+    var consumedScroll: Float,
     /** MeasureResult defining the layout.*/
     measureResult: MeasureResult,
+    /** True when extra remeasure is required. */
+    val remeasureNeeded: Boolean,
     // properties representing the info needed for LazyListLayoutInfo:
     /** see [LazyGridLayoutInfo.visibleItemsInfo] */
-    override val visibleItemsInfo: List<LazyGridItemInfo>,
+    override val visibleItemsInfo: List<LazyGridMeasuredItem>,
     /** see [LazyGridLayoutInfo.viewportStartOffset] */
     override val viewportStartOffset: Int,
     /** see [LazyGridLayoutInfo.viewportEndOffset] */
@@ -55,7 +57,67 @@
     /** see [LazyGridLayoutInfo.mainAxisItemSpacing] */
     override val mainAxisItemSpacing: Int
 ) : LazyGridLayoutInfo, MeasureResult by measureResult {
+
+    val canScrollBackward
+        get() = (firstVisibleLine?.index ?: 0) != 0 || firstVisibleLineScrollOffset != 0
+
     override val viewportSize: IntSize
         get() = IntSize(width, height)
     override val beforeContentPadding: Int get() = -viewportStartOffset
+
+    /**
+     * Tries to apply a scroll [delta] for this layout info. In some cases we can apply small
+     * scroll deltas by just changing the offsets for each [visibleItemsInfo].
+     * But we can only do so if after applying the delta we would not need to compose a new item
+     * or dispose an item which is currently visible. In this case this function will not apply
+     * the [delta] and return false.
+     *
+     * @return true if we can safely apply a passed scroll [delta] to this layout info.
+     * If true is returned, only the placement phase is needed to apply new offsets.
+     * If false is returned, it means we have to rerun the full measure phase to apply the [delta].
+     */
+    fun tryToApplyScrollWithoutRemeasure(delta: Int): Boolean {
+        if (remeasureNeeded || visibleItemsInfo.isEmpty() || firstVisibleLine == null ||
+            // applying this delta will change firstVisibleLineScrollOffset
+            (firstVisibleLineScrollOffset - delta) !in
+            0 until firstVisibleLine.mainAxisSizeWithSpacings
+        ) {
+            return false
+        }
+        val first = visibleItemsInfo.first()
+        val last = visibleItemsInfo.last()
+        if (first.nonScrollableItem || last.nonScrollableItem) {
+            // non scrollable items require special handling.
+            return false
+        }
+        val canApply = if (delta < 0) {
+            // scrolling forward
+            val deltaToFirstItemChange = first.offsetOnMainAxis(orientation) +
+                first.mainAxisSizeWithSpacings - viewportStartOffset
+            val deltaToLastItemChange = last.offsetOnMainAxis(orientation) +
+                last.mainAxisSizeWithSpacings - viewportEndOffset
+            minOf(deltaToFirstItemChange, deltaToLastItemChange) > -delta
+        } else {
+            // scrolling backward
+            val deltaToFirstItemChange =
+                viewportStartOffset - first.offsetOnMainAxis(orientation)
+            val deltaToLastItemChange =
+                viewportEndOffset - last.offsetOnMainAxis(orientation)
+            minOf(deltaToFirstItemChange, deltaToLastItemChange) > delta
+        }
+        return if (canApply) {
+            firstVisibleLineScrollOffset -= delta
+            visibleItemsInfo.fastForEach {
+                it.applyScrollDelta(delta)
+            }
+            consumedScroll = delta.toFloat()
+            if (!canScrollForward && delta > 0) {
+                // we scrolled backward, so now we can scroll forward
+                canScrollForward = true
+            }
+            true
+        } else {
+            false
+        }
+    }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
index 961341b..d7f4dd5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
@@ -90,6 +90,12 @@
         private set
 
     /**
+     * True when this item is not supposed to react on scroll delta. for example items being
+     * animated away out of the bounds are non scrollable.
+     */
+    var nonScrollableItem: Boolean = false
+
+    /**
      * Calculates positions for the inner placeables at [mainAxisOffset], [crossAxisOffset].
      * [layoutWidth] and [layoutHeight] should be provided to not place placeables which are ended
      * up outside of the viewport (for example one item consist of 2 placeables, and the first one
@@ -123,6 +129,19 @@
         maxMainAxisOffset = mainAxisLayoutSize + afterContentPadding
     }
 
+    fun applyScrollDelta(delta: Int) {
+        if (nonScrollableItem) {
+            return
+        }
+        offset = offset.copy { it + delta }
+        repeat(placeablesCount) { index ->
+            val animation = animator.getAnimation(key, index)
+            if (animation != null) {
+                animation.rawOffset = animation.rawOffset.copy { mainAxis -> mainAxis + delta }
+            }
+        }
+    }
+
     fun place(
         scope: Placeable.PlacementScope,
     ) = with(scope) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
index 7ec7f70..30b61cc 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
@@ -67,6 +67,11 @@
         }
     }
 
+    fun updateScrollOffset(scrollOffset: Int) {
+        check(scrollOffset >= 0f) { "scrollOffset should be non-negative ($scrollOffset)" }
+        this.scrollOffset = scrollOffset
+    }
+
     /**
      * Updates the scroll position - the passed values will be used as a start position for
      * composing the items during the next measure pass and will be updated by the real
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
index e76d3de..913d241 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
@@ -28,6 +28,7 @@
 import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo
 import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
 import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
+import androidx.compose.foundation.lazy.layout.ObservableScopeInvalidator
 import androidx.compose.foundation.lazy.layout.animateScrollToItem
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
@@ -35,17 +36,20 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.neverEqualPolicy
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.listSaver
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.layout.AlignmentLine
+import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.Remeasurement
 import androidx.compose.ui.layout.RemeasurementModifier
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.util.fastForEach
 import kotlin.math.abs
+import kotlin.math.roundToInt
 
 /**
  * Creates a [LazyGridState] that is remembered across compositions.
@@ -115,7 +119,10 @@
     val firstVisibleItemScrollOffset: Int get() = scrollPosition.scrollOffset
 
     /** Backing state for [layoutInfo] */
-    private val layoutInfoState = mutableStateOf<LazyGridLayoutInfo>(EmptyLazyGridLayoutInfo)
+    private val layoutInfoState = mutableStateOf(
+        EmptyLazyGridLayoutInfo,
+        neverEqualPolicy()
+    )
 
     /**
      * The object of [LazyGridLayoutInfo] calculated during the last layout pass. For example,
@@ -239,6 +246,8 @@
 
     internal val nearestRange: IntRange by scrollPosition.nearestRangeState
 
+    internal val placementScopeInvalidator = ObservableScopeInvalidator()
+
     /**
      * Instantly brings the item at [index] to the top of the viewport, offset by [scrollOffset]
      * pixels.
@@ -308,9 +317,21 @@
         // inside measuring we do scrollToBeConsumed.roundToInt() so there will be no scroll if
         // we have less than 0.5 pixels
         if (abs(scrollToBeConsumed) > 0.5f) {
+            val layoutInfo = layoutInfoState.value
             val preScrollToBeConsumed = scrollToBeConsumed
-            remeasurement?.forceRemeasure()
-            if (prefetchingEnabled) {
+            val intDelta = scrollToBeConsumed.roundToInt()
+            if (layoutInfo.tryToApplyScrollWithoutRemeasure(intDelta)) {
+                applyMeasureResult(
+                    result = layoutInfo,
+                    visibleItemsStayedTheSame = true
+                )
+                // we don't need to remeasure, so we only trigger re-placement:
+                placementScopeInvalidator.invalidateScope()
+
+                notifyPrefetch(preScrollToBeConsumed - scrollToBeConsumed, layoutInfo)
+            } else {
+                remeasurement?.forceRemeasure()
+
                 notifyPrefetch(preScrollToBeConsumed - scrollToBeConsumed)
             }
         }
@@ -329,7 +350,10 @@
         }
     }
 
-    private fun notifyPrefetch(delta: Float) {
+    private fun notifyPrefetch(
+        delta: Float,
+        layoutInfo: LazyGridLayoutInfo = layoutInfoState.value
+    ) {
         val prefetchState = prefetchState
         if (!prefetchingEnabled) {
             return
@@ -414,18 +438,23 @@
     /**
      *  Updates the state with the new calculated scroll position and consumed scroll.
      */
-    internal fun applyMeasureResult(result: LazyGridMeasureResult) {
-        scrollPosition.updateFromMeasureResult(result)
+    internal fun applyMeasureResult(
+        result: LazyGridMeasureResult,
+        visibleItemsStayedTheSame: Boolean = false
+    ) {
         scrollToBeConsumed -= result.consumedScroll
         layoutInfoState.value = result
 
+        if (visibleItemsStayedTheSame) {
+            scrollPosition.updateScrollOffset(result.firstVisibleLineScrollOffset)
+        } else {
+            scrollPosition.updateFromMeasureResult(result)
+            cancelPrefetchIfVisibleItemsChanged(result)
+        }
+        canScrollBackward = result.canScrollBackward
         canScrollForward = result.canScrollForward
-        canScrollBackward = (result.firstVisibleLine?.index ?: 0) != 0 ||
-            result.firstVisibleLineScrollOffset != 0
 
         numMeasurePasses++
-
-        cancelPrefetchIfVisibleItemsChanged(result)
     }
 
     /**
@@ -454,16 +483,25 @@
     }
 }
 
-@OptIn(ExperimentalFoundationApi::class)
-private object EmptyLazyGridLayoutInfo : LazyGridLayoutInfo {
-    override val visibleItemsInfo = emptyList<LazyGridItemInfo>()
-    override val viewportStartOffset = 0
-    override val viewportEndOffset = 0
-    override val totalItemsCount = 0
-    override val viewportSize = IntSize.Zero
-    override val orientation = Orientation.Vertical
-    override val reverseLayout = false
-    override val beforeContentPadding: Int = 0
-    override val afterContentPadding: Int = 0
-    override val mainAxisItemSpacing = 0
-}
+private val EmptyLazyGridLayoutInfo = LazyGridMeasureResult(
+    firstVisibleLine = null,
+    firstVisibleLineScrollOffset = 0,
+    canScrollForward = false,
+    consumedScroll = 0f,
+    measureResult = object : MeasureResult {
+        override val width: Int = 0
+        override val height: Int = 0
+        @Suppress("PrimitiveInCollection")
+        override val alignmentLines: Map<AlignmentLine, Int> = emptyMap()
+        override fun placeChildren() {}
+    },
+    visibleItemsInfo = emptyList(),
+    viewportStartOffset = 0,
+    viewportEndOffset = 0,
+    totalItemsCount = 0,
+    reverseLayout = false,
+    orientation = Orientation.Vertical,
+    afterContentPadding = 0,
+    mainAxisItemSpacing = 0,
+    remeasureNeeded = false
+)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
index 131225f..e0624cb 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
@@ -32,12 +32,12 @@
 import androidx.compose.ui.util.fastForEachIndexed
 import androidx.compose.ui.util.fastForEachReversed
 import androidx.compose.ui.util.fastMaxOfOrNull
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.compose.ui.util.packInts
 import androidx.compose.ui.util.unpackInt1
 import androidx.compose.ui.util.unpackInt2
 import kotlin.math.abs
 import kotlin.math.min
-import kotlin.math.roundToInt
 import kotlin.math.sign
 import kotlinx.coroutines.CoroutineScope
 
@@ -166,7 +166,7 @@
     }
 
     return context.measure(
-        initialScrollDelta = state.scrollToBeConsumed.roundToInt(),
+        initialScrollDelta = state.scrollToBeConsumed.fastRoundToInt(),
         initialItemIndices = initialItemIndices,
         initialItemOffsets = initialItemOffsets,
         canRestartMeasure = true,
@@ -673,8 +673,8 @@
         // can be larger if items were resized, or if, for example, we were previously
         // displaying the item 15, but now we have only 10 items in total in the data set.
         val consumedScroll = if (
-            state.scrollToBeConsumed.roundToInt().sign == scrollDelta.sign &&
-            abs(state.scrollToBeConsumed.roundToInt()) >= abs(scrollDelta)
+            state.scrollToBeConsumed.fastRoundToInt().sign == scrollDelta.sign &&
+            abs(state.scrollToBeConsumed.fastRoundToInt()) >= abs(scrollDelta)
         ) {
             scrollDelta.toFloat()
         } else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
index 840031e..be96dd5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
@@ -27,6 +27,7 @@
 import androidx.compose.foundation.gestures.awaitFirstDown
 import androidx.compose.foundation.gestures.scrollable
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.lazy.layout.IntervalList
 import androidx.compose.foundation.lazy.layout.LazyLayout
@@ -91,7 +92,9 @@
     horizontalAlignment: Alignment.Horizontal,
     /** The alignment to align pages vertically. Required when isVertical is false */
     verticalAlignment: Alignment.Vertical,
-    /** The content of the list */
+    /** The final positioning of [PagerState.currentPage] in this layout */
+    snapPosition: SnapPosition,
+    /** The content of the pager */
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     require(beyondBoundsPageCount >= 0) {
@@ -118,7 +121,7 @@
         horizontalAlignment = horizontalAlignment,
         verticalAlignment = verticalAlignment,
         itemProviderLambda = pagerItemProvider,
-        snapPosition = SnapAlignmentStartToStart,
+        snapPosition = snapPosition,
         pageCount = { state.pageCount }
     )
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
index 5161445..37d73a5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
@@ -33,6 +33,7 @@
 import androidx.compose.foundation.gestures.snapping.MinFlingVelocityDp
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
 import androidx.compose.foundation.gestures.snapping.calculateFinalSnappingItem
 import androidx.compose.foundation.layout.PaddingValues
@@ -57,6 +58,7 @@
 import androidx.compose.ui.unit.dp
 import kotlin.math.abs
 import kotlin.math.absoluteValue
+import kotlin.math.roundToInt
 import kotlin.math.sign
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.launch
@@ -102,6 +104,11 @@
  * is passed the position in the list will represent the key.
  * @param pageNestedScrollConnection A [NestedScrollConnection] that dictates how this [Pager]
  * behaves with nested lists. The default behavior will see [Pager] to consume all nested deltas.
+ * @param snapPosition The calculation of how this Pager will perform snapping of pages.
+ * Use this to provide different settling to different positions in the layout. This is used by
+ * [Pager] as a way to calculate [PagerState.currentPage], currentPage is the page closest
+ * to the snap position in the layout (e.g. if the snap position is the start of the layout, then
+ * currentPage will be the page closest to that).
  * @param pageContent This Pager's page Composable.
  */
 @Composable
@@ -121,6 +128,7 @@
     pageNestedScrollConnection: NestedScrollConnection = remember(state) {
         PagerDefaults.pageNestedScrollConnection(state, Orientation.Horizontal)
     },
+    snapPosition: SnapPosition = SnapPosition.Start,
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     Pager(
@@ -138,6 +146,7 @@
         reverseLayout = reverseLayout,
         key = key,
         pageNestedScrollConnection = pageNestedScrollConnection,
+        snapPosition = snapPosition,
         pageContent = pageContent
     )
 }
@@ -182,6 +191,11 @@
  * is passed the position in the list will represent the key.
  * @param pageNestedScrollConnection A [NestedScrollConnection] that dictates how this [Pager] behaves
  * with nested lists. The default behavior will see [Pager] to consume all nested deltas.
+ * @param snapPosition The calculation of how this Pager will perform snapping of Pages.
+ * Use this to provide different settling to different positions in the layout. This is used by
+ * [Pager] as a way to calculate [PagerState.currentPage], currentPage is the page closest
+ * to the snap position in the layout (e.g. if the snap position is the start of the layout, then
+ * currentPage will be the page closest to that).
  * @param pageContent This Pager's page Composable.
  */
 @Composable
@@ -201,6 +215,7 @@
     pageNestedScrollConnection: NestedScrollConnection = remember(state) {
         PagerDefaults.pageNestedScrollConnection(state, Orientation.Vertical)
     },
+    snapPosition: SnapPosition = SnapPosition.Start,
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     Pager(
@@ -218,6 +233,7 @@
         reverseLayout = reverseLayout,
         key = key,
         pageNestedScrollConnection = pageNestedScrollConnection,
+        snapPosition = snapPosition,
         pageContent = pageContent
     )
 }
@@ -595,7 +611,8 @@
         }
 
         override fun calculateSnappingOffset(currentVelocity: Float): Float {
-            val (lowerBoundOffset, upperBoundOffset) = searchForSnappingBounds()
+            val snapPosition = pagerState.layoutInfo.snapPosition
+            val (lowerBoundOffset, upperBoundOffset) = searchForSnappingBounds(snapPosition)
 
             val isForward = pagerState.isScrollingForward()
 
@@ -723,14 +740,23 @@
             }
         }
 
-        private fun searchForSnappingBounds(): Pair<Float, Float> {
+        private fun searchForSnappingBounds(snapPosition: SnapPosition): Pair<Float, Float> {
             debugLog { "Calculating Snapping Bounds" }
             var lowerBoundOffset = Float.NEGATIVE_INFINITY
             var upperBoundOffset = Float.POSITIVE_INFINITY
             val totalPageSize = pagerState.pageSize + pagerState.pageSpacing
+            val layoutInfo = pagerState.layoutInfo
 
             val currentPage = pagerState.currentPage
-            val currentPageScrollOffset = pagerState.calculateCurrentPageLayoutOffset(totalPageSize)
+            val currentPageScrollOffset = snapPosition.currentPageOffset(
+                layoutInfo.mainAxisViewportSize,
+                layoutInfo.pageSize,
+                layoutInfo.pageSpacing,
+                layoutInfo.beforeContentPadding,
+                layoutInfo.afterContentPadding,
+                pagerState.currentPage,
+                pagerState.currentPageOffsetFraction
+            )
 
             // the closest page should be close to the current page, we'll start from current page
             // and search both sides.
@@ -751,7 +777,7 @@
                     itemSize = layoutInfo.pageSize,
                     itemOffset = currentOffset,
                     itemIndex = page,
-                    snapPosition = SnapAlignmentStartToStart
+                    snapPosition = snapPosition
                 )
 
                 debugLog { "Snapping Offset=$offset for page=$page" }
@@ -784,7 +810,7 @@
                     itemSize = layoutInfo.pageSize,
                     itemOffset = currentOffset,
                     itemIndex = page,
-                    snapPosition = SnapAlignmentStartToStart
+                    snapPosition = snapPosition
                 )
 
                 debugLog {
@@ -820,6 +846,27 @@
 }
 
 @OptIn(ExperimentalFoundationApi::class)
+internal fun SnapPosition.currentPageOffset(
+    layoutSize: Int,
+    pageSize: Int,
+    spaceBetweenPages: Int,
+    beforeContentPadding: Int,
+    afterContentPadding: Int,
+    currentPage: Int,
+    currentPageOffsetFraction: Float
+): Int {
+    val snapOffset = position(
+        layoutSize,
+        pageSize,
+        beforeContentPadding,
+        afterContentPadding,
+        currentPage
+    )
+
+    return (snapOffset - currentPageOffsetFraction * (pageSize + spaceBetweenPages)).roundToInt()
+}
+
+@OptIn(ExperimentalFoundationApi::class)
 internal class PagerWrapperFlingBehavior(
     val originalFlingBehavior: SnapFlingBehavior,
     val pagerState: PagerState
@@ -946,11 +993,8 @@
 
 private const val LowVelocityAnimationDefaultDuration = 500
 
-internal const val PagerDebugEnable = false
-
-private const val DEBUG = PagerDebugEnable
 private inline fun debugLog(generateMsg: () -> String) {
-    if (DEBUG) {
+    if (PagerDebugConfig.MainPagerComposable) {
         println("Pager: ${generateMsg()}")
     }
 }
@@ -964,3 +1008,11 @@
 } else {
     upDownDifference.y
 }
+
+internal object PagerDebugConfig {
+    const val MainPagerComposable = false
+    const val PagerState = false
+    const val MeasurePolicy = false
+    const val MeasureLogic = false
+    const val ScrollPosition = false
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt
index b14f6e2..c2cff84 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.ui.unit.IntSize
 
 /**
@@ -98,6 +99,11 @@
      * scroll during scroll events.
      */
     val beyondBoundsPageCount: Int
+
+    /**
+     * The calculation of how this Pager performs snapping of pages.
+     */
+    val snapPosition: SnapPosition
 }
 
 @ExperimentalFoundationApi
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLazyAnimateScrollScope.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLazyAnimateScrollScope.kt
index a3b7712..3d8eba3 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLazyAnimateScrollScope.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLazyAnimateScrollScope.kt
@@ -47,8 +47,8 @@
         }
 
         override fun ScrollScope.snapToItem(index: Int, scrollOffset: Int) {
-            val finalOffset = scrollOffset / state.pageSizeWithSpacing.toFloat()
-            state.snapToItem(index, finalOffset)
+            val offsetFraction = scrollOffset / state.pageSizeWithSpacing.toFloat()
+            state.snapToItem(index, offsetFraction)
         }
 
         override fun calculateDistanceTo(targetIndex: Int, targetItemOffset: Int): Float {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
index 02bd345..c60b0b8 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
@@ -61,9 +61,13 @@
     require(beforeContentPadding >= 0) { "negative beforeContentPadding" }
     require(afterContentPadding >= 0) { "negative afterContentPadding" }
     val pageSizeWithSpacing = (pageAvailableSize + spaceBetweenPages).coerceAtLeast(0)
-    debugLog { "Starting Measure Pass..." +
-        "\nCurrentPage = $currentPage" +
-        "\nCurrentPageOffset = $currentPageOffset" }
+
+    debugLog {
+        "Starting Measure Pass..." +
+            "\n CurrentPage = $currentPage" +
+            "\n CurrentPageOffset = $currentPageOffset" +
+            "\n SnapPosition = ${snapPosition.string()}"
+    }
 
     return if (pageCount <= 0) {
         PagerMeasureResult(
@@ -81,7 +85,8 @@
             beyondBoundsPageCount = beyondBoundsPageCount,
             canScrollForward = false,
             currentPage = null,
-            currentPageOffsetFraction = 0.0f
+            currentPageOffsetFraction = 0.0f,
+            snapPosition = snapPosition
         )
     } else {
 
@@ -120,6 +125,12 @@
             currentFirstPageScrollOffset = 0
         }
 
+        debugLog {
+            "Calculated Info:" +
+                "\n FirstVisiblePage=$firstVisiblePage" +
+                "\n firstVisiblePageScrollOffset=$firstVisiblePageScrollOffset"
+        }
+
         // this will contain all the measured pages representing the visible pages
         val visiblePages = ArrayDeque<MeasuredPage>()
 
@@ -135,6 +146,8 @@
         // max of cross axis sizes of all visible pages
         var maxCrossAxis = 0
 
+        debugLog { "Composing Backwards" }
+
         // we had scrolled backward or we compose pages in the start padding area, which means
         // pages before current firstPageScrollOffset should be visible. compose them and update
         // firstPageScrollOffset
@@ -152,6 +165,9 @@
                 reverseLayout = reverseLayout,
                 pageAvailableSize = pageAvailableSize
             )
+
+            debugLog { "Composed Page=$previous" }
+
             visiblePages.add(0, measuredPage)
             maxCrossAxis = maxOf(maxCrossAxis, measuredPage.crossAxisSize)
             currentFirstPageScrollOffset += pageSizeWithSpacing
@@ -175,6 +191,7 @@
             currentMainAxisOffset += pageSizeWithSpacing
         }
 
+        debugLog { "Composing Forward Starting at Index=$index" }
         // then composing visible pages forward until we fill the whole viewport.
         // we want to have at least one page in visiblePages even if in fact all the pages are
         // offscreen, this can happen if the content padding is larger than the available size.
@@ -196,6 +213,8 @@
                 pageAvailableSize = pageAvailableSize
             )
 
+            debugLog { "Composed Page=$index at $currentFirstPageScrollOffset" }
+
             // do not add space to the last page
             currentMainAxisOffset += if (index == pageCount - 1) {
                 pageAvailableSize
@@ -252,6 +271,7 @@
         // the initial offset for pages from visiblePages list
         require(currentFirstPageScrollOffset >= 0) { "invalid currentFirstPageScrollOffset" }
         val visiblePagesScrollOffset = -currentFirstPageScrollOffset
+
         var firstPage = visiblePages.first()
 
         // even if we compose pages to fill before content padding we should ignore pages fully
@@ -371,16 +391,31 @@
                 snapPosition
             )
 
-        val currentPagePositionOffset = newCurrentPage?.offset ?: 0
+        val snapOffset = snapPosition.position(
+            mainAxisAvailableSize,
+            pageAvailableSize,
+            beforeContentPadding,
+            afterContentPadding,
+            newCurrentPage?.index ?: 0
+        )
 
-        val newCurrentPageOffsetFraction =
-            ((-currentPagePositionOffset.toFloat()) / (pageSizeWithSpacing)).coerceIn(
-                MinPageOffset, MaxPageOffset
+        val currentPagePositionOffset = (newCurrentPage?.offset ?: 0)
+
+        val currentPageOffsetFraction = if (pageSizeWithSpacing == 0) {
+            0.0f
+        } else {
+            ((snapOffset - currentPagePositionOffset) / (pageSizeWithSpacing.toFloat())).coerceIn(
+                MinPageOffset,
+                MaxPageOffset
             )
+        }
 
-        debugLog { "Finished Measure Pass" +
-            "\n Final currentPage=${newCurrentPage?.index} " +
-            "\n Final currentPageOffsetFraction=$newCurrentPageOffsetFraction" }
+        debugLog {
+            "Finished Measure Pass" +
+                "\n Final currentPage=${newCurrentPage?.index} " +
+                "\n Final currentPageScrollOffset=$currentPagePositionOffset" +
+                "\n Final currentPageScrollOffsetFraction=$currentPageOffsetFraction"
+        }
 
         return PagerMeasureResult(
             firstVisiblePage = firstPage,
@@ -401,7 +436,8 @@
             beyondBoundsPageCount = beyondBoundsPageCount,
             canScrollForward = index < pageCount || currentMainAxisOffset > maxOffset,
             currentPage = newCurrentPage,
-            currentPageOffsetFraction = newCurrentPageOffsetFraction
+            currentPageOffsetFraction = currentPageOffsetFraction,
+            snapPosition = snapPosition
         )
     }
 }
@@ -595,12 +631,21 @@
     return positionedPages
 }
 
+@OptIn(ExperimentalFoundationApi::class)
+private fun SnapPosition.string(): String {
+    return when (this) {
+        SnapPosition.Start -> "Start"
+        SnapPosition.End -> "End"
+        SnapPosition.Center -> "Center"
+        else -> "Custom"
+    }
+}
+
 internal const val MinPageOffset = -0.5f
 internal const val MaxPageOffset = 0.5f
 
-private const val DEBUG = PagerDebugEnable
 private inline fun debugLog(generateMsg: () -> String) {
-    if (DEBUG) {
+    if (PagerDebugConfig.MeasureLogic) {
         println("PagerMeasure: ${generateMsg()}")
     }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
index 35bbf3b..f255c9e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
@@ -36,8 +36,6 @@
 import androidx.compose.ui.unit.constrainHeight
 import androidx.compose.ui.unit.constrainWidth
 import androidx.compose.ui.unit.offset
-import androidx.compose.ui.util.fastFirstOrNull
-import kotlin.math.roundToInt
 
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
@@ -145,10 +143,18 @@
 
         val currentPage: Int
         val currentPageOffset: Int
-        val pageSizeWithSpacing = pageAvailableSize + spaceBetweenPages
+
         Snapshot.withoutReadObservation {
             currentPage = state.matchScrollPositionWithKey(itemProvider, state.currentPage)
-            currentPageOffset = state.calculateCurrentPageLayoutOffset(pageSizeWithSpacing)
+            currentPageOffset = snapPosition.currentPageOffset(
+                mainAxisAvailableSize,
+                pageAvailableSize,
+                spaceBetweenPages,
+                beforeContentPadding,
+                afterContentPadding,
+                state.currentPage,
+                state.currentPageOffsetFraction
+            )
         }
 
         val pinnedPages = itemProvider.calculateLazyLayoutPinnedIndices(
@@ -190,31 +196,8 @@
     }
 }
 
-private const val DEBUG = PagerDebugEnable
 private inline fun debugLog(generateMsg: () -> String) {
-    if (DEBUG) {
+    if (PagerDebugConfig.MeasurePolicy) {
         println("PagerMeasurePolicy: ${generateMsg()}")
     }
 }
-
-@OptIn(ExperimentalFoundationApi::class)
-internal fun PagerState.calculateCurrentPageLayoutOffset(pageSizeWithSpacing: Int): Int {
-    val previousPassOffset =
-        layoutInfo.visiblePagesInfo.fastFirstOrNull { it.index == currentPage }?.offset
-            ?: 0
-
-    val previousPassFraction = if (pageSizeWithSpacing == 0) {
-        currentPageOffsetFraction
-    } else {
-        ((-previousPassOffset.toFloat()) / (pageSizeWithSpacing))
-    }
-
-    val fractionDiff = currentPageOffsetFraction - previousPassFraction
-    debugLog {
-        "\npreviousPassOffset=$previousPassOffset" +
-            "\npreviousPassFraction=$previousPassFraction" +
-            "\nfractionDiff=$fractionDiff"
-    }
-
-    return -(fractionDiff * pageSizeWithSpacing - previousPassOffset).roundToInt()
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasureResult.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasureResult.kt
index 16832df..c236604 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasureResult.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasureResult.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.unit.IntSize
 
@@ -34,9 +35,10 @@
     override val beyondBoundsPageCount: Int,
     val firstVisiblePage: MeasuredPage?,
     val currentPage: MeasuredPage?,
-    val firstVisiblePageScrollOffset: Int,
     val currentPageOffsetFraction: Float,
+    val firstVisiblePageScrollOffset: Int,
     val canScrollForward: Boolean,
+    override val snapPosition: SnapPosition,
     measureResult: MeasureResult,
 ) : PagerLayoutInfo, MeasureResult by measureResult {
     override val viewportSize: IntSize
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt
index 14302fc..ea35c64 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt
@@ -23,7 +23,6 @@
 import androidx.compose.runtime.mutableFloatStateOf
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.setValue
-import kotlin.math.absoluteValue
 import kotlin.math.roundToInt
 
 /**
@@ -36,7 +35,6 @@
     currentPageOffsetFraction: Float = 0.0f,
     val state: PagerState
 ) {
-
     var currentPage by mutableIntStateOf(currentPage)
         private set
 
@@ -83,8 +81,8 @@
      * c) there will be not enough pages to fill the viewport after the requested index, so we
      * would have to compose few elements before the asked index, changing the first visible page.
      */
-    fun requestPosition(index: Int, scrollOffsetFraction: Float) {
-        update(index, scrollOffsetFraction)
+    fun requestPosition(index: Int, offsetFraction: Float) {
+        update(index, offsetFraction)
         // clear the stored key as we have a direct request to scroll to [index] position and the
         // next [checkIfFirstVisibleItemWasMoved] shouldn't override this.
         lastKnownCurrentPageKey = null
@@ -102,24 +100,25 @@
         return newIndex
     }
 
-    private fun update(page: Int, pageOffsetFraction: Float) {
+    private fun update(page: Int, offsetFraction: Float) {
         currentPage = page
         nearestRangeState.update(page)
-        currentPageOffsetFraction = if (pageOffsetFraction.absoluteValue == 0.0f) {
-            0.0f
-        } else {
-            pageOffsetFraction
-        }
+        currentPageOffsetFraction = offsetFraction
     }
 
-    fun currentScrollOffset(): Int {
-        return ((currentPage + currentPageOffsetFraction) * state.pageSizeWithSpacing).roundToInt()
+    fun currentAbsoluteScrollOffset(): Int {
+        return ((currentPage +
+            currentPageOffsetFraction) * state.pageSizeWithSpacing).roundToInt()
     }
 
     fun applyScrollDelta(delta: Int) {
         debugLog { "Applying Delta=$delta" }
-        val fractionDelta = delta / state.pageSizeWithSpacing.toFloat()
-        currentPageOffsetFraction += fractionDelta
+        val fractionUpdate = if (state.pageSizeWithSpacing == 0) {
+            0.0f
+        } else {
+            delta / state.pageSizeWithSpacing.toFloat()
+        }
+        currentPageOffsetFraction += fractionUpdate
         state.remeasureTrigger = Unit // trigger remeasure
     }
 }
@@ -135,9 +134,8 @@
  */
 internal const val NearestItemsExtraItemCount = 100
 
-private const val DEBUG = PagerDebugEnable
 private inline fun debugLog(generateMsg: () -> String) {
-    if (DEBUG) {
+    if (PagerDebugConfig.ScrollPosition) {
         println("PagerScrollPosition: ${generateMsg()}")
     }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
index ad2a58a..3f808a9d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
@@ -76,8 +76,8 @@
     initialPageOffsetFraction: Float = 0f,
     pageCount: () -> Int
 ): PagerState {
-    return rememberSaveable(saver = PagerStateImpl.Saver) {
-        PagerStateImpl(
+    return rememberSaveable(saver = DefaultPagerState.Saver) {
+        DefaultPagerState(
             initialPage,
             initialPageOffsetFraction,
             pageCount
@@ -87,12 +87,31 @@
     }
 }
 
+/**
+ * Creates a default [PagerState] to be used with a [Pager]
+ *
+ * Please refer to the sample to learn how to use this API.
+ * @sample androidx.compose.foundation.samples.PagerWithStateSample
+ *
+ * @param currentPage The pager that should be shown first.
+ * @param currentPageOffsetFraction The offset of the initial page as a fraction of the page size.
+ * This should vary between -0.5 and 0.5 and indicates how to offset the initial page from the
+ * snapped position.
+ * @param pageCount The amount of pages this Pager will have.
+ */
 @ExperimentalFoundationApi
-internal class PagerStateImpl(
-    initialPage: Int,
-    initialPageOffsetFraction: Float,
+fun PagerState(
+    currentPage: Int = 0,
+    currentPageOffsetFraction: Float = 0f,
+    pageCount: () -> Int
+): PagerState = DefaultPagerState(currentPage, currentPageOffsetFraction, pageCount)
+
+@ExperimentalFoundationApi
+private class DefaultPagerState(
+    currentPage: Int,
+    currentPageOffsetFraction: Float,
     updatedPageCount: () -> Int
-) : PagerState(initialPage, initialPageOffsetFraction) {
+) : PagerState(currentPage, currentPageOffsetFraction) {
 
     var pageCountState = mutableStateOf(updatedPageCount)
     override val pageCount: Int get() = pageCountState.value.invoke()
@@ -101,7 +120,7 @@
         /**
          * To keep current page and current page offset saved
          */
-        val Saver: Saver<PagerStateImpl, *> = listSaver(
+        val Saver: Saver<DefaultPagerState, *> = listSaver(
             save = {
                 listOf(
                     it.currentPage,
@@ -110,9 +129,9 @@
                 )
             },
             restore = {
-                PagerStateImpl(
-                    initialPage = it[0] as Int,
-                    initialPageOffsetFraction = it[1] as Float,
+                DefaultPagerState(
+                    currentPage = it[0] as Int,
+                    currentPageOffsetFraction = it[1] as Float,
                     updatedPageCount = { it[2] as Int }
                 )
             }
@@ -141,7 +160,7 @@
 
     init {
         require(currentPageOffsetFraction in -0.5..0.5) {
-            "initialPageOffsetFraction $currentPageOffsetFraction is " +
+            "currentPageOffsetFraction $currentPageOffsetFraction is " +
                 "not within the range -0.5 to 0.5"
         }
     }
@@ -188,7 +207,7 @@
      * determine scroll deltas and max min scrolling.
      */
     private fun performScroll(delta: Float): Float {
-        val currentScrollPosition = scrollPosition.currentScrollOffset()
+        val currentScrollPosition = scrollPosition.currentAbsoluteScrollOffset()
         debugLog {
             "\nDelta=$delta " +
                 "\ncurrentScrollPosition=$currentScrollPosition " +
@@ -440,9 +459,8 @@
      * destination page will be offset from its snapped position.
      */
     fun ScrollScope.updateCurrentPage(page: Int, pageOffsetFraction: Float = 0.0f) {
-        val targetPageOffsetToSnappedPosition = (pageOffsetFraction * pageSizeWithSpacing).toInt()
         with(animatedScrollScope) {
-            snapToItem(page, targetPageOffsetToSnappedPosition)
+            snapToItem(page, pageOffsetFraction)
         }
     }
 
@@ -719,6 +737,7 @@
     override val viewportEndOffset: Int = 0
     override val reverseLayout: Boolean = false
     override val beyondBoundsPageCount: Int = 0
+    override val snapPosition: SnapPosition = SnapPosition.Start
 }
 
 private val UnitDensity = object : Density {
@@ -726,13 +745,8 @@
     override val fontScale: Float = 1f
 }
 
-@OptIn(ExperimentalFoundationApi::class)
-internal val SnapAlignmentStartToStart =
-    SnapPosition { _, _, _, _, _ -> 0 }
-
-private const val DEBUG = PagerDebugEnable
 private inline fun debugLog(generateMsg: () -> String) {
-    if (DEBUG) {
+    if (PagerDebugConfig.PagerState) {
         println("PagerState: ${generateMsg()}")
     }
 }
@@ -743,7 +757,7 @@
 
 @OptIn(ExperimentalFoundationApi::class)
 private fun PagerMeasureResult.calculateNewMaxScrollOffset(pageCount: Int): Float {
-    return beforeContentPadding +
+    return (beforeContentPadding +
         pageCount * (pageSpacing + pageSize).toFloat() +
-        afterContentPadding - pageSpacing - singleAxisViewPort
+        afterContentPadding - pageSpacing - singleAxisViewPort).coerceAtLeast(0.0f)
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
index e5219f2..a8a6420 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt
@@ -51,8 +51,8 @@
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMapIndexedNotNull
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.floor
-import kotlin.math.roundToInt
 
 /**
  * Basic element that displays text and provides semantics / accessibility information.
@@ -381,7 +381,7 @@
                             maxHeight = floor(it.height).toInt()
                         )
                     ),
-                    IntOffset(it.left.roundToInt(), it.top.roundToInt())
+                    IntOffset(it.left.fastRoundToInt(), it.top.fastRoundToInt())
                 )
             }
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
index b2af5fa4..681a728 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
@@ -38,6 +38,7 @@
 import androidx.compose.foundation.text.selection.updateSelectionTouchMode
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.DontMemoize
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.RecomposeScope
@@ -123,8 +124,8 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.max
-import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
@@ -353,7 +354,7 @@
                         startInputSession(
                             textInputService,
                             state,
-                            value,
+                            manager.value,
                             imeOptions,
                             offsetMapping
                         )
@@ -629,7 +630,7 @@
         .textFieldScrollable(scrollerPosition, interactionSource, enabled)
         .then(pointerModifier)
         .then(semanticsModifier)
-        .onGloballyPositioned {
+        .onGloballyPositioned @DontMemoize {
             state.layoutResult?.decorationBoxCoordinates = it
         }
 
@@ -705,8 +706,8 @@
                                 width = width,
                                 height = height,
                                 alignmentLines = mapOf(
-                                    FirstBaseline to result.firstBaseline.roundToInt(),
-                                    LastBaseline to result.lastBaseline.roundToInt()
+                                    FirstBaseline to result.firstBaseline.fastRoundToInt(),
+                                    LastBaseline to result.lastBaseline.fastRoundToInt()
                                 )
                             ) {}
                         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextDelegate.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextDelegate.kt
index 41027f0..c14fd66 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextDelegate.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextDelegate.kt
@@ -37,8 +37,8 @@
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.constrain
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.ceil
-import kotlin.math.roundToInt
 
 /**
  * An object that paints text onto a [Canvas].
@@ -299,7 +299,7 @@
     }
 }
 
-internal fun Float.ceilToIntPx(): Int = ceil(this).roundToInt()
+internal fun Float.ceilToIntPx(): Int = ceil(this).fastRoundToInt()
 
 /**
  * Returns the [TextDelegate] passed as a [current] param if the input didn't change
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
index 710857d..d665bbd 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
@@ -34,6 +34,7 @@
 import androidx.compose.ui.text.input.OffsetMapping
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import kotlinx.coroutines.withContext
 
 internal fun Modifier.cursor(
@@ -57,7 +58,7 @@
         }
         drawWithContent {
             this.drawContent()
-            val cursorAlphaValue = cursorAlpha.value.coerceIn(0f, 1f)
+            val cursorAlphaValue = cursorAlpha.value.fastCoerceIn(0f, 1f)
             if (cursorAlphaValue != 0f) {
                 val transformedOffset = offsetMapping
                     .originalToTransformed(value.selection.start)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
index 20c8055..284e4e6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
@@ -49,8 +49,8 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.min
-import kotlin.math.roundToInt
 
 // Scrollable
 internal fun Modifier.textFieldScrollable(
@@ -162,7 +162,7 @@
             )
 
             val offset = -scrollerPosition.offset
-            placeable.placeRelative(0, offset.roundToInt())
+            placeable.placeRelative(0, offset.fastRoundToInt())
         }
     }
 }
@@ -206,7 +206,7 @@
             )
 
             val offset = -scrollerPosition.offset
-            placeable.placeRelative(offset.roundToInt(), 0)
+            placeable.placeRelative(offset.fastRoundToInt(), 0)
         }
     }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/MinLinesConstrainer.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/MinLinesConstrainer.kt
index 02d1f32..1774883 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/MinLinesConstrainer.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/MinLinesConstrainer.kt
@@ -23,7 +23,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Coerce min and max lines into actual constraints.
@@ -119,8 +119,7 @@
             lineHeightCache = lineHeight
         }
         val minHeight = if (minLines != 1) {
-            (oneLineHeight + (lineHeight * (minLines - 1)))
-                .roundToInt()
+            (oneLineHeight + (lineHeight * (minLines - 1))).fastRoundToInt()
                 .coerceAtLeast(0)
                 .coerceAtMost(inConstraints.maxHeight)
         } else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextAnnotatedStringNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextAnnotatedStringNode.kt
index bebe4ec..2852f89 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextAnnotatedStringNode.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextAnnotatedStringNode.kt
@@ -64,7 +64,7 @@
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Node that implements Text for [AnnotatedString] or [onTextLayout] parameters.
@@ -395,8 +395,8 @@
             onTextLayout?.invoke(textLayoutResult)
             selectionController?.updateTextLayout(textLayoutResult)
             baselineCache = mapOf(
-                FirstBaseline to textLayoutResult.firstBaseline.roundToInt(),
-                LastBaseline to textLayoutResult.lastBaseline.roundToInt()
+                FirstBaseline to textLayoutResult.firstBaseline.fastRoundToInt(),
+                LastBaseline to textLayoutResult.lastBaseline.fastRoundToInt()
             )
         }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt
index b5045b9..4764b12 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt
@@ -62,7 +62,7 @@
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Node that implements Text for [String].
@@ -333,8 +333,8 @@
             if (cache == null) {
                 cache = LinkedHashMap(2)
             }
-            cache[FirstBaseline] = paragraph.firstBaseline.roundToInt()
-            cache[LastBaseline] = paragraph.lastBaseline.roundToInt()
+            cache[FirstBaseline] = paragraph.firstBaseline.fastRoundToInt()
+            cache[LastBaseline] = paragraph.lastBaseline.fastRoundToInt()
             baselineCache = cache
         }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt
index e3b7eb4..f7a6ffb 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt
@@ -648,9 +648,17 @@
     }
 
     internal fun getHandlePosition(isStartHandle: Boolean): Offset {
+        val textLayoutResult = state?.layoutResult?.value ?: return Offset.Unspecified
+
+        // If layout and value are out of sync, return unspecified.
+        // This will be called again once they are in sync.
+        val transformedText = transformedText ?: return Offset.Unspecified
+        val layoutInputText = textLayoutResult.layoutInput.text.text
+        if (transformedText.text != layoutInputText) return Offset.Unspecified
+
         val offset = if (isStartHandle) value.selection.start else value.selection.end
         return getSelectionHandleCoordinates(
-            textLayoutResult = state?.layoutResult!!.value,
+            textLayoutResult = textLayoutResult,
             offset = offsetMapping.originalToTransformed(offset),
             isStart = isStartHandle,
             areHandlesCrossed = value.selection.reversed
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldCoreModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldCoreModifier.kt
index 87c5432..ab79717 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldCoreModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldCoreModifier.kt
@@ -60,6 +60,7 @@
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import kotlin.math.ceil
 import kotlin.math.floor
 import kotlin.math.min
@@ -492,7 +493,7 @@
         // invalidates.
         if (cursorAlpha.value <= 0f || !showCursor) return
 
-        val cursorAlphaValue = cursorAlpha.value.coerceIn(0f, 1f)
+        val cursorAlphaValue = cursorAlpha.value.fastCoerceIn(0f, 1f)
         if (cursorAlphaValue == 0f) return
 
         val cursorRect = textFieldSelectionState.cursorRect
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldTextLayoutModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldTextLayoutModifier.kt
index 00cd95a8..d6da1f5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldTextLayoutModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldTextLayoutModifier.kt
@@ -36,7 +36,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.dp
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * This ModifierNodeElement is only responsible for laying out text and reporting its global
@@ -150,8 +150,8 @@
             width = result.size.width,
             height = result.size.height,
             alignmentLines = mapOf(
-                FirstBaseline to result.firstBaseline.roundToInt(),
-                LastBaseline to result.lastBaseline.roundToInt()
+                FirstBaseline to result.firstBaseline.fastRoundToInt(),
+                LastBaseline to result.lastBaseline.fastRoundToInt()
             )
         ) {
             placeable.place(0, 0)
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopOverscroll.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopOverscroll.desktop.kt
similarity index 100%
rename from compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopOverscroll.kt
rename to compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopOverscroll.desktop.kt
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/DesktopTextFieldMagnifier.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/DesktopTextFieldMagnifier.desktop.kt
similarity index 100%
rename from compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/DesktopTextFieldMagnifier.kt
rename to compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/DesktopTextFieldMagnifier.desktop.kt
diff --git a/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupPerfettoSdkBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupPerfettoSdkBenchmark.kt
index eb9ab43..32e2f34 100644
--- a/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupPerfettoSdkBenchmark.kt
+++ b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupPerfettoSdkBenchmark.kt
@@ -23,6 +23,7 @@
 import androidx.benchmark.macro.TraceSectionMetric
 import androidx.benchmark.macro.junit4.MacrobenchmarkRule
 import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
 import androidx.testutils.measureStartup
 import org.hamcrest.CoreMatchers.`is`
 import org.hamcrest.MatcherAssert.assertThat
@@ -33,6 +34,7 @@
 
 @OptIn(ExperimentalMetricApi::class)
 @LargeTest
+@SdkSuppress(minSdkVersion = 30) // required for perfetto sdk capture
 @RunWith(Parameterized::class)
 class TrivialStartupPerfettoSdkBenchmark(
     private val startupMode: StartupMode,
diff --git a/compose/integration-tests/material-catalog/build.gradle b/compose/integration-tests/material-catalog/build.gradle
index 80f662f..c7bf51b 100644
--- a/compose/integration-tests/material-catalog/build.gradle
+++ b/compose/integration-tests/material-catalog/build.gradle
@@ -45,7 +45,7 @@
     implementation project(":compose:runtime:runtime")
     implementation project(":compose:foundation:foundation-layout")
     implementation project(":compose:ui:ui")
-    implementation project(":compose:material:material")
+    implementation("androidx.compose.material:material:1.6.0-beta01")
     implementation project(":compose:material3:material3")
     implementation project(":compose:material:material:integration-tests:material-catalog")
     implementation project(":compose:material3:material3:integration-tests:material3-catalog")
diff --git a/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt b/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
index 1d2a07a..747301d 100644
--- a/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
+++ b/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
@@ -31,7 +31,7 @@
     val Color: TestFile = bytecodeStub(
         filename = "Color.kt",
         filepath = "androidx/compose/ui/graphics",
-        checksum = 0x2a148ced,
+        checksum = 0x143250ca,
         source = """
             package androidx.compose.ui.graphics
 
@@ -76,113 +76,112 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcolmZiXUpSfmVKhl5yfW5BfnKqX
-        m1iSWpSZmCPE4Zyfk19U7F3Cpc4li1OZXlp+vhBbSGpxCVihDIbC0ky99KLE
-        gozM5GIhdrCR3iVKDFoMAMec7K6RAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        TSxJLcpMzBHicM7PyS8q9i7hUueSxalMLy0/X4gtJLW4BKxQBkNhaaZeelFi
+        QUZmcrEQO9hI7xIlBi0GAPW9qnSRAAAA
         """,
         """
         androidx/compose/ui/graphics/Color$Companion.class:
-        H4sIAAAAAAAAAJWWXVMcRRSG3579ZFiW5TNACBpcI2BgAWOiIUbDYpBkSZQQ
-        YkTFZnaEgdkZanoWkzvKKv0feu+FV6a8sCi883/4NyxP9ywMjl2roYrunvO+
-        Tx+mZ84Z/vjr198AXIPFcJV79cB36s8qlt848IVdaTqVnYAf7DqWqFR91w/K
-        VVK45/heDoyhtMcPecXl3k7l4faebYU5pBiytxzPCW8zpCYmNwrIIGsijRxD
-        Otx1BMNM7WUSLVCaHTtcdLm1Pz1bv7F1f++x2voew/h/b5RDF0MvtyxbiPLp
-        PmXroIBuFEwUUWLoo/gSD/aXA/48TjEQQ6ei4voirp+hm6R/Mj0xc+a/EPmH
-        GPopXHN2dhPQYAydqYq8GJGj0Qk82XVCO6bO3ZNSFPFKRLzKUKT4ml2P/aXY
-        T3Hlfi1yl6P9lwPb9rT7K0URb0TERHTvi27T1t67FJT/zch/lVQKP7Vd1/8m
-        JvpiIpIUU4mY2ShH9Tn3tDmkoPxvRf5r9CdTeJXv2F7IY6Q/Rlqaom5E1Dt0
-        /KSsB9wTBzwgOSaHYvKcruiFiL7FMDdR2/dD1/Eqe4eNiuOFduBxt7Jkf82b
-        blj1PREGTSv0g1V6h+xgYXLDhCGLoa9sxeJWQ6myNl5qNzqRU2DVDnmdh5xi
-        RuMwRUXN5JBhYPsUeubIKzpUoz7H2J/HR/2mMWSYRun4yDTyRnSRH86ffJ8a
-        Oj6aN2bZYi5vnPyYNUrG2mgpNWLMpn9/wY6PaGD0KyWT8NxIOp8pZcmSb2fp
-        UBaznaVTWQrtLF3KUmxn6VaWUjtLj7L0trP0KUt/O8uAsgy2s1xQlqF2lmFl
-        GWlnuagso+0sl0rZk2+NbvkAzUz+5IexWUbry/JhzzN6EZBRbY+h/D9aL71A
-        jHprWhYxTbLOGPKnLZAi0ZRRXYGh46xnMeRaFUb9mXoMQ+e5uiFC9Sn6PkTF
-        TuhZk6cEKvfMfihT+nWyddccz37QbGzbwTrfdinSW/Mt7m7wwJHXrWBhxfPs
-        oOpyIWz6uJiP/GZg2XcdqQ2vNb3QadgbjnDIfMfz/JCHlE9gjqowDflTpBV9
-        o+iUvqCrCs1M1s3UL8j/TAsDX9KYjYLYorHQWnfApLkHnSoi4RlySy39Aj0/
-        JdjsOTZ9xvbq2IEkm9Oygzp2OMnmteyIjr2UZDu07JiOvZxkTS07rmNfT7Kd
-        WvaKjp1MsgUtO6Vjp5Nsl5ad0bFzSbaoZed17NtJtlvLXtex7ybZkpa9qWPf
-        S7I9/2bp36EMbrfYaZqNVjG8L4uBKWAwCraSydUHuENaCl+pBy+hIjYxDK4S
-        fo5tmr+j+CJ5q5tIrWBpBR/SiLtyWF7BR1jZBBO4h/ubGBMwBWoCWYFVgQcC
-        nQIFgYcCHwtMCXwiMC+wJtAr8EhgUGBd4IrAY4ERgQ2B6wJPBMYFPhW4KfBU
-        yD0/E5j5G4ru30HxCgAA
+        H4sIAAAAAAAA/5WW3VfcRBiHf5P9JLvA8lmWtmhxrYCFBaytlloti8Vtl1Yp
+        pVZUHLIRAtmEk8lie8fxHP0/9N4LruzxwsPBO/8oj28mC8E4OdqbmeR93mfe
+        zcc72T//+u13ANfRZLjGnabnWs3nVcNt7bvCrLat6rbH93csQ1Rrru16lRoR
+        7liukwNjKO3yA161ubNdfbS1axp+DimG7G3Lsfw7DKmJyfUiMsjqSCPHkPZ3
+        LMEw03iVQgtUZtv0F21u7E3PNm9uPth9Ipe+zzD+3wvl0M3Qzw3DFKJyuk7F
+        2C+iF0UdPSgxDFB8iXt7yx5/EZUYiqRTKL2B0Btk6CX0T6cvcs7yL4T5IwyD
+        FG5Y2zsxaTiSzqg0L4bmpfAOPN2xfDOyzl2TJNJ4LTReZ+ih+KrZjPJLUT7F
+        ZfYbYXYlXH/ZM01Hub4k0ngrNCbCa1+026by2gMg898O868RpfAz07bd7yJj
+        IDJCJJ1q6MyGNWovuKOsEQCZ/06Yf51+MoVX+Lbp+DxSBiOlw6R1M7Teo9tP
+        ZM3jjtjnHuHIHInMc1zaC6F9m2FuorHn+rblVHcPWlXL8U3P4XZ1yfyWt22/
+        5jrC99qG73or9A6Z3sLkug4taIaBihHBzZakQW+80mp0R06FFdPnTe5zimmt
+        gxQ1NQuGrmAAA9uj+HMrOKM7qzXnGDs6PhzUtRFN10rHh7qW18KTfDl/8mNq
+        5PhwXptli7m8dvJzVitpq+VSalSbTf/xkh0f0sAorJOaG03nM6Us4XwS7pJY
+        T8IFiYtJuFviniTcK3EpCfdJ3J+EByQeTMJDEg8n4QsSjyThssSjSfiixJeS
+        8OVS9uR7raBn8ic/jc0yejBXggc3z4LHmZH7GEPlf+yl9EYw2izTQVfSFDQO
+        Q/50T6NIOGVkmzN0nW1CDLlOy9CGS5sGQ+FcI5AhNx7a8MPuJfVs16YCsvbM
+        nh+UdJuU1tuwHPNhu7Vlemt8y6ZIf8M1uL3OPSs47wSLdccxvZrNhTDpa6E/
+        dtueYd6zAlZebTu+1TLXLWFR8l3HcX3uUz2BOWqrdPCuU19qwUeH7tLXdFYN
+        Xn6aM1O/In9EBxo2acyGQXxDY7Fz3AWd5j4UZCSQZyg7YOmX6Psl5mbPuekz
+        t1/lDsXdnNIdVrnluJtXuqMq93Lc7VK6Yyr3StzVle64yn0z7haU7lWVOxl3
+        i0p3SuVOx91upTujcufibo/SnVe578bdXqV7Q+W+H3dLSveWyv0g7vb926X/
+        Nxnc6bjTNGudZvjwSH4YAmE4DHaKBUcf4S6xFLh88IHUgy9RxpYs+BUMmn+g
+        +CLl1jaQqmOpjo/ruIdlOsQnddRxfwNM4AEaGxgT0AVWBLICDwUeCRQEigKf
+        CnwmMCWwKjAv8FigX2BNYFjgicBVgXWBUYGnAjcEPhcYF3gmcEvgCxGsuSEw
+        8zddh+AewgoAAA==
         """,
         """
         androidx/compose/ui/graphics/Color.class:
-        H4sIAAAAAAAAAI1X+1Mb1xX+7kpCYllAYBkDJsQPagsMFhA3TW3HxkDjSBY4
-        MTYuIWm6iI1YWHbl3ZVst2lL005D2+l0Ok3bSTqdNukjfdhtHCdA45kOdX7r
-        +E/on9Kpe+7di4Rhp47H7Dn33O887nncC//67yf/AHACf2c4pNvzrmPO38gU
-        nOWS4xmZspkpunppwSx4mTHHctw4GENyUa/oGUu3i5mLc4tGwY8jQtKi4U/r
-        VtkY8AamL0xeuMIQSffmGNSyPefcGDCXS5aGOOpUKEgwRP0F02PoyT/e6ymG
-        Rt+Z8l3TLgo7DHvTud58LY5gj3D7dspGy6Y1b1DgTQx1p03b9M+IwKY1JNGi
-        ohmtDJpwk67w8J9NIEVQvVQy7HmGgfRuN7s9Sy+nNLRhHzfaTkaXHN8y7cyV
-        vGMX4+jUoKFRxX507bAaJPExVru51ScZutJj/x94kAMPMSS2MsaQSofkSkMP
-        PsexR6gWulscZGA5XhsKr3FB9xbGnHlDZjtK2c5qOIZ+Hv8AGd8CiFxmuRpJ
-        G4xrZd3ypFJbOhdyyJcYYo6/YLgMrbu3KfGBDV7hMG0Nw3iKu3smiGpaRZRX
-        MCZqp+E0eutp91nqx4Jje75bLviOu+0Y1JCJrXZkOMrb6DM0IG+Wk9ztGGWp
-        QrXddlJKXCydy/GTKaUh/hmms+mFguF5PTQUo5ZeWOoplAgmWA0XgiDzdMga
-        bFx3l867+k2BTGytNFwMwC8wtNTAVWA0AE0FoMuU9RoobxYXasj66lLD1QD+
-        5UfivLpg+kYQp2A1zAawlymZNdglY16AIsRoeDWAfPURS+ddw7ADS4LVUAhg
-        848cYpQqFhxiVNSuGIAWGPbUQDOGZTnXBawu4DUsBUDrEWtjN/XAZ5RzGpwA
-        RIJUDTShFw3b1wUuLhcavADqM7TXoJdd3fZKuksQAW/YJtBwPVC5QaU6XbDk
-        tdL/+E7qGaMd3TYdO46vMwyl8/KWWKwsZ0zbN1xbtzLjxmt62fLHah08Qf1A
-        Ax5cW99Q8Tq+SSWtGmM4/hnauOacGnoF3+YneCNG1z8e0g/dxY83cYEu++9R
-        XcVCwypGVLyJ7wdGxsfHA2Z1dTVgHjx4EDD0TzKA9Phwi8HWVlVSAz/kU5vt
-        zXFXv+aufsNwOO+4xcyi4c+5uml7Gd22HV/36VheZtLxJ8uWRRdJ2/bM5irL
-        WZsWBm20bG1MGL4+r/s6yZTlSoSngH9iNOJLJLph8hVNtzJPU/3vzZU+VWlX
-        VCW5uaLSf8En6mjdQDRKNEE0QrSJ08T9N0faN1cOtA0rg+wkaxttba1LKp3K
-        YOTTDba5cv+9umgimozlOpP1JFSHE8mGzmg7G2TPf/rziNjVko25ZLKJdptJ
-        xoQsmWwhWSvJ9lRlqeTeS13bTNOH0Y9CmyqPqjOaqEvG768yJfD8htJMAXao
-        scT9d7sHGfEH+Rnp0qIWaMpvf7UoMwlR6eNLNBz7L5Vt31w2snbF9Mw5yzhX
-        SzwfO/EcNOcpy5Pl5TnDvawThl/zTkG3pnXX5GspbJzy6Sqc0EtyrWVt23DH
-        LN3zDDKmTjllt2A8Z/K9Dul3epdXDFEHR6lKTejgDU0HuEOrOqLvEW3lzwHR
-        Tn7jCnpR0ilJr0o6K+mrkhYkLUq6JKkjqSfpdUE70EKdy71+SKsMxcR4H/Wt
-        of42MQruyqBAwX5EXy0AQEUD0Xr+i4FUPokI4YGue2ieWcee1r1r6OjewBNr
-        OJDsXcPhNRz9QAxrzU4X0iIMxl90aeeIDCLBg9hA306dRNU3PepS5zDpcN8x
-        8nf81g6FWNVJBoPhToZ26tSc0KMtdV6gFPDh3t//TyjvIBa51b8JhfRHuw++
-        9TZfR2+JnH1M3ziU+v+gOUhamwhuv4yDcyfweRHB0/iCtD4k01fPIzq2gS/W
-        QgrU62VInOPqLKnwp12qnyF1PvRq3zpO9T35Mc7cCa1fYEut2lJFo9GFjLMY
-        kbYOydaMdp87cHtHYqJBYyY7cA6jEn+UpCLCe1BmutcxvrNk9fiSUGrhv0Rv
-        K1nQax/hzE4vW/3VgedwXiqcJS88Kq37wFvvIB59H9FILd8xKOrI9nRpeF5m
-        W0OWOIVCzlW9dwkMHedDTATOtyWKkJNhyBfDkJfCkFfCkNNhyJkw5EthyFfC
-        kF8JQ+phyLkwpBGGfC0MaYYhF8OQy2FIOwx5LQzphiHLYchKGPLmLiTN8tfo
-        lguQn4ghASr38PoMW8e37uI7KXx3Az+4i4kUfiiYF1P4kWCupPBjwcyk8BPB
-        vJLCTwWjp/AzwRgp/EIwZgpvC2Y5hV8K5loKvxJMObKBd+/i5p1qbMPUlQ0U
-        YYom4gmK8AjNSIaa/hmSnqO9HF2rU/Q2vEx/5Rg05jadIII1MbCMfoVS6M3o
-        wLpo/w+wQdQn7rdEf0ej8PtZRLL4Qxbv0xd/5J8/ZfFn/GUWzMMt3J7FPg8N
-        Hv7q4bSHv3k462HEQ8xDHb0PHp4WWyc8DHt4ykNGLI956PfQI3jNQ6OHlf8B
-        UC9ZO4QPAAA=
+        H4sIAAAAAAAA/41W+1Pc1hX+rvbBIgQIvMaACbFjYi8YvEDa5mHHsYHG2TXg
+        xNi4hKSpWJRFIKS1pMV206bUfYT0MZ1OX5N2Op2k79Zu4zgBGnc6lPyW8Z/U
+        qXvuvWKXh6YOs+ice+53Hvc8rvTpfz/+F4DP4Z8MjxnOrOdas9ezBXex5Ppm
+        tmxli55RmrMKfnbYtV2vBoxBnzeWjKxtOMXshZl5sxDUIEbSohlMGnbZ7PP7
+        Js+Pn7/MEMt05xkSS1zKwPIaapCqhYJahngwZ/kMXaMPd3qSoT5wJwLPcop9
+        1mLJZtifyXePVsOQe4Q7sFs2VLbsWZPibmRInrIcKzgt4prU0IRmFTr2MWjC
+        TUbE+WwK+wlqlEqmM8vQl9nrZq/n0MtJDQfQyo22kdEFN7AtJ3t51HWKNTio
+        oR4NKjrwyC6rMocPsfoot3qIoSMz/P+Bj3HgEYbUVsYY0pmIXGl4HEc59hjV
+        wvCK/SrVhUKrnzP8uWF31gwzHadM5zQcRy+PvY8MbwFEHnNcjaR15tWyYfuh
+        UksmH3HAlxnUsjPjXhcojZouybU/Ty3iBnOmx9C8V4tqIU3zokcZ1TCIJ7id
+        kzLYSRVxXlS94Dp+4JULgettOws1ZGorBIZjvI8+QwfybnmWOxmmPl6i4m47
+        bj/Fn8nneSTP4xzP0gsMSmmAPwbpTEahYPp+F43HkG0UFroKJVIQrIYxOQ/j
+        dLgqbMTwFs55xg2BTG2tNLwkwRcZmqrgCjAuQZclaJKKUAWNWsW5KrK2stQw
+        JeEv74jzypwVmDJOwWp4VcK+TGmtwi6aswIUI0aDISEzOyyd80zTkZYEq8GU
+        sNd3HGKIBk8egnMaLAmaZ9hXBU2Ztu1eE7Ck5DUsSqCzw9rwDUP6jHNOw1UJ
+        ov5KV0FjRtF0AkPgasKFhrKEUoVbq9BLnuH4JcMjiIDXbRNouCFVvkqlOlWw
+        wxum9+E91TVMO4ZjuU4Nvs4wkBkNL4z5pcWs5QSm5xh2dsR83SjbwXC1l8eo
+        H2jW5Q32DRVvYplKWjHGcOIzNHTVObX2TXyLn+DbCXoR4AH907X8cBPn6dpf
+        obqKhYbv4YyKt/F9aWRkZEQyKysrkrl//75k6C9kgNDjgy0GW1sVSRX8gM9v
+        rjvPXb3LXb3HcGTU9YrZeTOY8QzL8bOG47iBEdCx/Oy4G4yXbZtuhZbtmc0v
+        LeYcWpi00bS1MWYGxqwRGCRTFpdiPAX8UcsflA22QPLrFl/RsCuzNNqfbiz3
+        qEqroir6xrJKP8GnkrSuIxonmiIaI9rAaWrzrTOtG8uHWgaVfvYMaxlqbE7q
+        SrvSH9t8LxlPxfVEvl2vpbU6mNLr2uOtrJ+98MnP5a6m1+d1vYF2G0nGhEzX
+        m0jWTLJ9FVla33+xTVr9ZJ1tLNODb6g8mPZ4KqnXbK4wZfOmUqcmUpvvdvYz
+        Cu0wPxHdU3TOhtHt7yxKRkoU98RCwHDwYtkJrEUz5yxZvjVjm2erueaTJl4I
+        jaOU2PHy4ozpXTIIw290t2DYk4Zn8XUorJ8I6PYbM0rhWss5jukN24bvm2RM
+        nXDLXsF83uJ7baHfyT1eMUBNG6eaNKCN9zAd4ENaJYn+jmgz/9gg2s4vWUFf
+        CunlkE6F9NWQGiE1Q2qFdDGkV0NaDukNQdtoDBPC60e0ylJMlEskej6EepsY
+        BathUKBg1+ipSQDqiKMe458FofIziBEe6LgHfWoN6eaWVbR3rqNzFYf17lV0
+        rSLzvujIqp0OdIswGH+fh3aOhkGkeBDr6Nmtk6r4ptd6qHOEdLjvBPk7cWuX
+        QqLiJIv+aCcDu3WqTuj9HOq8SCng83yw999QfolE7FbvBpRVfGGo8/BP3+Hr
+        +C2Rs3V61kCp/Q8aZdJaRHAHwzg49ySeEhE8TWmT1gfC9NXyiI6v41Q1JKle
+        G4bEOa7OdIW/10P106TOR1ztWcPpnkc/gnonsn7SllqxpYpGozsYz+FMaOtQ
+        mE2l8/autCiyLfU2nMVQiD5GlkV896BMda5hZHfBavFFodTEv5m2FWxHp7GI
+        7mrjnyShwgnywscl2XloHbnduUkiH6Y2ifPEKRThaMVZh8BQBj7ABelrW1YI
+        +WIUciIKeSkKeSUK+aUo5HQU8pUo5GtRyK9EIQtRyNkoZDEKOReFXIhC2lFI
+        NwpZikL6UcggCnktCnk9CvnGHiTV/mt0eUrkx2IigKV7eHOKreGbd/GdNL67
+        jh/cxYU0fiiYiTR+JJgrafxYMNNp/EQwr6XxM8EU0viFYIppvCOYhTR+JRg3
+        jV8Lxk/jN4K5FlvHb+/ijTuV2Aapm+sowjRNzyMU4VEaiSxN3lMkPUt7ebpF
+        J+gefQWNdH3rcGiuY/iHmE5Gn0gKvSDa6DR8/u7iHtGAuN8T/QPNyh+nEcvh
+        Tzn8OYe/4K/E4lYOt/G3aTAff8f70zjgQ/Nxx0eNjw98POfjjI+Ej6SPlI+n
+        xdaTPgZ9POEjK5bHffT6eFzw9T4afNz8Hx1rfp1uDwAA
         """,
         """
         androidx/compose/ui/graphics/ColorKt.class:
-        H4sIAAAAAAAAAJVUz28bRRT+Zn/a2026ae202dSpk7hglyR2UkgAN6EhUiSn
-        LpUo6SUHNF4v7ibrXWt3XZULREj8EVy5c+GALA4oKjdO/EWUN5uVnaZCLSvN
-        vB8z73vfmzezf/3z+x8APsQuQ4UH3Sj0ui/qTtgfhLFbH3r1XsQHzzwnru+F
-        fhg9THQwBuuYP+d1nwe9+uPOseuQV2ZQ0y0MSvWgdsBgnoSJ7wX1w3YY9HTo
-        FOaEQZxEQycJo1WvP/BN5KEZyMFQiQRe0cew9HYaOqYNXIVBOZ3znOxA5G2J
-        vKzFoFf36RNWfo9AeOCFAcNa++3QlfH+polZ3MhTnpsMK/8nUodNxfbc5HOf
-        Oyerje7W1w+PDxnkau3AxC2UDMxjgezI7RLffSqjF7kuMVQ6/tAlk/uDZ5xh
-        6hy4637Dh37CYKdltdqXj78pcFUUDUh4X1Tfok9Ub6fafwbURMAHDDPtrFeP
-        3IR3ecKbDFL/uUw9YWJSieWJUCTyv/CE1iCtu87w99npgnF2akg3pVRYuiHl
-        VJI5khLJPLnthkWT1GAbmiWRlEkqmVRTmctJlia0P0fs7PTlzxoB2bOTqBzJ
-        /GTNuIyYzxDzGWJ+jHgh6splRHOyNvXyB0khynOirg16DO9wV+iUwJBL9bUT
-        6o+yF3apfVfbXuB+Mex33Ogr3vHJc60dOtx/yiNP2Jlz6klC1+MRH2S28SQc
-        Ro677wlj7sthkHh996kXe7S6GwRhwhO6XDHWqWmKeC/QMEdd1IhEk6wOeXWS
-        Kwu78qZSHuHKbgHmliJvauVZ5XthW+VNMtVyUfmWzBGsX0RTcZ/maynmLAwa
-        No0qjW3ymIROmJihHUjzXc/ytSFDvFvbvi9vz/9IgA+s8g6lvl16A30a4tLY
-        hG6n+BNkm5ALGXIxQ36cVaj/irnfcHsCo6UhS2n43fMtKGMxPQyd/Ivpuo5l
-        0qRUq5AmW3ncwXsZeJPiNFFwUbFy3/0E1dxfWq7cGaF6nmeHZhnMuMC7RL+o
-        ReJeSlnW3o1l7RLLwphlYcyyMGZZyFjezcC3M5aFjKU+g1c79vyt0ggrr/E0
-        L/CsEM8qnWuFlj9LN32KByQPCXSVmK8dQW6h3kKDZqy3sIF7Lfr5f3QEFmMT
-        W0eYjqHG+DhGOcYnMZZiLMeoxCjGmEk912PUUkX7F4jgH2k8BgAA
+        H4sIAAAAAAAA/5VUTW8bVRQ9b/wxnskkcRI7NJMm5MMFuzRxGgoFTFtSS5Em
+        calESTdZoIk9uJOMZ6x546psoBt+BFv2bBBCEQtUseRHUc4bj9wQgVpG8j33
+        3vfueee+++Q///rtdwC30BaouWEvjvzes2Y3Ggwj6TVHfrMfu8Mnflc221EQ
+        xYeJDiFQPnWfus3ADfvNhyenXpfZnEAh3SKQrx80DgSssygJ/LB51InCvg6d
+        Zd0olEk86iZRvOUPhoEFA0UTJZgFisBLfgIbr5ehY8bELEye2R2fKQ7UuY46
+        VzgCen2fn4qMNknc0I9Cge3O66lrk/0tC4t4y+A5VwRu/J9KHTab7XvJ/cDt
+        nm3t9G5/dXh6JJCrNw4sXMWKiWWsMo69HvXus41+7HlUmD8JRh5DNxg+cQWm
+        x8Q972t3FCQCdtqW07l8/S3FW0DVhIZ3VfcOP9W9nXr/WdBQBe8JzHWyWT3w
+        ErfnJm5LQBs8zXEmQhlDGVDqmXI0Lj7zlbdDr3dT4JcXz1fNF89N7YqWQlk3
+        tVKBWCJqRINpe6tMo+2I3WJZI+aI+QwLKZZKWrmovD9+LJLDXnhVUCIaadq8
+        zGNkPEbGY0x4xgVTl3msND2ttO/y1b/Bo+B1sPtS6m+fcRD5dtTjnGY7fuh9
+        PhqcePGX7knAzHwn6rrBYzf2VZwlpx8lfAcP3GEWW04YenE7cKX0pID5KBrF
+        XW/fV2tLX4zCxB94j33pc/NeGEaJm/BRSdzksPJqEChiidMrUtOnjA6Z1YjV
+        1XNMVWB9RyivfUN7jvJPamC4QzufFi/SLmKKvzn+7jJjkYbFjOeJinghI95D
+        Ll2btb//d8oZqFdgs8QmpX2BbpZ0lYyumtE9zPTrP2PpV7z9iqaYlmyk5dfH
+        W7CG9bRVnfn1dF3HJj0t9Wr0cmUD1/BORt5iXVF1Wc2XS9/+gIK1v7FZu3aO
+        +vice7Tsxryge4V/POswiUpl481UNi6prExUViYqKxOVlUzl9Yz8TqaykqnU
+        5/Dyrr18deUcN/6h07qgs0addd5rjdFnjE2SLfOGF6l7Ly1q4T7xiPktdrJ9
+        jJyDpoMdh29m18H7uOXgA3x4DCFxGx8dY0aiIPGxxJrEJxIbEpsSNYmqxFya
+        WZBopE7xb1ipCXciBgAA
         """
     )
 
     val Composable: TestFile = bytecodeStub(
         filename = "Composable.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0x12c49724,
+        checksum = 0xbcdac3c7,
         source = """
         package androidx.compose.runtime
 
@@ -198,31 +197,30 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlkZiXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbKsQVlJqbmpuUWuRdwqXJJYyhrjRTSMgZwk7xzU/JTMsEK+XjYilJ
-        LS4RYgsBkt4lSgxaDACMRj6sewAAAA==
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuaSTMxLKcrPTKnQS0wuySzLLKnU
+        S87PLcgvThViC0ktLvEu4RLl4gYK6aVWJOYW5MCFlRi0GADOEtiIVAAAAA==
         """,
         """
         androidx/compose/runtime/Composable.class:
-        H4sIAAAAAAAAAI1STW/aQBB9ayBQ2ibQT0ia5pu0PdRp1FtPQJwWiS8ZJxLi
-        EG3sVeRg7AivaXLjUKn/qYcK9dgfVXUWVKCSpdaW3s7OvNnZeTs/f337DuA9
-        3jDscd8ZBq5zq9vB4CYIhT6MfOkOhF6d7vmlJ9JgDLlrPuK6x/0rvXV5LWyZ
-        RoJha+Hlvh9ILt3A18tzM40Uw369H0jP9ZcpjSiUFXES2NFA+FI4Hxg2Y2im
-        kBQmi+KpEfciwXAYw1tUXM5YqdSaZbPLsB6TYvHhlZDEWuWeF3wWzswRxt93
-        UWCelzk9a1atWqvJkLS6bYNOUstFu2yWG4ZlmAxrbbPVNkyre/HRsKaenXqs
-        Yn8JsR3PWe6s9A9KO/Bc+06JVq2XOx0lbmzCvJnd+LjhCXUt6+5GKD2prU+t
-        E2p92uhZh3rO/xGrISR3uOTE0wajBA0YU0Dvz/rkunXV7ogs5x1DcTLOZLWC
-        ltVyG5kfX7XCZHysHbHKZKwIxwwH9f8YTCoFhocLx9u+ZMh2gmhoi1PXo2Ep
-        mrOsczd0ibB4xrBElZCk/BWoT8OrKR7iNa1fkKYfyFD8nkAW9/FAleohKbCK
-        NQU5BXkFj/CYuE9m3Kd4hufK7CEhUEBRQV7BOjaQwgvy17BZw0tCbCnYrmEH
-        uz2wEHvY70ELcRCi9BuuoX9IqAMAAA==
+        H4sIAAAAAAAA/41SW28SQRT+ZoFCUVuwXqC19k6tJm5tfPMJ6FY34ZZl24Tw
+        0EzZSbNl2W3YAds3Hkz8Tz4Y4qM/yngGImCyiWaTb7455ztzLnt+/vr2HcB7
+        vGHY477TD1znTu8EvdsgFHp/4Eu3J/Ty5M6vPJEEY8jc8CHXPe5f6/WrG9GR
+        ScQYtuZW7vuB5NINfL04o0kkGPYr3UB6rr8oqQ5CWRKnQWfQE74UzgeGzQiZ
+        JSS5iZE/MeTeQDAcRujmGRcjlkpmrWi1GNYjQmzevxaSVCvc84LPwpkawuh6
+        5wlmcamz81rZNus1hrjdahj0kjouG0WrWDVsw2JYbVj1hmHZrcuPhj2x7FQi
+        J/bXILajNYudFf4haQSe27lXQytXis2mGm5kwKyZ3Wi/4QlVln1/K9Q8qa1P
+        9VNqfdLoeZN6zv4ZVlVI7nDJSaf1hjFaMKZgWQEYWJfsd666HRNz3jHkx6NU
+        WstpaS2zkfrxVcuNRyfaMSuNR0pwwnBQ+Y/tpHz0/KO54W1XMqSbwaDfEWeu
+        RxuTt6ZRF27okmD+L8MCZUKc4pdUlcSPJvgKr+n8giR9QIr8ywJpPMBDlaqN
+        uMAKVhVkFGQVPMYaaZ9MtU/xDM8VbSMmkENeQVbBOjaQwAuym9g08dLEFraJ
+        YsfELvbaYCH2cdCGFqIQ4vA3hGOdXq0DAAA=
         """
     )
 
     val Composables: TestFile = bytecodeStub(
         filename = "Composables.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0x92d0959f,
+        checksum = 0x8882d27,
         source = """
         package androidx.compose.runtime
 
@@ -251,41 +249,41 @@
         """,
         """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMuWSSMxLKcrPTKnQS87PLcgvTtUr
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgMuWSSMxLKcrPTKnQS87PLcgvTtUr
         Ks0rycxNFeJ1BgskJuWkFnuXCHEFpeam5ialFnmXcPFxsZSkFpcIsYUASe8S
-        JQYtBgDjkUhNXwAAAA==
+        JQYtBgAsMUsXXwAAAA==
         """,
         """
         androidx/compose/runtime/ComposablesKt.class:
-        H4sIAAAAAAAA/51VzXLbVBT+rvwnK04sy05xXEhT103tGCrHpfzUaaBNKfHg
+        H4sIAAAAAAAA/51VzXLbVBT+rvwnK7ajyE5xXEhT103tGCrHpfzUaaBNKfHg
         BiY2gWlW17IaFNtSR5I9ZZdhwzN0yxPArrBgMmHHg/AUDMORLCdO7GkK49H5
         P+d+55wr+c9/fvsdwPv4jGGVmx3bMjovVM3qP7ccXbUHpmv0dXXL13m7pztf
         uDEwBvmQD7na4+aB+mX7UNfIGmIIdfXvGT4v7jcuumuNruX2DFM9HPbVZwNT
         cw3LdNTHgVSplaZTGFobrXvT9s3/UX+j3GrVNmslogw3G2/QKcXdaFj2gXqo
         u22bG1SNm6bl8lHlHcvdGfR6FBWmph0REsPyBAbDdHXb5D21bro2JRuaE0OC
-        YVH7Tte6QfZX3OZ9nQIZbhVn9HRmaXpFDmqlvQQWkJQwD5kh0u5ZWleEcv7o
-        Ge3HkGGIGubQ6uoMmeKMaSdwBW/NYRFZBrFgFJ4V/GWyOkN6xrwZVi5bKUNy
+        YVH7Tte6QfZX3OZ9nQIZbhVn9HRmaXpFDmqlvQRSmJeQhMwQafcsrStCOX/0
+        jPZjyDBEDXNodXWGTHHGtBO4grfmsIgsg1gwCs8K/jJZnSE9Y94MK5etlGF+
         Vx/4w9yyaBymy3B3VpuXXY09hkf/PW9j7P/aNFxv91Sm8LqN0kKCxce0EV4R
-        eZqWP4ypTpRZM0lfCNu2HAotFJ++SY93Lg2b1VJ2FrzRuVFOaUNaOHvKkBrn
-        PtFd3uEuJ7hCfxiit595RPQIKLbrCQI5XxieVCGps87w1/HRmnR8JAmyMGJE
-        PJ4VRo9IjzwX8JTHcyWKyQkVVhVlIRfOskqompLDuXklrJC1Ejn5KSqI0e2T
-        H8U/XjEKLckxPzwqi8Tj1bQYfl34Q6oqbEv5sHh8JEvVK/JcLqGIIlP8oyqJ
-        /PjI+VGNbWmqhqfKCyc/CDEpIp68rFaY122VeYNQxgObvNGsxbAw8Tm83aU5
-        h7esDk052TBMfWfQb+t2y3N6JSyN9/a4bXh6YIw3jQOTuwOb5Ku7o+9O3Rwa
-        jkHuB2cXku7NRe/p9+Jc2HzT5Vr3CX8eHCA1rYGt6Y8NT1kKauxN1cc6BIS9
-        pSOEJUQQJW2DtCbZvc0vrilzr5AqK2miofvlX7HE8LN3OXCfaJRmtIA4Nkle
-        oYQFxJDDVfJSKiS87ZdehIJ3KPITPy+GT4NMkfgDeuYFUuL+zfPoEpZxLcCx
-        G+CQy8qNCQTf/HIKQSIuQkYSqVMYIv0KAQyZurrpw5CRn4CxMhvG9QkYq7gV
+        eZqWP4ypTpRZM0lfCNu2HAotFJ++SY93Lg2b1VJ2FrzRuVFOaUNaOHvKsDDO
+        faK7vMNdTnCF/jBEbz/zSNwjoNiuJwjkfGF4UoWkzjrDX8dHa9LxkSTIwogR
+        8XhWGD0iPfJcwBc8nitRTE6osKooC7lwllVC1QU5nEsqYYWslcjJT1FBjG6f
+        /Cj+8YpRaEmO+eFRWSQer6bF8OvCH1JVYVvKh8XjI1mqXpHncglFFJniH1VJ
+        5MdHJkc1tqWpGp4qp05+EGJSRDx5Wa0wr9sq8wahjAc2eaNZiyE18Tm83aU5
+        h7esDk15vmGY+s6g39btluf0Slga7+1x2/D0wBhvGgcmdwc2yVd3R9+dujk0
+        HIPcD84uJN2bi97T78W5sGTT5Vr3CX8eHCA1rYGt6Y8NT1kKauxN1cc6BIS9
+        pSOEJUQQJW2DtCbZvc0vrilzr7BQVtJEQ/fLv2KJ4WfvcuA+0SjNKIU4Nkle
+        oYQUYsjhKnkpFRLe9ksvQsE7FPmJnxfDp0GmSPwBPUmBlLh/8zy6hGVcC3Ds
+        BjjksnJjAsE3v5xCkIiLkDGPhVMYIv0KAQyZurrpw5CRn4CxMhvG9QkYq7gV
         wGgHMDJjGLmXkCaghPBwVOxvpNkErCzSVOcMVgKlAFYGayj7sDLnYBWnYMWF
-        U0gCtnxawyPi35L1XeruvX2E6rhdh1pHBet1VHGnTn/nd/fBHHyAD/eRdLDs
-        4CMHEZ/mHXzsQHSw6mDNt9xzIPmC4iD6Lx9Lm/oRCAAA
+        U0gCtnxawyPi35L1XeruvX2E6rhdh1pHBet1VHGnTn/nd/fBHHyAD/cx72DZ
+        wUcOIj7NO/jYgehg1cGab7nnQPIFxUH0X0eNH/YRCAAA
         """
     )
 
     val Modifier: TestFile = bytecodeStub(
         filename = "Modifier.kt",
         filepath = "androidx/compose/ui",
-        checksum = 0xe49bcfc1,
+        checksum = 0x33b78359,
         source = """
         package androidx.compose.ui
 
@@ -308,113 +306,114 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlkZiXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbKsQVlJqbmpuUWuRdwqXJJYyhrjRTSMgZwk7xzU/JTMsEK+XjYilJ
-        LS4RYgsBkt4lSgxaDACMRj6sewAAAA==
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUueSTMxLKcrPTKnQS87PLcgvTtXL
+        TSxJLcpMzBHiCk5OTEvLz0nxLuHi5WJOy88XYgtJLS7xLlFi0GIAADDzNLNQ
+        AAAA
         """,
         """
         androidx/compose/ui/CombinedModifier.class:
-        H4sIAAAAAAAAAKVTWU8TURT+7nRlKFJGyw6iVOmCDCAusQajGJMmBQ0QYoIv
-        t+0FbjudITPThkfiT/EX6AOR+GAIj/4o47ltKVpIeTBNz/Lds58zv37/+Alg
-        Bc8Zktwuu44sH5klp3boeMKsS3PNqRWlLcrrTlnuSeFGwBjiFd7gpsXtffN9
-        sSJKfgQBhsnr/C/9Qgzhl9KW/irDq1Shl3Gu92t6h2G24Lj7ZkX4RZdL2zO5
-        bTs+96VD8objb9QtK8cQcuq+cKPQGaarjm9J26w0aqa0CbW5ZeZt3yVvWfIi
-        iDEkSgeiVG27f+AurwkyZJhLFbo7zv2FbKkg+1RWDLcwqGMAcUotbVulNhgC
-        KfUUwR0dQSSolN7txaBjpA8aRmMwWtI4Q9A/kB7Dw2t9u7eUa9oLm2H1hkmn
-        ez8zpHu9J9+KPV63/Hzt0KIRzjB8+r/N3jSZadzXcQ+zarXUIO1mqNBe7Lrw
-        eZn7nGrWao0AXTVThM6OVQk6kkpbJKm8xLB9dhzTtVGt9Y8GRs+Ol7VF9iZh
-        hOPaOEnEA4qffwlr8eDmrZb28fxzUCH62TFBWhekYi8z9F/Uu1D1GSY267Yv
-        ayJvN6Qni5Z4fXmptKU1pywYBgu0vY16rSjcbU42DEbBKXFrh7tS6W0w2R2r
-        c6P/BNW3nLpbEu+k8hlr++xcyY4luqwg6LMkbqijI3mJhhQm3kfcUOfXhWnE
-        I4gSXyZNEFdjncga/acYmjduE818x3Ame4KxzPwJJr41nR43wwURQ5x+Q0iQ
-        Nk7SCuEzrRCYxBTQlFqlKEkVoOEJyQNau4ILOo275KiqeEEmmqoxkz1F8msn
-        YbgZpJVkuGXRSRLGgyu9qTQR1mn0aZMu4lkzBX16CGFuF4E8UnmkiSKjSDaP
-        eTzaBfOwAHMXIQ9THkY86B4MD9E/kXas0GMFAAA=
+        H4sIAAAAAAAA/6VTWU8TURT+7nRlKFBG2RdBqnRBBhDXGoxiTJoUNECICb7c
+        the47XSGzEwbHok/xV+gD0TigyE8+qOM57ZlsZDyYJqe7Z7znXV+//n5C8Ay
+        sgwJbpdcR5YOzaJTPXA8YdakuepUC9IWpTWnJHelcCNgDPEyr3PT4vae+aFQ
+        FkU/ggDD+E3xl3EhhvAraUt/heF1Mt/JOdv5NbXNMJN33D2zLPyCy6Xtmdy2
+        HZ/70iF53fHXa5ZFLYWcmi/cKHSGyYrjW9I2y/WqKW2y2twyc7bvUrQsehHE
+        GAaK+6JYaYV/5C6vCnJkmE3m2zvOXrFsKpA9KiuGXvTp6EGcUkvbVqkNhkBS
+        PUVwV0cQA1RK5/Zi0DHUBQ3DMRhNaZQh6O9Lj+HhjbHtW8o2/IXNsHLLpFOd
+        nxlSnd4T78Qur1l+rnpg0QinGD7/32Zvm8wk7uuYxoxaLTVIu+nPtxa7Jnxe
+        4j6nmrVqPUBXzRTpUgQMrEL2Q6m0BZJKiwxbp0cxXRvWmv9oYPj0aElbYG8H
+        jHBcGyWJeEDxs69hLR7c6G1qn86+BJVFPz0ik9ZmUthLDLGrk2HoPu9hvuIz
+        jG3UbF9WRc6uS08WLPHm8nppc6tOSTD05Wmj67VqQbhbnHwYjLxT5NY2d6XS
+        W8ZEO9bF3f4DGsupc1y1uOcJUvVNp+YWxXupIEZaENvXisEiHV+Qphcmbqi7
+        JPkxjTBMvIu4oS60zaYRjyBKfJk0QVwNfSxjdJ+gf864QzT9A4PpzDFG0nPH
+        GPveCHrSgAsihjj9+jFA2ihJT8k+1YTAOCbUNklqlqIkVYCGZyT3aK0Kzukk
+        7lGgquIluWiqxnTmBIlvFwnDDZBmksGmx0WSMB5c602libCWEsBzojpp0+Sw
+        iBG8aAAvUTqVkr5WhDC7g0AOyRxSOaSRIRFzOTzC/A6YBxMLOwh5mPAw5EH3
+        YHiI/gWbMWV0lgUAAA==
         """,
         """
         androidx/compose/ui/Modifier$Companion.class:
-        H4sIAAAAAAAAAI1SXU8TQRQ9s1u6y1JkQYHyIX5QoYCyQHwwlpBgo7GmVCOE
-        xPA03Y4w7XbW7G4bHnnyJ/gD/AUSHzCaGMKjP8p4p1QUTMCHuTP3zDn33rl3
-        fvz8+h3AQ6wwzHBVi0JZ2/f8sPkujIXXkt5GWJNvpYhyRcK4kqGywBjcOm9z
-        L+Bq13tZrQs/sWAyTF4WwUIPQ3pVKpmsMZj5ue0MLNgOUuhlSCV7MmbIl/+v
-        iEJHIRTD2uWSwtzl1wzT5TDa9eoiqUZcqtjjSoUJTyhJ7FXCpNIKAmL1hJQu
-        suEyTDXCJJDKq7ebnlSJiBQPvJJKIlJLP7YwxDDs7wm/0ZW/4hFvCiIyzObL
-        FztX+AvZ1EF2C7o1NzDs4DpGKN9VL7BX/aDTVgeG7qWTy5Uqm1vrleLTDCaQ
-        6SV4kmGw3C18QyS8xhNOUqPZNmn+TBsaD2sQtC+1t0Sn2jLDo+ODjGNkjdNl
-        m/bJezN7fLBiLLEnlm2cfEwbrvFi0DXHCVlJuym9Pz/5kNJ6+lW9ZzNj6Ptd
-        9GIjoQEWw5pgGChLJSqtZlVEW7waEDJUDn0ebPNIar8LTrxuqUQ2RUm1ZSwJ
-        Wv8zJ4bcxduznp+jZUpKiagY8DgW5DqbYSvyxTOpE4x1Q2z/Ex7L1MAU6PeC
-        uVndUeqPSRh9X0LnyfNoZ7qH80dwDulgYIFsugP24T7ZzCmBPC1n6Mc1CqLF
-        q8Q2aLcXhga/YHTh0zl9mvhaP3LK6er1yUWW7h90eQO0L9KyWNexMXZW32hH
-        TKV8g/HmCOOfcfOwA5hUOuAQzaAoeZIsdbLP0aOBx4RPUc23dmCWcLuEO2Rx
-        V5vpEnK4twMWYwazO+iJkYmRjWHH6I/h/gJ6Cp4UWgQAAA==
+        H4sIAAAAAAAA/41SXU8TQRQ9s1va7bLIggLlQ/ygQgFlofpgLCHBRuOaUo0Q
+        EsPTdDvCtNtZs7tteOTJn+AP8BdIfMBoYgiP/ijj3VJRMEEfeufeM+fce3tm
+        v//48g3AA9xnmOWqHgayvu94QettEAmnLZ2NoC7fSBHmy4RxJQOVAWOwG7zD
+        HZ+rXedFrSG8OAOdYeqyDhn0MaRXpZLxGoNemN+2kIFhIoUsQyrekxFDofJ/
+        S5S6CqEY1i6XlOYvv2aYqQThrtMQcS3kUkUOVyqIeUxDIqcaxNW27xOrL6Bx
+        oQGbYboZxL5UTqPTcqSKRai477gqDkktvSiDYYYRb094zZ78JQ95SxCRYa5Q
+        uehc6Q9kM2myW0qsuYYRE1cxSvP+9Q+MVc/v2mpCS7w083m3urm1Xi0/sTAJ
+        K0vwFMNQpbf4hoh5ncecpFqro9P7syRkkwAG1iR8XybVMmX1FYaHxweWqeW0
+        05+hGyfv9NzxQVFbZo8zhnbyIa3Z2vMhW58gpJi2U8n57OR9KtEXGbJnD8fQ
+        /2vzpWZMr1gO6oJhsCKVqLZbNRFu8ZpPyHAl8Li/zUOZ1D1w8lVbxbIlXNWR
+        kSRo/fdjMeQv3p4Zf45muUqJsOzzKBJUmptBO/TEU5kMGO+12P6rPVbIxRTZ
+        kwazc4mt5I9OGH3DhC5S5STm0dm3cATzkBINdymmu2A/7lG0TglUWV2vB3CF
+        miTiVWJrdBqLw0OfMbb48Zw+TfxEP3rK6emTzEaO7pd6vMHuGkCG9QoD42f7
+        jXXFtMpXaK+PMPEJ1w+7gI5liibRNOoyT5KV7vQFFOl8RPg07XxjB7qLmy5u
+        ubiNGUqRd3EHsztgEeZQ2EFfBCtCLoIRYSCC/RM2YumyXwQAAA==
         """,
         """
         androidx/compose/ui/Modifier$DefaultImpls.class:
-        H4sIAAAAAAAAAKVSXU8TQRQ9swW2LUVKEbCCoFKlLcqi8a1GYzAmG9tqrGli
-        9GW6HWDa3RmyO9vwi/TV+KLRxPjsjzLehRUQTX1wk71zz/04M/fj+4/PXwHc
-        w12GGlf9UMv+oePp4EBHwoml09J9uStFWHksdnnsGzc48CMbjKE44CPu+Fzt
-        Oc96A+EZGxmGCbMvFMObanMcW2O8tzbezbDe1OGeMxCmF3KpIocrpQ03UpPe
-        1qYd+37j6C0yyiLLsDrUxpfKGYwCRyojQsV9x1UmpGTpUT15hgVvX3jDNPs5
-        D3kgKJBho9o8X2njjKWTkOw1at0CCpjJYxoXGCY1tSHMosiwMq4UGyWG3A45
-        uKLHM4xvW+UkslHARSzkMI9Fhsrfcii0J5Xon151iWHqvlTSPGB4+H/zoWIv
-        YzmPMlaouf+a1lwzbX9LGN7nhpPNCkYZWjyWiEkGNkwU2h/rUCbaNkPh7MYx
-        TP8i3BoaGu2O7guGmY7h3rDFD17ynk94tkklt+OgJ8LUUmpqj/tdHsoEp8bl
-        F7EyMhCuGslIkunR6f5QO897T5bht7CCq5QId3weRYJgvqPj0BNPZHJBOaXo
-        /kGPO7AwgeSjyWMSU8igRkiQ1aKzUi/lPmF2szSXyA9Yegu7/g6zX1B+Vd/8
-        iCvfMP8+6RXqJG1YS09tWoNNAlNEWSDTLdIXj8mQxerRZRUUSWO4ncbZdG7R
-        P2Ol4Fhm4JDME7KIdIMGvE3YQpXejSOCNYq5+hoZF9dcXCeJdZfYb7i4+RNB
-        PoFzTQQAAA==
+        H4sIAAAAAAAA/6VS308TQRD+9gq9thShVUAE8QcVWqqcP3ir0Zgak4stGjFN
+        jCZme13abe92yd224S/SV+OLRhPjs3+UcQ5OQDTVxIebm/lmdnbnm+/b909f
+        AGxhi6HCVSfUsrPveDrY05FwhtJp6o7clSIsPRS7fOgbN9jzIxuMYbbPR9zx
+        ueo6T9p94RkbKYYJ0xOK4VW5Ma5bbXy2Mj7NsNrQYdfpC9MOuVSRw5XShhup
+        yd/WZnvo+1Q1qekxYQYZhpWBNr5UTn8UOFIZESruO64yIZ2WHg2UY5jzesIb
+        JMef8pAHggoZ1suN06PWTiA7cZNurdLKI4/pHKZwhmF53AA2ZhmydUpwRU9m
+        GE9W6aiylkcRZ7Mo4BxD6U9nqLQtlegcXzXPkL4rlTT3GO7/31ZowvNYzGEB
+        F4jckunJiJj9264KjYT7pjC8ww0nzApGKZIdi002NmBgg9ghCVn7MvZuMqz9
+        Gy021hnyJwXKMPWzbHNgSJV13REM0zuGe4Mm33vO2z7FMw3iansYtEWYIMWG
+        9rjf4qGM4wRcejZURgbCVSMZSYIeHMuN9nA6eySdX8ryrlIirPs8igSFuR09
+        DD3xSMYXLCYtWr+1xy1YmMAhQ1lMIo0UqhS9JtSi/0q1mP2Imep7zL2BvfEW
+        M5+x8GKj+gFLX1F4FzOK62RtWIXHNinnBgVpapYmaJP8+cM2WMbFg2tWkCGP
+        wUnq7HgV9E1bSXBoU/QykBotlKlpEYvkFVCh/23CLWzgzkEzEgjVXnqJlIvL
+        Lq64uIpVFyVcc7H2Ayw1Nq9+BAAA
         """,
         """
         androidx/compose/ui/Modifier$Element$DefaultImpls.class:
-        H4sIAAAAAAAAAKVSS2/TQBD+Ni8nqUvTlBRKS3k0tHlATSVuOaECkiU3IIpy
-        gcvG2aab2LuVvYn6szhWHBBnfhRinBpoixQiYcmz8/hmZveb+f7jy1cAL/Cc
-        4YCrQaTl4NzxdXimY+FMpHOkB/JEiqj+OhChUKb+SpzwSWDc8CyILTCGyohP
-        uRNwNXTe9kfCNxayDDlzKhTDoOEtUrUzF9Vpzg8z7Hg6GjojYfoRlyp2uFLa
-        cCM16V1tupMg6MzuJOMiigzbY20CqZzRNHSkMiJSPHBcZSJKlj69q8xQ80+F
-        P06z3/GIh4KADHsN7+aLO1c8x0mRYafZs2FjuYwl3GLIa6IjKqLCsDXvKRaq
-        DM25jF3n/zbDp/kU/x+1NvJYL6OGOwy7i42S2P3XuFa9lP8jYfiAG06+TDjN
-        0iayROQZ2DhRaJEy5zLRaD/ri7S3sMNgXyWJwUpjDEu/4PtjsnKHeiAYVjyp
-        RHcS9kX0gfcD8lQ97fOgxyOZ2Klz8/1EGRkKV01lLMn18s+S0eVuRn9vzDWY
-        7SolosOAx7Egs3ysJ5Ev3sikwUZaovdXeRwggxySj6FEIykgiwZZLvkzdNZa
-        1dIFVtrVVZKtb1hrX+DuZwpk0CRZoDSbElukr18moIiNWcEaKrhH8XaKs+h8
-        Sv9yJjUuZRbPSFZn/ep4Qsl1rGG3UML+rM0eHDq3Cb1J2K2PyLq472KbJB64
-        eIhHLh7/BG04LjBuBAAA
+        H4sIAAAAAAAA/6VSXW8SQRQ9A5QFSqVQW62t9aO0haJdm/jGk0FNNqFoWsOL
+        vgzLFAZ2Z5rdWdKf5WPjg/HZH2W8C6u2NUESH/Z+nHvu3Zkz9/uPL18BvMQL
+        hmOu+oGW/Uvb1f6FDoUdSftE9+W5FEH1jSd8oUz1tTjnkWcc/8ILLTCG1RGf
+        cNvjamC/642EayykGTJmKBRDv9ZeZGpzLqtZn19m2G3rYGCPhOkFXKrQ5kpp
+        w43UFHe06USeR6wlTYcKcsgx7Iy18aSyRxPflsqIQHHPdpQJqFu6dLECw7o7
+        FO44aX/PA+4LIjIc1Nq3r9y8hpzFQwbNereIIlYKWMYdhu15F7CwylCfq9NN
+        1SsMn+YL+3+CFrGEuwWsYZ1Eq5qhDBn2F3tIkvZfj1VuJ+KfCMP73HDCUv4k
+        TXvIYpOPDRjYOA5ol1KXMo5oRYvXdWCoLnIkC1UGK0kYln/Vj8aUZVq6LxhK
+        balEJ/J7IvjAex4hlbZ2udflgYzzBNw6jZSRvnDURIaSoFd/9oxOc7v6e2du
+        0IqOUiJoeTwMBaWFMx0Frngr4x9sJiO6f43HMVLIYKZMnt4nizRqlLUIT5Ev
+        NSr5K5QOv6HcuMLGZ4JSqJPNUkOWWg4p3phRcQ/3p6NKyGGT6o2EZ5F/Rt9K
+        KklmNo3nZB+QX0MZu9SyR34/m6dxe9P8aPq7A9jkd6gr5m59RNrBtoOHDmGP
+        HDzGEwdPfwJuilgecwQAAA==
         """,
         """
         androidx/compose/ui/Modifier$Element.class:
-        H4sIAAAAAAAAAI1QTU8CMRB9s6ssXyogKqjxRDy6QLx5Mn4km0BMNPHCqbDF
-        VHZbst0lHPldHgxnf5RxNtHEE6HJvL5586ad9uv74xPANc4IHaHDxKhw6U9M
-        PDdW+pnyhyZUUyWTzkMkY6lTD0SovYuF8COh3/yn8bucsOoSzjf1e9gl1Acz
-        k0ZK+0OZilCk4obgxAuXJ6Ac2EIzlpYqz7rMwh6huV4Vy07LyaM4ba1XfadL
-        ea1PuBxsMzRfc7HRyIbeNgd17uVUZFEaxPPIejgkVP8rBO/XSKj89V7NOKsG
-        WsvkLhLWSraVX0yWTOSjiiSh/ZzpVMXyVVk1juSt1iYVqTLaFviV2AGhgHy5
-        aDE2WGtyHKHNWMBxocQMzE9wynuP/fzbKI7gBigFKDOikkM1wB72RyCLA9RG
-        cCzqFo0fJIqRGAUCAAA=
+        H4sIAAAAAAAA/42QTU/CQBCG32mVUkAFRAUlnohHC8SbJ+NH0gRiookXTgtd
+        zEK7Jd2WcOR3eTCc/VHGaaKJJ8JhZ2efeedj5+v74xPADdqEjtBBEqtg5U3i
+        aBEb6WXKG8aBmiqZdB5DGUmdOiBCdSaWwguFfveexzM5YWoT2tvyHewTaoN5
+        nIZKe0OZikCk4pZgRUubJ6DcuLkBgebMVyp/ddkLeoTGZl0sWU0rP8Vpc7Pu
+        W13KY33C1WCXybnX5VYhC5xfLaG3S8nOg5yKLEz9aBEaByeEyn9CKP9lXM+5
+        ZsXXWib3oTBGcrD0GmfJRD6pUBJaL5lOVSTflFHjUN5pHaciVbE2Bf4l9ngr
+        hXw5sNFiW2dmMWkUXJyyd8b0nLmFJi747rGeV47iCLYP10fJR5kHgIsDH4c4
+        GoEMqqiNYBnUDY5/AJ5HRJ4KAgAA
         """,
         """
         androidx/compose/ui/Modifier.class:
-        H4sIAAAAAAAAAIVSS2/TQBD+ZuPESRogoTzSB6XQUBJeLhVcKFSqQhFGbUAU
-        9dLTNtmUbZ115d1EPeZX8D+AGwcUceRHIcZVoRSkYMvzzXwzOzOe2e8/vnwF
-        8Aj3CbPSdJJYd46Cdtw7jK0K+jrYjDu6q1XigwjlfTmQQSTNXvB6d1+1nY8M
-        wXPvlSGs1jfGJVhpjHcTFjbiZC/YV243kdrYQBoTO+l0zHordq1+FHFU/mk7
-        0ka7VUKm3tgmLI5LW2syJw3n8FEkFGu1sLX1bq3VXCeM7/f05EoJJZwrYALn
-        CYXfdAnllBWoECobB7HjtoJN5WRHOsmNit4gw6OlVGQJdMDUkU6tJdY6DwmP
-        R8NSUVRFUZRHw6LIe/ludTSc95bFEj0RXvZVpSymxdJouJwrZ46Vl98+eOnh
-        ZcLc/8YJQjbm1SQEfz1SPWUcoTb2l0/CfNwgNMZGPldd2Y9c2DuMrI8FQulP
-        hjDxK/LBAVededs3TvdUaAba6t1IrZ2ulnv62/tGJrKnnErOhHnNuKO4UGiM
-        SpqRtFYxW9yK+0lbvdAR+6ZOMm3/UyXHU4OXrgNT6d4Yb7OVY/QZBU81y5Y4
-        w9b58+nEyPNbYL3B+iRj+vifcOEzLn48NjK4w3Ka8Sbnmc+lF0ZwrSnUGG8x
-        3k0rYRH3GJ9xikmueWkHmRCXQ1xhiaupqIYcO70DspjB7A5yFtcs5iyyFtct
-        yhbzPwFNAZX3twMAAA==
+        H4sIAAAAAAAA/4VRTW/TQBB94zhxkgZwKB/9orQ0lIaPulRwoVCpCkUYpQFR
+        1EtOm2RbtnXWlXcT9Zhfwf8AbhxQxJEfhRhHhVKQgi3vm3m7+9545vuPL18B
+        PMIqYU7oThKrzknQjrvHsZFBTwU7cUftK5l4IIJ/KPoiiIQ+CF63DmXbesgQ
+        XPteasLmSn2cwEZ1/DZhqR4nB8GhtK1EKG0CoXVshVUxx43YNnpRxKfyT9uR
+        0spuEjIr1T3C8jjZSo05oVnDQ5FQrFTCxu67rUZtmzC+3rObGyWUcKGACVwk
+        FH7TJfgp66BMKNePYstlBTvSio6wggt1uv0Mt5bSpZAuINAR8ycqzdY46jwk
+        PB4OSkVnyik6/nBQdPJufn9qOFhw1501euK42Vdl35lx1oaD9ZyfGQUvv31w
+        08vrhPn/9ZQ9szHPJyF425HsSm0J1bH//Vzui15kw+5xZDzcIpT+ZAiVsbdP
+        TTzcJkz8YleP2HX2bU9b1ZWh7iujWpHcOpsvq/69+0YkoiutTM4dc2txR3JJ
+        odYyqUXCGMlscTfuJW35QkW8N32qtPePS467Bnc0iOl0eIwrnOUYPUaHu5rl
+        zDnHVvnz6DTJ81vg+C7Hk4zp433Cpc+4/HGUZHCP1xnGCdbx2WeJscK4zLiY
+        K+B+6oQ7eMD4jCUm2fNKE5kQV0NcC3EdUxxiOmSV2SbIYA43msgZzBvcNMga
+        LBj4Bos/AU5gqBi8AwAA
         """
     )
 
     val PaddingValues: TestFile = bytecodeStub(
         filename = "Padding.kt",
         filepath = "androidx/compose/foundation/layout",
-        checksum = 0xeedd3f96,
+        checksum = 0x393214e7,
         """
 
             package androidx.compose.foundation.layout
@@ -426,18 +425,18 @@
         """,
         """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGI2BijgUueSTMxLKcrPTKnQS87PLcgvTtXL
-        TSxJLcpMzBHiCk5OTEvLz0nxLuHi5WJOy88XYgtJLS7xLlFi0GIAACJwI+tQ
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUueSTMxLKcrPTKnQS87PLcgvTtXL
+        TSxJLcpMzBHiCk5OTEvLz0nxLuHi5WJOy88XYgtJLS7xLlFi0GIAADDzNLNQ
         AAAA
         """,
         """
         androidx/compose/foundation/layout/PaddingValues.class:
-        H4sIAAAAAAAAAJVOTUvDQBB9s9Gkxq9ULdQ/YdrizZMXIVBRFHrJaZtsyzbp
-        rnQ3pd76uzxIz/4ocVL9A87Amzfz4L35+v74BHCLHmEgTbmyutykhV2+WafS
-        mW1MKb22Jq3lu218+izLUpv5RNaNchGIkCzkWrJs5unTdKEKHyEgdMeV9bU2
-        6aPyki3kHUEs1wFnUQthCyBQxfeNbrcBs3JI6O22nVj0RSwSZrP+bjsSA2rF
-        EWE0/u+THMw58d/tpvK8vNpmVagHXSvC9UtjvF6qiXZ6Wqt7Y6zfu7mQM3GA
-        3xK43OMFrngO2fKQO8wRZIgydDIcIWaK4wwnOM1BDmc4zyEcEofuD692uKBp
+        H4sIAAAAAAAA/5VOTU/CQBB9syiF+lVUEvwTFog3T15MmmA0mnDpaWkXsrTd
+        NeyWwI3f5cFw9kcZp+gfcCZ582Ze8t58fX98ArhDnzCUJl9ZnW/izFbv1ql4
+        bmuTS6+tiUu5tbWPX2Sea7OYyrJWLgARoqVcS5bNIn6eLVXmA7QIvUlhfalN
+        /KS8ZAt5TxDVusVZ1EC3ARCo4PtGN9uQWT4i9Pe7TigGIhQRs/lgvxuLITXi
+        mDCe/PdJDuac8O92W3he3my9ytSjLhXh5rU2Xldqqp2elerBGOsPbq7NmTjC
+        bwlcHfAS1zxHbHnM3U7RShAk6CToImSKkwSnOEtBDue4SCEcIofeD+cWtEFp
         AQAA
         """
     )
@@ -445,7 +444,7 @@
     val Remember: TestFile = bytecodeStub(
         filename = "Remember.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0x736631c7,
+        checksum = 0x715f1bc1,
         source = """
         package androidx.compose.runtime
 
@@ -482,44 +481,44 @@
         ): V = calculation()
         """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuOSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeIKSs1NzU1KLfIu4eLjYilJLS4RYgsBkt4lSgxaDAC9VMzjUAAA
-                AA==
-                """,
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuOSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFeIKSs1NzU1KLfIu4RLl4gZK66VWJOYW5KQKsYWkFpd4lygxaDEA
+        ALrkMh5XAAAA
+        """,
         """
-                androidx/compose/runtime/RememberKt.class:
-                H4sIAAAAAAAA/61WWXPbVBT+rrzJjhfFWUgcCCFL62yV44YCdeoSAqEe3MDU
-                HsNMnmRbTeVF6kiyKW8ZXvgNvPILeCw8MJnwxo9iOFeWHW9JXdIHXZ17dO53
-                vnO/u+iff//8C8A+vmRYU/SqaWjVV3LFaL40LFU2W7qtNVX5mdpUm2XV/MYO
-                gDFINaWtyA1FP5O/LdfUCnk9DKLpRjHsJ/N1w25oulxrN+XnLb1ia4Zuyceu
-                lcps5ocxMgyHB8WHo/7sm8AOtovFTDazSS3DRv7aKo6cvlJuqBS3ljfMM7mm
-                2mVT0QhN0XXDVjrIJ4Z90mo0KGqqojQqrYbjFxFiWO6joum2aupKQ87ptkkY
-                WsUKIMwwV3mhVuouyHeKqTRVm8/K3eRocX2eAgc5y2yWwogiFkIE0mC+MaUH
-                EGfwa3rbqKsMs8kx0xrGLOamMIN5hsi6tv58/UonlmNYeZNUDMfjiP8fgQvX
-                Cfy28AOSr98kJUngKu6tqz/tMcTHEfvhZmluU7M6ec23mgVeXpqhNhnwu6nt
-                x9vUdutq7zN8nTx9R6UUD0pjS3l7fOJZcniWMs7efNmyLRFJhpkxWAzTXbin
-                qq1UFVshn9Bse+hUZrwReQPaq3VuCPTxlcatFFnVPcZeXJwnQoLoCQkLAr3p
-                kS7OyQiQMR2ijxvUTwhP2KpXvDiXWDosCQkx7o2TK+V5cvmL+PdrdnF++Ztf
-                kLyJvaFgUfIlvAss5U9HRe/1AwOJzLUDRUmcBCKY+GoCCFEKTQI2lXjcAQt3
-                wMLpeSmSCMdFkcWd4ano6ihMeBgmdvmzEAj5xMtf0ynG55s2GCvyM8TVrP+U
-                5BqV6MroXpb36jat0yOjSidzLK/p6kmLu4v8OOIQBt0tJcXUeN91Bgvama7Y
-                LZPspWedayuntzVLo8+HV8canXnDX3v3zEBYqGC0zIp6rHH0RXdMaQQPexDg
-                5esMPizS46feAfWOyC/QO7YVn3qNac/B1h94j+F3vhLxiFo/VS0igCzZ8+Tj
-                9gJBMD4IISTo/diJDuDzXjxwSE+AJgxBMnjGJTfjUwrlyzu23cn4aHtsxoiT
-                cYVCuxkdmljGh04ZndzMzf3+SO6IQJ0PnI3VZbDiMvjenYvYTodBdmcsg1mH
-                wRaFdhl4hhisknU1D4LL5aMRLjOeHpdBRmsuozIN89Fb2u0weuDdHUMpSGVm
-                nX85H9kdSrwOqUdJ6lGSsEGW4FicnMcltz5CbtE7RG6Q4h2XYsGVbW4rvkkU
-                bxIvSiy64kX7xJtDkqYTjtUv3t3x4gV7PAR84bQZWq7AKXm3idnOKTw57OZw
-                LwcZqRyt8XQO97FPARY+xoNTSBZ8Fj6xELLwqQW/hWULn1lYsrBqYcXChoU1
-                Cw8tJB3/nf8A7cabHS4LAAA=
+        androidx/compose/runtime/RememberKt.class:
+        H4sIAAAAAAAA/61WS3PbVBT+rvySHT8U50HiQAh5tM6rctxQoHZdQiDUgxuY
+        2mOYyUq21VR+SB1JNmWXYcNvYMsvYFlYMJmw40cxnCvLjmM7qUu60NW5R+d+
+        5zv3uw/98++ffwHYx5cMa4peMw2t9kquGq2XhqXKZlu3tZYqP1Nbaquimt/Y
+        ATAGqa50FLmp6Kfyt5W6WiWvh0E03SiG/WShYdhNTZfrnZb8vK1Xbc3QLfnI
+        tVKZzcIwRobhIFt6OOrPvQksu10qZXKZTWoZNgrXVnHo9JVKU6W4tYJhnsp1
+        1a6YikZoiq4bttJFPjbs43azSVFTVaVZbTcdv4gQw/IAFU23VVNXmnJet03C
+        0KpWAGGGueoLtdpwQb5TTKWl2nxW7iZHixvwFDnIaWazHEYUsRAikK7mG1N6
+        AHEGv6Z3jIbKMJscM61hzGJuCjOYZ4isa+vP1y91YnmGlTdJxXA0jvj/Ebh4
+        ncBvC39F8vWbpCQJXMW9DfWnPYb4OGI/3CzNbWpWJ6/5VrPAy0sz1CcDfje1
+        /Xib2m5d7X2Gr5Mn76iUUrY8tpS3xyeeZYdnOePszZdt2xKRZJgZg8Uw3YN7
+        qtpKTbEV8gmtjodOZcabIG9Ae7XBDYE+vtK4lSKrtsfYi/OzREgQPSFhQaA3
+        PdL5GRkBMqZD9HGD+gnhCVv1iudnEkuHJSEhxr1xcqU8Ty5+Ef9+zc7PLn7z
+        C5I3sTcULEq+hHeBpfzpqOi9fmAgkbl2oCiJk0AEE19NACFKoUnAphKPu2Dh
+        Llg4PS9FEuG4KLK4MzwVXR2FCQ/DxC5+FgIhn3jxazrF+HzTBmMlfoa4mg2e
+        klyjMl0ZvcvyXsOmdXpo1OhkjhU0XT1uc3eJH0ccwqC7payYGu+7zmBRO9UV
+        u22SvfSse23l9Y5mafT54PJYozNv+Gv/nrkSFioabbOqHmkcfdEdUx7Bwx4E
+        ePk6gw+L9Pipl6XeIfkFese24lOvMe3Jbv2B9xh+5ysRj6j1U9UiAsiRPU8+
+        bi8QBOODEEKC3o+d6AA+78cDB/QEaMIQJINnXHIzPqVQvrxj292Mj7bHZow4
+        GVcotJfRoYllfOiU0c3N3Nzvj+SOCNT5wNlYPQYrLoPv3bmI7XQZ5HbGMph1
+        GGxRaI+BZ4jBKlmX8yC4XD4a4TLj6XO5ymjNZVShYT56S7tdRg+8u2MoBanM
+        nPMv5yO7S4nXIfUpSX1KEjbIEhyLk/O45NZHyC16h8hdpXjHpVh0ZZvbim8S
+        xZvEixKLnnjRAfHmkKTphGMNind3vHjBPg8BXzhthpYrcELebWK2cwJPHrt5
+        3MtDRipPazydx33sU4CFj/HgBJIFn4VPLIQsfGrBb2HZwmcWliysWlixsGFh
+        zcJDC0nHf+c//GYG8S4LAAA=
         """
     )
 
     val StateFactoryMarker: TestFile = bytecodeStub(
         filename = "StateFactoryMarker.kt",
         filepath = "androidx/compose/runtime/snapshots",
-        checksum = 0x79ef0e9d,
+        checksum = 0x2ecf44e1,
         source = """
         package androidx.compose.runtime.snapshots
 
@@ -529,31 +528,31 @@
         annotation class StateFactoryMarker
         """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMueSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeIKSs1NzU1KLfIuEeIPzkssKM7ILwkuSSxJ9S7hUuOSwaVRLy0/
-                X4gtJLW4xLtEiUGLAQDM+x9weQAAAA==
-                """,
-                """
-                androidx/compose/runtime/snapshots/StateFactoryMarker.class:
-                H4sIAAAAAAAA/51STW/TQBB965AmBCgpUEhaSj8o6Q2XCsSBU9I2wlI+UJIi
-                oZy29qq4dryRdx2aW278Jw4o4siPQsw2IgnCAglZGr+ZefPxdvf7jy9fAbzE
-                AcMrHnmx9L0r25WDoVTCjpNI+wNhq4gP1Uepld3VXIs6d7WMx00eByLOgTEU
-                L/mI2yGPLuz2+aVwdQ4Zhu1FlEeRpFJfRnZ1DnPIMuw3AqlDP1qmNBOla+JE
-                uslARFp4bxg2Umg9Hl8ITclVHobyk/BmAZXedDF3Xpevn7WOe067xbCVUtER
-                msYTImp2xMNEMBz8tfNyxUrNaVU7Hxh2G6nn8Ju8nXTOcr/KPyjvZOi7Y7Pq
-                caPa7RpJqQVz9Xvp+dNQmLV646EwKpqnvbftE4a1X8KbQnOPa05JazDK0Oth
-                xuSNAQMLKH7lG++QkPeCoTyd5AtWySpYxc38t89WaTo5sg5ZbToxhCOG143/
-                enq0AQ1c/zPxPNAMha5MYlfU/ZCurdyZ9XvvK/88FIsbUxXaATeoz4rZn/Cz
-                a7uPCv0D5OgjcZS/2QcTKOAWbpN3R2AVd1Gk5NrMvYf7eGDgNW8dD/EIWZT6
-                yDgoO9hwsInHBLHl4Am2iaWwg90+LIU9hac/AcQycP6LAwAA
-                """
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuOSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFRL0LS1JTMpJ9cwrCS5JLEn1LhHiD85LLCjOyIcJcOlwKeHSr5eT
+        mVeiV5JaXCLEFgIkvUuUGLQYAH5U0JeGAAAA
+        """,
+        """
+        androidx/compose/runtime/snapshots/StateFactoryMarker.class:
+        H4sIAAAAAAAA/51Sy27TQBQ945AmDVBSoJC0lD4o6Q6XCsSCVdI2wlIeKAlI
+        KKupPSquHU/kGYdmlx3/xAJFLPkoxJ1GJEFYICFL1+fec+5rZr7/+PIVwAsc
+        MrzkkRdL37uyXTkYSiXsOIm0PxC2ivhQfZRa2V3NtahzV8t43ORxIOIcGEPx
+        ko+4HfLowm6fXwpX55Bh2FlEeRRJSvVlZFfnMIcsw0EjkDr0o2VJM1G6Jk6l
+        mwxEpIX3mmEzRdbj8YXQRK7xMJSfhDcLqPSii77zvHz9Xeuk57RbDNspGR2h
+        qT0hkmZHPEwEw+FfKy9nrNScVrXzgWGvkXoOv623m65Zrlf5h+StDH13bEY9
+        aVS7XbNSasJ8+/10/iwUZqzeeCjMFs2z3pv2KcP6r8WbQnOPa06kNRhl6PUw
+        Y1aNAQMLKH7lG++IkPecoTyd5AtWySpYxa38t89WaTo5to5YbToxgmOGV43/
+        eno0ATXc+JN4FmiGQlcmsSvqfkjXVu7M6r33lX8eisWNqQrNgBtUZ8XMT/jp
+        tT1Ahf4BcvQBeeJX+2ACBdzELfJuC6zhDopErs/cu7iH+wZe6zbwAA+RRamP
+        jIOyg00HW3hEENsOHmOHVAq72OvDUthXePITiiesbIsDAAA=
+        """
     )
 
     val SnapshotState: TestFile = bytecodeStub(
         filename = "SnapshotState.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0xa797b7e1,
+        checksum = 0xe6e3c192,
         source = """
         package androidx.compose.runtime
 
@@ -672,348 +671,347 @@
             override fun toString() = "NeverEqualPolicy"
         }
         """,
-
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMueSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeIKSs1NzU1KLfIuEeIPzkssKM7ILwkuSSxJ9S7hUuOSwaVRLy0/
-                X4gtJLW4xLtEiUGLAQDM+x9weQAAAA==
-                """,
-                """
-                androidx/compose/runtime/DerivedState.class:
-                H4sIAAAAAAAA/4VRTW/TQBB9Yzuxk4bghhbSAG1BQiQccKk4IFJVQnyISKmQ
-                mihCymkbL2Ebx668m6jH/BYO/AgOyOqRH4UYp6hCRIXLzLzZN29Hb378/PYd
-                wHM8IDwScZgmKjwPRsn0LNEySGexUVMZvJGpmsuwZ4SRLohwdNB/2T0VcxFE
-                Ih4HH05O5ci0D1db3Ws1l2IH/X77sE3w/x504RC2/z3sokjwxtIMRDSThI1m
-                a3UBQqHZ4l+Yqa+Ym81VYmtAKDaZmRfr3UliIhUHR9KIUBjB89Z0brNVlAcv
-                DyDQhPvnKkd7XIXPCG+zRbVs1a1ytlgmyyt4n+rZ4onjZQuf9r2aU7Pe0551
-                XPfthvUiW3y8+Fq9+FKsNBzP8QsPHa/ou7nYPuHx9f79eRPejvqE3f+4nZsx
-                v3TA78XiTH9OzPLh6cQQSj01joWZpfxc7iWzdCTfqYjB1vGlyEBpdRLJV3Gc
-                8JBKYs3+WyiwDy4bYPHFPJQYbecIZcZrqFzhG7B/VzZ2lvk+djm/ZkaVVW4O
-                YXfgd7DeQQ23uMRGB5u4PQRp3EF9yCfElkZD467GPZ3DksaaRuUXZ2oGC8cC
-                AAA=
-                """,
-                """
-                androidx/compose/runtime/DerivedStateImpl.class:
-                H4sIAAAAAAAA/41S204TURRd58x0OoylDOWOeEORtgiDxAcDTY2XEJtUTWjT
-                GHk6tBM40M6QOacNj/0KP8Av0ERj4oNpePSjjHvahqg1sS97r71mn732ZX78
-                /PYdwCNsMeRE0IhC2bjw6mHrPFS+F7UDLVu+98KPZMdvVLTQfql13kyCMVQL
-                1d3yqegIrymCY+/N0alf13vFUao8Vt1CtbpX3GNw/36fhMmwNlaNJCwGqyAD
-                qYsMc9nRXnI1SsiSVAyMbK6Wgo1rDhJIMSQ6otn2GTKj71JIY2oCHC6DqU+k
-                YtgYb654XzSWfezr2qD8bDY3KkDq2Rz1RZnqKjNZILz5hGYx+p+my2ehbsrA
-                e+Vr0RBaEMdbHYMuyGJjxwYM7Iz4CxlH24QaDxne9bpphy9yp9ftO25bNl/s
-                dfOm3eu6bMfOmBn+km3zZ5MZyzWW+eNe9/KDxV3zYGUYvr18nybKdbhrL5t2
-                wrVWTTvpmrHCDolWGdbH20l85kogztVJqPvE1plmmKjI40DodkSTm8/DBrmp
-                sgz81+3WkR9VxVGzf5uwLpo1Eck4HpJOJWxHdX9fxsHSwUCxJpWkr0+DICQJ
-                GQYK23TABO2H/l9CdFHyWVoSxxIMwjbiE+eIKZLn5J38V0zmN75g+lM/L0/W
-                okzQ2w2y84MsZDATr57Q71UdQrOYG9b04suQT+Q/Y/rjP8ulBgnDcoMi88Qt
-                XDW2O2zM+m9T1lVTFhb/aMoYIgMP+n4dm+T3KWOZtK8fwihhpYQbJdzELYK4
-                XcIdrB6CKdzFvUNMKMworCncV0irOJxVmFNYUJj6BY25tQRSBAAA
-                """,
-                """
-                androidx/compose/runtime/MutableState.class:
-                H4sIAAAAAAAA/4VR0WoTURA9c3eT3aQxbmOradRaBTHxwa3FBzGlIKIYSBCa
-                EIQ83SZrvM1mt+TeDX3cb/HBj/BBlj76UeJsKkUM1Zc7c+aeOTOc+fHz23cA
-                L/CQ8FhGk0WsJuf+OJ6fxTrwF0lk1Dzwe4mRJ2HQN9IEDojQOxy86p7KpfRD
-                GU39Dyenwdi0j9ZL3Ws1V2KHg0H7qE3w/m50YBN2/93soEhwp4EZyjAJCFvN
-                1voChEKzxVOYqa+Y2811YmtIKDaZmSeb3VlsQhX5vcDIiTSS+8V8abFVlD9u
-                /oBAM66fqxztczZ5TnibpdWyqItylq6CcAvup3qWPrXdLPXowK3ZNfGe9sVx
-                3bMa4mWWfrz4Wr34Uqw0bNf2Co9st+g5udgB4cn1/v15E96OBoS9/7idm7G8
-                dMDrR/JMf47N6uPZzBBKfTWNpEkW/F3ux8liHLxTIYOd40uRodKKJ76Oopib
-                VBxp9l+gwD44bIDgi7koMdrNEcqMN1C5wjdg/c4sPFjF+9jj+IYZVVa5OYLV
-                gdfBZgc13OIUWx1s4/YIpHEH9RGfEDsaDY27Gvd0DksaGxqVX4ySaL/HAgAA
-                """,
-                """
-                androidx/compose/runtime/MutableStateImpl.class:
-                H4sIAAAAAAAA/41S224SURRdZ2YYpiOFKb3XeqvWArWd2vhgWoJRk0YSqkkh
-                xNinU5jQU2Cm4RyaPvIVfoBfoInGxAdD+uhHGfcB0jRiIi97rb1mn32dX79/
-                /ATwDNsMWR7WO5GoX/q1qH0eycDvdEMl2oF/2FX8pBWUFVdBsX3eioMxVPKV
-                vdIZv+B+i4cN/93JWVBT+4VxqTRR3nylsl/YZ/D+fh+HxbA+UY44bAY7L0Kh
-                CgzzmfFeslUKyFApTcxMtpqAg1suYkgwxC54qxswpMffJZBEagoGPAZLnQrJ
-                sDnZXHpfNJbTCFR1mH4ukx0vQNUzWeqLIuV1ZDxPfOsFzWIOPs2UmpFqidA/
-                DBSvc8VJM9oXJl2QaeNoAwbWJP1SaG+HWP0pw4d+L+kaS4bb7w3AcGzHWOr3
-                cpbT73ls10lbaeMN2zFeTadtz1wxnvd7V59sw7OOVkfu+6uPSZI81/CcFcuJ
-                efaa5cQ9S1fYpaIVho3JdqLPXA75uTyN1EDYbiqGqbJohFx1OzS59TqqE6RK
-                IgzedtsnQaeiX+vbRDXeqvKO0P5IdMtRt1MLDoR2lo+GFatCCvr6MgwjKiGi
-                UGKHDhij/dD/S4wuSpihJRlYhkncgT5xlpQCoUHo5r5jOrf5DTNfBnE5sjZF
-                AkvYJLswjEIas3r1xG5mdYnNYX6U09eXIYzlvmLm8z/TJYYBo3TDJAukLV43
-                tjdqzP5vU/Z1UzbpN5syR8zEkwFuYIvwgCJWqPbtY5hFrBZxp4i7uEcU94t4
-                gLVjMImHeHSMKYlZiXWJxxJJqd05iXmJRYnUH5JR7zxSBAAA
-                """,
-                """
-                androidx/compose/runtime/NeverEqualPolicy.class:
-                H4sIAAAAAAAA/5VU3W8bRRD/7Z0/zhcndZyQpmn4KA3UTpqeE8pnTNoSinqR
-                ayJcBUGe1vbibnK+c+/2rCJeIv4Unnmg4qEIJBTBW/8oxOydCcFJUSLLO7Mz
-                s7/5zc7svfjr198B3MZdhir3u2Egu0+dTtAfBJFwwthXsi+cphiK8P6TmHs7
-                gSc73+bBGL5s7PMhdzzu95zP2/uiozYaL0Vo+XwQPQ7Uw1hxJQM/xamfhtjc
-                YCiNW/PIMDgXBM8jx5CrS1+qTQazUt0twkLBRhY2Q0Y9lhHDysspjxdNxGzx
-                JJZD7glfMdyonHEBpyzVrxmWGkHYc/aFaodc+hEV4gcp08hpxp7H254gdMYZ
-                yqcRyNFmsFTQUqH0ewyzleqJqNRKUdf/L0ugdCJ9t+NlWbjMkO2LsCcYts9V
-                0xlVnkW7fsGGLX0qvuGxp9z+wIvyuMrwXeWiE3UutufiX8QVvGpjEa/R5Q9C
-                MZRBTAOT78RhmPQ/zwcDT4ouuesdLxkzG4aeLcttth7da27dL+ItTBbI+DbD
-                dOMgUBTmPBSKd7nidENGf2jS62N6sfQCavYB2Z9KvauR1l1jEEeHi7Yxb6T/
-                0tGhbVhamSBpkpyy/vzemD86XLfLuXJmntWMGvskbxl//JAzSub2YimzYNSy
-                61Ypt5B4Scun2oO5batkkbfwYE4nW2dYu/CVM027eLJ5NGb/xLYoVNw6oPu6
-                +kUK4/pDGUka+Xv/Dii9x62gSwN4qSF90Yz7bRE+0s9Cv4igw71dHkq9HxmX
-                xrF2eMj7QonwP6BF1/dFuOXxKBK0LbRkz+cqDgnBbgVx2BGfSQ13ZQS3e4oY
-                atS9LNVHnzwaCGonyfepNzmScySz5KevCu0+oJ2jG6ity88x8YwUAx+OgoEQ
-                H9FaTANITib9nsIlitKH79JOt90wfxw7GSUn30i9o5Nam0Y58RuYIc3ABumT
-                BplKCXS6zuKVUYLVETuzPP/TWAZ1gps5ynCyTF38Ank0zA4y9KOJXV65ufoL
-                Xh/HSutcTmOO2VrEP2Vr4VrCVmtvkmYeZ9KEdQ0z5lgNpST4+vE9X06OAxO/
-                wfjqOZZ+xo1niSGDOq02hS1Sy94l1h8n7ExsJvI93CHpkr9CPajuwXSx7GLF
-                xU2skopbLjWxtgcWYQ3re7AjTEZ4J8LtCIUIU4kyHWEmwizpfwOnXXg5QAcA
-                AA==
-                """,
-                """
-                androidx/compose/runtime/ProduceStateScope.class:
-                H4sIAAAAAAAA/41T328SQRCeXSgcSPWKv4BWq7ZGJcY7iU9CiEbTFENrI+gL
-                T8tx4MKxS273sI/EP8UH/wbjgyH45h9lnINeG4u1fbid2ZlvvtnZ/e7X7+8/
-                AOAZbBMoMtHxJe8cWo4cjqRyLT8Qmg9d68CXncBxG5ppt+HIkZsEQqBZaT6v
-                99mYWR4TPettu+86ulxdDtXPJN4LNGt7C+JKs1mulgmYp+uTECdw/0IcSUgQ
-                yLBPjOvXXIUwPObD+kBqjwurPx5a3UA4mkuhrJ0jzy5HeUf6MtBcuMp6JZFc
-                BCwElB8tj0Sgex5tJcq/Fxyv5bwulWL1342269LvWX1Xt33GsQETQmq2aLYf
-                eF44PMK2/geTOkQiai06xZ6rWYdphjE6HMdQAyRcjHABAmSA8UMe7mz0Ok9x
-                4OlkI01zND2dHBuTRDtqhhGjm5tOinFjOjFJycjGs3SX2PTNphkrUDteypgr
-                hXnUTtqJ3dnXFz+/kelk9iVBTWP2mcbT1MiH3UoEHp8tmiU14gykSeDBxXSG
-                aBwwJcWxQrLRpZxIAmXYEGykPko9L3oy0FjT4D3BdOBjzfq7BXVNjLniyP3y
-                5L7xzU5nD5jPhq52/b9g6YYMfMfd4R4y5o9qPizxoaYprOChk+Hb4M9gQApi
-                sIk7Cmm4gzaB2Uto7+K3SnGTmT9juEbAGNyb29uwhXYHs6tIerkFsRpcqYFZ
-                gzXIogtXa3ANrreAKLgBN1uQUpBTkFdQUGAoWFewoeDW3En9Ae+dQkpABAAA
-                """,
-                """
-                androidx/compose/runtime/ReferentialEqualityPolicy.class:
-                H4sIAAAAAAAA/5VUW08bRxT+ZteX9WITYygBQq8hiblljUuvuDSUpoqRIShG
-                RC1PY3viDKx3nb1YifqC+lP60L70oVEfUrVShdq3/qiqZ3Zd6hqoQJbnnDnn
-                zHe+M+fM/vnXL78BWMUGQ5k7Lc+VredW0+10XV9YXugEsiOsR+KJ8ATp3L7/
-                LOS2DF7surZsvkiDMTyuHfIet2zutK2HjUPRDNZqF0LVHd71n7rBdhjwQLpO
-                jFM5C7G+xpAftqaRYLCuCJ5GiiFVkY4M1hn04vx+FgYyJpIwGRLBU+kzrF5M
-                +cLqiaEpnoWyx21yM9wpnnMTZyzzXzHM1VyvbR2KoOFx6fhUkePGlH1rJ7Rt
-                3rAFoTPOUDiLQI4GgxG49cCTTpthojg/EBVbKerm/2VxA5WIoqYvrM/AdYZk
-                R3htwbB1qeLOKfc8/pUrtnDuc/GEh3ZQ7XRtP40bDF8Xrzpjl2J7Kf5ZTON1
-                E7N4g7rQ9URPuiGNULoZel40CGne7dpStMhdadrR4JnQ1LQZ1Z363sbO5v0s
-                biGXIeNthrHakRtQmLUtAt7iAacb0jo9nR4mU4uhFlDXj8j+XKpdibTWCoM4
-                OZ41tSkt/udPjk3NUMoISZ3kqPHHN9rUyXHZLKQKiSlW0krss7Sh/f5tSsvr
-                W7P5xIxWSpaNfGom8pKWjrUHk1tG3iBv5sGkSlZmWLnylTNFOzvYPHrU/8TW
-                KVTcPaL7uvEohqk6PelLmv2NfyeVXuim26IBvFaTjtgJOw3h7an3oZ6G2+T2
-                Pvek2veNOYJtHm3zbn8/N4y9yz3eEYHw/pMkW3Uc4W3a3PcFbTN12XZ4EHqE
-                YNbd0GuKL6SCm+7D7Z8hihJ1M0n10keRBoTaS/ID6lWK5CTJJPnpu0O7D2ln
-                qYYq68IrjLwkRcNH/WCA42Nas3EAyVzU/1Fcoyh1eI+kGoORxaXvkE58j4T+
-                A211rMV5MvfYAFojQnsrPtFHU9oYCpF/BOOkaaiQntPIlI/SxesEXusnXe4z
-                1gtTPw7xbQ7w1fsZBktXFzJDHgWziwT9aKoXFpeWf8abw1hx7QtxzClbg/jH
-                bA28HbFV2juk6aeZFGFVw7g+VEM+Cr55evfXo+NU+K/QvnyFuZ9w52VkSOAT
-                Wk0Km6U2vkes1yN2Oj6N5Pu4R7JK/iJd8/wB9CoWqlisYgnLpOJulRpbOgDz
-                sYLyAUwfOR/v+lj1kfExGiljPsZ9TJD+NyU9ROd/BwAA
-                """,
-                """
-                androidx/compose/runtime/SnapshotMutationPolicy$DefaultImpls.class:
-                H4sIAAAAAAAA/5VSTW/TQBB96yR1GlL6wWcotEADohwwlTiRqBIqQjJKS0Wi
-                Hspp4yzpJvautV5HRfwpzhz4AfwoxKyTCmgQIpY9++bNm5n17H7/8fUbgBd4
-                zNDmamC0HJwHkU5SnYnA5MrKRARdxdPsTNvD3HIrtTrWsYw+NV+LjzyPbZik
-                ceaDMayN+IQHMVfD4F1/JCLro8RQSYQZCobPTzoLdmh1Lhf8L2Z3nmI4bfde
-                zvP7C++p3eu19ltkpu8ufQzNjjbDYCRs33CpsoArpadJWXCUxzHvx4JkO/+S
-                aeuUpKo07ZnMGPYWHhdDNTViInVO6Rt/m4If5cYIZQnxNI2lGDCsd8baxlIF
-                h8LyAbecdF4yKdG9YM5UnQEDGztAB+qdS4eeMwQL7tBHg6H++72hS3Mh7ZJS
-                PBvT3soHekAXZrUjlTjKk74wPTdB90864vEJN9L5M3K5K4eK29wQ3nw/7R+q
-                icwkhV/9GjEd0+XoMTc8EVaYP2T1UClhDmKeZYLcWlfnJhJvpGvWmJU4mSuP
-                PXgoYzqrZVSwRN498t6S73iPfXEWW2SXiANOsU326TSKGq4U2R7qWCniHq4S
-                8gq0SqiE+wX28WBWo0rrQ/pWykXTi6eEHbI14jzcwSYaaBaJd/GI1i3i10iz
-                /gGlEBshroW4jhshbuJWiNs/Ac089AgUBAAA
-                """,
-                """
-                androidx/compose/runtime/SnapshotMutationPolicy.class:
-                H4sIAAAAAAAA/5VTzW7TQBD+1kltx2mLC6WkKeU3NCkHnFYcEK2QEAjhKgXU
-                RBzoaZNswybOOnjtqHDKs/AYHFDEkYdCjJ1WINIDlbzz/83szox//vr2HcBj
-                bDN4XHWjUHZPvU44HIVaeFGiYjkUXlPxkf4YxodJzGMZqndhIDufLTCG2n7r
-                aaPPx9wLuOp5b9t90Yn3ns2bGNx/bRbyDI74lMgxD4SKGaq1eeC8ZfsDQ6HW
-                au3Rl8oLQxH1BMPBf6EvyHfRbZfPCqQ16DBUGmHU8/oibkdcKk3dUuGsHdp7
-                kwQBbweCwlYagzAOpPIORcy7POZkM4bjHHWZpcROCRjYgOynMtXqJHV3GL5M
-                J6uOUTKc6cQxXCIZLzqGbdsnpenkYd6eTly2a9SNg003Vzbq+V3TXSgbT6YT
-                EsxMeL3146tpuNZB1bXL+RKb+QrnQc65UJxFr2XRi+kNdhl2GpfcAXoca7Hs
-                PZxOm8EeRWIsw0QzWJ0kirK5Wnw0CqToMuxfskDlpTjhSRD7w1GgLdxhWPzb
-                Qlt1jmsSTDwaULVCU/YUj5OIdmLjaJbeV2OpJY3o+Z+xUS5fKRG9CLjWglSn
-                GSZRR7ySASHXz5Dv53AmdQsL6Rhh0AaboD8BlVSDTXoBDkkzvYgHxE3yLxLP
-                Y4uoQ9pd8t3D+llUDtWM30eN+BH5lyj/8jFyPq74cH2s4CqJuOZjFdePwTTW
-                cOMYSxoljXWNsoaZ0Q2NmxqWRkFjU+OWxm0N5zfYvY915wMAAA==
-                """,
-                """
-                androidx/compose/runtime/SnapshotStateKt$produceState$1.class:
-                H4sIAAAAAAAA/41T0U4TURA9d7ttl7XQUgGhKqJW3RZloZqoKZAYIklj1YSS
-                xoSnZXcpF9q7ZPe24bFf4Qf4BZpoTHwwDY9+lHHutjEoCKbpzLmTmTPn3pn9
-                8fPbdwBP8JjhqSO8MODese0GnaMg8u2wKyTv+HZDOEfRfiAb0pH+K1k8CgOv
-                6/rxsbiSBqPi+oHTc+y2I1r2290D35XV+r/5VOHq9nZ1vcqQ+7swDZ1h/uLi
-                NFIMqVUuuFxnmLbOdi81KcGiHgokrFIzAwNXTCSRYUj2nHbXZ8ifrctgAtkx
-                aMgx6HKfRwzPL7jJhS9DtxsvKo3caTeHHY2WL0dwyiqdbU/arBKpJs2xnawf
-                BrLNhf3al47nSIdiWqeXoKExZQxlwMAOKX7M1WmZkLfCsDboj5uDvqnNaqZm
-                6GU26Bvm7KBfMfJ6Xns26C+zrZmcVlDw3cl7/eRDyjS1XLKgG4mcrkgqDAuX
-                TJHkWP/7OmncY8icfiKGvXNGd05k9AgHvY691xWu5IGI7M0RqlRLl6nM4AEs
-                2rU/FC0dSoaxBm8JR3ZDEqNvBB65bJ0L/023s+uH285uO96TwFUjDLk6j4KZ
-                mhB+uNF2osinLcm+FG47iLho0aj2A4/BbATd0PU3ucqe2xoKavKIU/kLIQLS
-                oO6BFdq2JM2QPiTk1fqRX6RBapilP80Yah8fEtokryJm+SvGy4tfMPkpzntE
-                dgJq+EvQYVP+Ev2AmWE2sV5Va0Jo6hS7SWg6zlHcttoi8snyZ0x+/E2bioN2
-                TJcZJozohiTX6GzH1CxuBsxhmayO+yiNchJ0ReXLqJBfo8w5qirsIFHD9Rpu
-                1HAT8wRxq4YF3N4Bi3AHd3eQihQsRpiIMB1hJkL2F+yJDPSyBAAA
-                """,
-                """
-                androidx/compose/runtime/SnapshotStateKt$produceState$2.class:
-                H4sIAAAAAAAA/41TUU8TQRD+9nptj7PQUgEBFVGrXotyUE1UCiSGQNJYNaGk
-                MeFpac+y0O6Ru23DY3+FP8BfoInGxAfT8OiPMs5eG4OiwMPNfDuZ+ebbnbkf
-                P799B/AEjxmectkIfNE4dut++8gPPTfoSCXanluV/Cjc91VVceW9VLmjwG90
-                6l50zBWTYFRcOeBd7ra4bLpv9g68uipV/s+nC1d3dkrrJYbM34VJmAxz5xcn
-                kWBIrAop1DrDpHO2e75GCQ710CDm5GspWLhiI44UQ7zLWx2PIXu2LoUxpEdg
-                IMNgqn0RMjw/5ybnvgzdbjSnNQreqg06Wk1PDeGEkz/bnrQ5eVJNmiM7Xjn0
-                VUtI95WneIMrTjGj3Y3R0Jg2ljZgYIcUPxb6tESoscyw1u+N2v2ebUwbtmGZ
-                BdbvWfZ0v1e0smbWeNbvLbHtqYwxq+Hbk/fmyYeEbRuZ+KxpxTKmJikyzF8w
-                RZLjXPZ1krjHkDr9RAzH/xjdpSLDZznott13HVlXwpehuzVExVL+It0pPIBD
-                2/eHxsVDxTBSFU3JVScgeeaG3yCXrgjpve6097xgh++1os3x63qogdDnYTBV
-                ltILNlo8DD3am/SmrLf8UMgmDW/fbzDYVb8T1L0tobNntgeCaiIUVP5CSp80
-                6HtgmfYvTlOlXwtZvZDkF2i0Bqbpo6lDb+hDQlvkdcQufMVoYeELxj9FeY/I
-                jkGvwwpMlCh/BYt0mhpkE+tVvTiEJk6x24QmoxzN7eq9Ih8vfMb4x9+0iShY
-                iuhSg4Qh3YDkGp3diJpFzYAZLJE1cR/5YU6Mrqh9AUXya5Q5Q1Wzu4iVcb2M
-                G2XcxBxB3CpjHrd3wULcwd1dJEINcyHGQkyGmAqR/gVj7U/wxAQAAA==
-                """,
-                """
-                androidx/compose/runtime/SnapshotStateKt$produceState$3.class:
-                H4sIAAAAAAAA/41TXU8TURA9d7v9YF1oqYCAiqhVt0VZKCZqCiSG0KSxakJJ
-                Y9KnpV3Lhe1dsnvb8Nhf4Q/wF2iiMfHBNDz6o4xzt41BQeBhZ87czJw5987s
-                z1/ffwB4ijWGZ45oBT5vHdtNv3Pkh64ddIXkHdeuCeco3PdlTTrSfSVzR4Hf
-                6jbdKMytJcGouHrg9Bzbc0Tbfrt34DZlqfp/PlW4vrtb2iwxZP4tTEJnWLi4
-                OIkEQ2KdCy43Gaats93zdUqwqIcCMStfN5HCNQNxmAzxnuN1XYbs2ToTE0iP
-                QUOGQZf7PGR4ccFNLnwZut14Tmnkjlcfdky1XTmCU1b+bHvSZuVJNWmO7GT1
-                0JceF/ZrVzotRzp0pnV6MRoaUyalDBjYIZ0fcxWtEGqtMmwM+uPGoG9os5qh
-                pfQCG/RTxuygX0xl9az2fNBfYTszGW1ewXcnH/STjwnD0DLxeT0Vy+iKpMiw
-                eMkUSY511ddJ4gGDefqJGNrnjK5xzi6NXuGg17Hfd0VTcl+EdnmEiqX8ZTJN
-                PIJFy/aXpOVDyTBW423hyG5AavQtv0UuXeXCfdPt7LnBrrPnRYviN9UMA67i
-                0aFZEcINtjwnDF1ak/S2aHp+yEWbZrXvtxiMmt8Nmm6Zq+y5naGgOg85lb8U
-                wicN6h5YpXWL0xDpT0JW7R/5JZqkhln6aMhQC/mYUJm8OjEK3zBeWPqKyc9R
-                3hOyE1DT34ZOWWPklymaGWYT63W1J4SmTrEbhKajHMVtqzUiHy98weSnP7SJ
-                6LAc0ZnDhBHdkOQGxXZEzaJmwBxWyOp4iPwoJ0ZXVL6AIvkNypyjqvkGYhXc
-                rOBWBbexQBB3KljE3QZYiHu430AiVDAXYiLEdIiZEOnfCWOj1bMEAAA=
-                """,
-                """
-                androidx/compose/runtime/SnapshotStateKt.class:
-                H4sIAAAAAAAA/91Ya1cb1xXdV4AkZAHjsTEgO0S2IWAwCLCT1IY6dokxCg9T
-                g6mJ6ziDGGCMmFHmjohpm8RNW/f9Th9pkz7Sd5u2br/EqdfqYrnf+lPav9DV
-                9tyrkRBiRiC7WcurH6R758557LPPua/5+7//8lcAJ3GHoVMzF2zLWLiZSFmr
-                GYvrCTtrOsaqnpg2tQxftpxpR3P0MScExqDc0Na0RFozlxIX52/oKRqtYqhf
-                0G1jTV+QkhcXGQY7x0sFB4+N+3p6tkh9kOHC0Mzp7fpnOmdmdmtkiETPkKWn
-                /cW5Gx1PSI0RLeVY9vqEZq/oNmkeHbfspcQN3Zm3NcPkCc00LZIzLOpPWs5k
-                Np0mqWO7QpNczaRDiDAEhwzTcM4wNHrxMxtFFHUR7EE9Q/uuLIegMNSsaems
-                zqBut0mpWc062nxaL6Qm7eHan6V8DUxkc8FPWWkjtV4uDRNF/sj/K/65rNRr
-                Lqm7dJ2vgGBG6obRxNC6Yjlpw0zcWFtNGKaj26aWTiRNx6YEGykeQgtlJrWs
-                p1bcDE9ptraqkyBDhxdtmyPTwsiSzOFBHIoghsfKVUcx0lx1PB5BvHzei3VC
-                OMLQX3HaGA5sLYe2BX1Ry6Ydhtf+F2WRrGjWl1RKM3fsbMrJ2lr6/EtZLW04
-                6zmzDCc6y5jxwRJFBzojCOBYFPvRKHrdNEeK4x83uCOmRO9uzBc0CGrSp6gr
-                MZMv0K7dq4TQx1DVmVsoBiLoxwmGvcURTWgZEVDPrpGQAmG4PjTmEc/sQ8VI
-                lodmxgZnZmWU/lOhVCmED0VwSkQWzdjWQjaVi4xhsfwMzI8UzfHFrJnKrdgj
-                bm+gXD3mC/EfZZasSv0N9fj7myoKbzplZdw1qydvMmXZVtYxTJ0nhi1SMbOy
-                vocKApdpMyGFbg+wO8aZL792f7lh+Sxqi+Tayu2HtFS6YmE3Z3YYZ2n73e3Z
-                oq041W39IXwkgmGxHLaWjyKE81QnYlM1tPRsbhusXtHX+xniO1UCw83dVdQH
-                UWP/qqjG/u+q7gELYyCE8QgmRGGILA8wLHmk8OoHkrF/+mescoePfIIEvTyM
-                Sw+cqhMhzERwWaRqnwc/tFIs6Y47Y1/s3Il+f4JtfTFNz4kxoi2j2444m3p4
-                y/hkbyc6uiUfFbgf6iKSSUkc9p1lg58J42puWZSvw7jGsL/TA2MUV3B9D0bw
-                IkNdm9G22LZJEEvSQb5NmCsajO9csyGhQvYZYv58ETpeMLpchpEt57VKMuJ1
-                12F4ueKUbD/fV5gYcYGkw9My6vbgKFbyRG+G75K8OdCx6+NrC3nUbd0UO1Hp
-                +XXywc+LXlcghgFfvUt+KEKgW0w4OTk9c25ymHbNk/6+fW1QkTrI1oJjjeFt
-                k7b9eEoeBOLzOvW4E3esuGmZPfKVs57R43knva6TXtdJr1+AcWtxZyV3yen1
-                5Zym3U06GRRf5qL4RO5m9kmGRIW8h/AK3bfKzDfvm0sIr9Hlpdw89daTPH+6
-                FrfwOsNbjwDPflczovmzDIqpr+m2fJOveP/z/mSJbAifZ+j256hUXnLzxVp8
-                AV9ieOMR4KY0eOLkK3Qtyy9EE7qjLWiORrM2sLpWBYCJv7D4Ay3tK6IToJc3
-                DdGjG15goZ8F/rNx64XIxq1IoDkQCYSrZVt4rPJ6DITpp4hB0Wku+imBTUFl
-                L7XB/HPsMCnEwmq1GhgN9LEj1eGNW0pgIKhUxWhgNHT/nWBAqY7tV2oKQkFX
-                aDQUiyuhWL0crpX/kb5w7mUtNUyJkEi/sqegGS0xP1AfDih1hdf1rruGmKoo
-                m6OuUmxJ2VsYVDct7ZOWwsr+WHUz62uk3gG316M0xY6FmRpR82ot+X7fwb6Y
-                GlSlXF+z8Bo+NBr62122cUtCeCx2bXfeHsJHa2ylnI8DyuOxqBom2zkL8SMP
-                7fEwEXtkO7GqcnT74EmlTcBwH7sKMCn2djf2iPJELKhSEfV1jN6/HZEuOmND
-                yrEYISlVjHorFiotb6Dr/usBKvZwi5gGA2X335KPxmyG4Xhln3HKrDoeH0nY
-                GP3o3ALxpdWd3MW3yTLOtx3pB4vupz7neRJpzYucv+noJqfBvL+ZdWlD2QKz
-                d8Whg/uwtUDnloZxMjiZXZ3X7RlxShGYrZS4I9uGeHYHa6eNJVOjhZ36By/l
-                0CbNNYMb9Prc5hWf7v+lbwvfRreI1RGS1AoR5jqIJk1Tt4fTGuc6vY5MW1k7
-                pY8Y4l2La3J2mzv0I4BqsUCiDi2oQRBV+CU9PUUtZQDRe9gz1/UeGjaw945Y
-                P/Er+g/Kdyp+LSRycvS0j9rfSJkQfkut+BIYpraWfi3i0yB5ErZHyHZA6Her
-                zXfReg9x4eHwBo5u9RBEq/RwICftehC9JrTR+5yvA9t8/U60Abno06NSi3Y8
-                QX3h+pQbrnKo5tU3EbqLrvGu7rs4nnP8Lv1T2BGJoB5ilzhIKB4j6wcpgh70
-                uuzEJSLaW+6hf+49nLwjnW0yc9jFlvDg4UnJbYmVU2TldKmVdtfK0x5WBjHk
-                sjlF1gRS9bh6TrI5LNh8dgMjpWz2SjbjOWlcKLA5Sr1cPs8iSRo5rx8ueD1T
-                xGuD3FfxTJ5dCeU5F8rzZFqwq/a4UCYElEkPKKcllK6ctCeUi9QLFEBVuaDG
-                PEE1VheB2gptyoU267LU3K1OE7Q8V5cFwNltAKM4X8RVcwFgMy7hYxJg8xau
-                PlqOq9oiQFcw5yb/mluJjV3qxyWgF+i/6kzX+9AYtqKpx2SBrnqaW/NISVyN
-                WIAucTVi0SWukQwvFXA9L3HsqyqgKCZnGYaLZZVEa6ht2oLlqequnveRDuBP
-                BTQiwgZcpjk3KxGdJLUGqspVQiSCaYIJSyJqKiBqchGJnpjB+VTeyKduOzaB
-                LoNOF127DJYWqD/j5Tl1/S4+tYFXS+fKddfqSzITwUKQHV5mPjOnfs7bzLKP
-                mdteZr48p37V20zG00wVfk//MWqH3SAn3Pay2/5Bav0Cf6T2XdL6GvH79auo
-                SuIbSXwziW/h20m8ge8k8V187yoYx/fx5lV0c9Rw/IDjhxwqR5Cjh+Mtjic5
-                3ub4EcePOfZzWBxNHG0cjRy3OQY5dI4LHKMcP+G4yHGW46cc73D8TI78nOM5
-                jiGOS/JxiiPD0cFxhWOR4xrHEsccxzKH8V81aexK6B4AAA==
-                """,
-                """
-                androidx/compose/runtime/SnapshotStateList.class:
-                H4sIAAAAAAAA/41QTUsjQRSs7smXY3YdXT/irruKJzcsOyqCoCKoIARmd8GE
-                XHLqZBptk3TLdEc8zm/xH3gSPMjg0R8lvoleVi9e6r2qLt571Y9Pd/cAtrDC
-                UBc6ToyKr8KeGV4YK8NkpJ0ayrCpxYU9M67phJORsq4MxrC219qJzsWlCAdC
-                n4b/uuey53b330sMwVutjAJDaU9p5fYZvLWf7SpKKPsoosJQcGfKMvyKPn4R
-                LZmO+sYNlA7/SCdi4QRpfHjpUT6WQyUHMLA+6VcqZ+vUxRsUJUurPq9xP0t9
-                HhBkaS1L64VKlgZsk6/zw+LDdYkHXu7fpBEtlk8K/jvjd9/R6UcmlgxTkdLy
-                72jYlUlLdAekzESmJwZtkaicv4oTTXWqhRsl1PtNM0p68ljlD4snL0Hbyipy
-                HmhtaIUy2mIDnH7pNUr+aYRfiYVjDhTrt5i4oYbjG2FpLK5iibD6YoCPSaoe
-                vo9dHn6M6yKWqW6Tp0qeTx14DXxuYKqBANPUYqaBL5jtgFnMYb6DgsWkxYJF
-                zaL8DHqS9VZKAgAA
-                """,
-                """
-                androidx/compose/runtime/SnapshotStateMap.class:
-                H4sIAAAAAAAA/41QyU4bQRB91eONwYGBbCZ7LlEgUgZQTsRCSiJFshgSKY7m
-                4lPb04LGdrc13UYc51vyB5yQOKBRjvmoKDWGS5ZDDvWq6vXr2n78vLwC8AbP
-                CZvSZLnV2Vk8stOZdSrO58brqYr7Rs7csfV9L706lLMmiNDtHuwlJ/JUxhNp
-                juLPwxM18m/Tf3D7f1OE6E+uiRqh0dVG+31C8HIzbaOBZog6WoSaP9aO8Cr5
-                7yG5x1oytn6iTXyovMykl8yJ6WnAG1MFrQpAoDHzZ7rKtjnKdghxWayEoiNC
-                0WKLyiIsi05ZbNVaZRERO4rErtgO3te/f2uIqFZ92+VKB2wpVUWj3wZ6Pfa8
-                xAebKcJqoo36NJ8OVf5VDifMrCd2JCepzHWV35BLfX1kpJ/nHId9O89H6qOu
-                Hja+XK+caqdZ+c4Yyy20NQ47EHyvm62q8zE+5Cxe5EB96wJL5xwIPGJsLMgX
-                eMzYvhYgxDL7AE8WqgBPF/4BnrHfY02bNbcGCHpY6WG1hwhrHGK9h9u4MwA5
-                3MW9AeoOyw73HToOGw7NXygOZ4ZqAgAA
-                """,
-                """
-                androidx/compose/runtime/State.class:
-                H4sIAAAAAAAA/31Qy07jQBCsthPHmJeT5RECQhzDHtaAOKx4SXtBihSERCKE
-                lNOQDGGIM0aZScTR38KBj+CALI77USvaYU+AuHR1VU/3VPfff88vAPaxQdgU
-                ujdKVO8h6ibD+8TIaDTWVg1l1LLCyhKIUD9qHzTvxEREsdD96Pz6Tnbt4cln
-                iRB+1EooEPy+tJciHkvCUn37q75ifbvdZiw3B4mNlY7OpBU9YQVrznDisl3K
-                g58HEGjA+oPK2Q5nvV3CUZYuBE7VCbI0cMI8+K5/U83Sn56fpSFt0Z6z41xU
-                Qrfm/M7Sq9enwuuj59UKfiEs5jP2CFvN78/BbqhNuYHi5H2fsKXFvblN7LT+
-                a2AJMy3V18KOR1wOWsl41JWnKmaydvE+61IZdR3LP1on3KQSbTz+H0VMd+N7
-                eeC7Y42ZAx/u/8xFbYpVrDMe84sZ7gk6cBuYbWCugXkscIrFBkKUOyCDCn50
-                4BksGSwbrBismpyW3gBNs/uhAwIAAA==
-                """,
-                """
-                androidx/compose/runtime/StructuralEqualityPolicy.class:
-                H4sIAAAAAAAA/5VVW08bRxT+ZteX9WLAcVJqCE2ThjbmljWkdygtIVQxciiq
-                I6qWp7E9dcasd53dWStRX1B/Sp/70KgPiVqpQu1bflTVM7suIQYikOU5Z845
-                c+Y7t9mX//7xF4APscmwxL1W4MvWE6fpd3t+KJwg8pTsCqeugqipooC7m48j
-                7kr1dMd3ZfNpFozhu1qH97njcq/tfNPoiKZaqZ3tyeO98JGvHkSKK+l7iZ/V
-                ky7WVhgKw9IsUgzOBZ1nkWHIrEpPqjUGszy7m4eFnI00bIaUeiRDhjtvgHxG
-                8ATQFo8j2eeu8BTDrfIpiTghmf2BYabmB22nI1Qj4NILKSDPTxCHznbkurzh
-                CvJ+bd9XrvScTr/rSE+JwOOuU/VUQGdkM8ziEoPFAxHDyuMyxm0UcYWBcYbi
-                yatJ0aATyq9rF22GK+XZY1aJlKxuvgmerzRCsiqdlRcL0wzprgjagmHrXEk5
-                JU2nwV+9YOVn7okfeeSqarfnUrquM/xUvmhrngvtufDncQ3v2biBm1SEXiD6
-                0o+o87LNKAjiBsryXs+VokXq1aYb96sNQzepVd2uP1zf3tjMYw6jORLOM1yq
-                DfrjgVC8xRWnDBndvknjzPRi6QVU9H2SP5F6VyGutcQgDg+mbaNkJP/C4YFt
-                WJoZIWoSHbP++dkoHR4s28VMMVViFaPC7mYt4+9fMkbB3JoupKaMSnrZKmSm
-                Yi1x2YS7P7FlFSzS5u5P6MuW6Vm5cMqZhp0/Xjx6C/63rZOpuL1P+br6beKm
-                6vVlKGlm1l81Kg32ht+iBhyvSU9sR92GCB7qudKT4Te5u8sDqfcD4cywrx0e
-                8K6goXvNab7qeSLYcHkYCtrm6rLtcZoB8mDX/Shoiq+ldjc5cLd7AhgqVL00
-                xUdvJyZ1OYmuUm0yRK8STZOenifafUE7RxdQS+eeY+QZMQbWBsZAB1/Smk8M
-                iI7G9R7DOFnpw/eI6rJn5hde4K1fh07vx6evJxaD05qbwNuxPoMScQa+In7U
-                IFEhdp+sk5gaXLI4QGgW3/lt6Ab3GD5zcMPxUOmJw7uk0W52kKIfde3c/MLi
-                C8wM+0pinUtsjtBaeH+A1sIHMVrN3SLOPLpJA9YxXDaHYijExuWjXCfHgZE/
-                YXz/HLO/Y+FZLEhhnVabzG5Q2T6n4O/G6ExsxHSFMg1USb9Idbi9B7MKp4pK
-                FUtYJhZ3qvSF/WgPLMTH+GQPdojREJ+G+CxELsRYzEyEKIWYJP4//rdNjpUH
-                AAA=
-                """
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuOSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFRL0LS1JTMpJ9cwrCS5JLEn1LhHiD85LLCjOyIcJcOlwKeHSr5eT
+        mVeiV5JaXCLEFgIkvUuUGLQYAH5U0JeGAAAA
+        """,
+        """
+        androidx/compose/runtime/DerivedState.class:
+        H4sIAAAAAAAA/4VRTW/TQBB9Yzuxk4bghhbSAG1BQiQccKk4IFJVQnyISKmQ
+        mihCymkbL2Ebx668m6jH/BYO/AgOyOqRH4UYp6hCRIXLzLzZN29Hb378/PYd
+        wHM8IDwScZgmKjwPRsn0LNEySGexUVMZvJGpmsuwZ4SRLohwdNB/2T0VcxFE
+        Ih4HH05O5ci0D1db3Ws1l2IH/X77sE3w/x504RC2/z3sokjwxtIMRDSThI1m
+        a3UBQqHZ4l+Yqa+Ym81VYmtAKDaZmRfr3UliIhUHR9KIUBjB89Z0brNVlIdS
+        HkCgCffPVY72uAqfEd5mi2rZqlvlbLFMllfwPtWzxRPHyxY+7Xs1p2a9pz3r
+        uO7bDetFtvh48bV68aVYaTie4xceOl7Rd3OxfcLj6/378ya8HfUJu/9xOzdj
+        fumA34vFmf6cmOXD04khlHpqHAszS/m53Etm6Ui+UxGDreNLkYHS6iSSr+I4
+        4SGVxJr9t1BgH1w2wOKLeSgx2s4RyozXULnCN2D/rmzsLPN97HJ+zYwqq9wc
+        wu7A72C9gxpucYmNDjZxewjSuIP6kE+ILY2Gxl2NezqHJY01jcovIuyLgMcC
+        AAA=
+        """,
+        """
+        androidx/compose/runtime/DerivedStateImpl.class:
+        H4sIAAAAAAAA/41S224SURRdZ2YYhpHClN5rvVVrgdpObXwwLcF4SSMJalII
+        MfbpABN6Wphp5hxIH/kKP8Av0ERj4oMhffSjjHuANCom8rL32mv22Wtf5sfP
+        b98BPMIOQ477zTAQzQu3EXTOA+m5YddXouO5L7xQ9LxmRXHllTrn7TgYQ7VQ
+        3S+f8h5329xvuW/qp15DHRQnqfJUdQvV6kHxgMH5+30cBsPGVDXiMBnMgvCF
+        KjIsZCd7ydUoIUtSEdCzuVoSFq7ZiCHJEOvxdtdjyEy+SyKFdAIaHAZDnQjJ
+        sDXdXNG+aCyr5anaqPx8NjcpQOrZHPVFmfIqM14gvP2EZtGHn2bLZ4FqC999
+        5Sne5IoTp3V6Ol2QRSYRGTCwM+IvRBTtEmo+ZHg36KdsbVmzB/2h0yzT0pYH
+        /bxhDfoO27MyRkZ7yXa1ZzMZ09FXtceD/uUHU3OMo7Vx+PbyfYoox9Yca9Ww
+        Yo65blhxx4gU9ki0yrA53U6iM1d8fi5PAjUkds4UQ6IiWj5X3ZAmN54HTXLp
+        svC9191O3QurvN4e3iZo8HaNhyKKx6RdCbphwzsUUbByNFKsCSno61PfD0hC
+        BL7ELh0wRvuh/5cQXZR8lpakYQU6YQvRiXPEFMlr5O38V8zkt75g9tMwL0/W
+        pEzQ2y2yi6MsZDAXrZ7Q71VtQvNYGNd0o8uQj+U/Y/bjP8slRwnjcqMii8Qt
+        XTW2P27M/G9T5lVTJpb/aEofIx0Phn4T2+QPKWOVtK8fQy9hrYQbJdzELYK4
+        XcIdrB+DSdzFvWMkJOYkNiTuS6RkFM5LLEgsSaR/Aaib5exSBAAA
+        """,
+        """
+        androidx/compose/runtime/MutableState.class:
+        H4sIAAAAAAAA/4VR0WoTURA9c3eT3aQxbmOradRaBTHxwa3FBzGlIKIYSBCa
+        EIQ83SZr3GZzt+TeDX3cb/HBj/BBlj76UeJsKkUM1Zc7c+aeOTOc+fHz23cA
+        L/CQ8FiqySIOJ+f+OJ6fxTrwF4ky4Tzwe4mRJ1HQN9IEDojQOxy86p7KpfQj
+        qab+h5PTYGzaR+ul7rWaK7HDwaB91CZ4fzc6sAm7/252UCS408AMZZQEhK1m
+        a30BQqHZ4inM1FfM7eY6sTUkFJvMzJPN7iw2Uaj8XmDkRBrJ/WK+tNgqyp9S
+        /oBAM66fhzna52zynPA2S6tlURflLF0F4RbcT/UsfWq7WerRgVuza+I97Yvj
+        umc1xMss/XjxtXrxpVhp2K7tFR7ZbtFzcrEDwpPr/fvzJrwdDQh7/3E7N2N5
+        6YDXV/JMf47N6uPZzBBK/XCqpEkW/F3ux8liHLwLIwY7x5ciw1CHPPG1UjE3
+        hbHS7L9AgX1w2ADBF3NRYrSbI5QZb6ByhW/A+p1ZeLCK97HH8Q0zqqxycwSr
+        A6+DzQ5quMUptjrYxu0RSOMO6iM+IXY0Ghp3Ne7pHJY0NjQqvwDJFOU0xwIA
+        AA==
+        """,
+        """
+        androidx/compose/runtime/MutableStateImpl.class:
+        H4sIAAAAAAAA/41S204TURRdZ2Y6nY6lDIVyE28o0hZhkPhgoKlRE2KToglt
+        GiNPh3YCB9oZ0nPa8Niv8AP8Ak00Jj6Yhkc/yrhP2xBiTezLXmuv2Wdf59fv
+        Hz8BPMMWQ46HjXYkGpd+PWpdRDLw251QiVbgH3QUP24GFcVVUGpdNONgDNVC
+        dbd8xrvcb/LwxH93fBbU1V5xXCpPlLdQre4V9xi8v9/HYTGsTZQjDpvBLohQ
+        qCJDJjveS65GAVkqpYmZzdWScHDLRQxJhliXNzsBQ3r8XRIpTCdgwGOw1KmQ
+        DBuTzaX3RWM5J4GqDdPPZXPjBah6Nkd9UaS8jowXiG++oFnMwaeZ8nmkmiL0
+        DwLFG1xx0oxW16QLMm0S2oCBnZN+KbS3TazxlOFDv5dyjUXD7fcGYDi2Yyz2
+        e3nL6fc8tuOkrbTxhm0br6bStmcuG8/7vatPtuFZhysj9/3VxxRJnmt4zrLl
+        xDx71XLinqUr7FDRKsP6ZDvRZ66E/EKeRmogbJ0rhkRFnIRcddo0ufU6ahBM
+        l0UYvO20joN2Vb/Wt4nqvFnjbaH9kehWok67HuwL7SwdDivWhBT09WUYRlRC
+        RKHENh0wRvuh/5cYXZQwS0sysASTuAN94hwpRUKD0M1/x1R+4xtmvgzi8mRt
+        igQWsUF2fhiFNGb16ondzOoSm0NmlNPXlyGM5b9i5vM/0yWHAaN0wyTzpC1c
+        N7Y7asz+b1P2dVM26TebMkfMxJMBrmOTcJ8ilqn27SOYJayUcKeEu7hHFPdL
+        eIDVIzCJh3h0hITErMSaxGOJlNTunERGYkFi+g+3c7/UUgQAAA==
+        """,
+        """
+        androidx/compose/runtime/NeverEqualPolicy.class:
+        H4sIAAAAAAAA/5VU3W8bRRD/7Z0/zhcndZyQpmn4KA3UTpqeE8pnTNoSinqR
+        ayJcBUGe1vbibnK+c+/2rCJeIv4Unnmg4qEIJBTBW/8oxOydCcFJUSLLO7Mz
+        s7/5zc7svfjr198B3MZdhir3u2Egu0+dTtAfBJFwwthXsi+cphiK8P6TmHs7
+        gSc73+bBGL5s7PMhdzzu95zP2/uiozYaL0Vo+XwQPQ7Uw1hxJQM/xamfhtjc
+        YCiNW/PIMDgXBM8jx5CrS1+qTQazUt0twkLBRhY2Q0Y9lhHDysspjxdNxGzx
+        JJZD7glfMdyonHEBpyzVrxmWGkHYc/aFaodc+hEV4gcp08hpxp7H254gdMYZ
+        yqcRyNFmsFTQUqH0ewyzleqJqNRKUdf/L0ugdCJ9t+NlWbjMkO2LsCcYts9V
+        0xlVnkW7fsGGLX0qvuGxp9z+wIvyuMrwXeWiE3UutufiX8QVvGpjEa/R5Q9C
+        MZRBTAOT78RhmPQ/zwcDT4ouuesdLxkzG4aeLcttth7da27dL+ItTBbI+DbD
+        dOMgUBTmPBSKd7nidENGf2jS62N6KegF1OwDsj+VelcjrbvGII4OF21j3kj/
+        paND27C0MkHSJDll/fm9MX90uG6Xc+XMPKsZNfZJ3jL++CFnlMztxVJmwahl
+        161SbiHxkpZPtQdz21bJIm/hwZxOts6wduErZ5p28WTzaMz+iW1RqLh1QPd1
+        9YsUxvWHMpI08vf+HVB6j1tBlwbwUkP6ohn32yJ8pJ+FfhFBh3u7PJR6PzIu
+        jWPt8JD3hRLhf0CLru+LcMvjUSRoW2jJns9VHBKC3QrisCM+kxruyghu9xQx
+        1Kh7WaqPPnk0ENROku9Tb3Ik50hmyU9fFdp9QDtHN1Bbl59j4hkpBj4cBQMh
+        PqK1mAaQnEz6PYVLFKUP36Wdbrth/jh2MkpOvpF6Rye1No1y4jcwQ5qBDdIn
+        DTKVEuh0ncUrowSrI3Zmef6nsQzqBDdzlOFkmbr4BfJomB1k6AdYyys3V3/B
+        6+NYaZ3LacwxW4v4p2wtXEvYau1N0szjTJqwrmHGHKuhlARfP77ny8lxYOI3
+        GF89x9LPuPEsMWRQp9WmsEVq2bvE+uOEnYnNRL6HOyRd8leoB9U9mC6WXay4
+        uIlVUnHLpSbW9sAirGF9D3aEyQjvRLgdoRBhKlGmI8xEmCX9b4SHlftABwAA
+        """,
+        """
+        androidx/compose/runtime/ProduceStateScope.class:
+        H4sIAAAAAAAA/41SW28SQRQ+s1BYkOoWb5TitTUqMe5KfHIJ0WhIMVQbQRPD
+        07AMOLDMkJ1Z7CO/xQd/hA+G9NEfZTwL3TYWa/swc27f+c5cvl+/f/wEgOew
+        Q6BMRS+QvHdge3I8kYrZQSg0HzN7P5C90GMtTTVreXLC0kAItKvtF80hnVLb
+        p2Jgv+8Omafd2mqqeSbxXqhp118SV9ttt+YSsE73pyFJ4MGFONKQIpCjXynX
+        b7iKYHjMR82R1D4X9nA6tvuh8DSXQtn1I89x47onAxlqLpiyX0skFyGNAO7j
+        1SsR6J9HW43rHwXHZzlvSrVc+/egnaYMBvaQ6W5AOQ6gQkhNl8Pehb4fXR5h
+        2/+DSR0hEbURn2KPadqjmmLOGE8TqAESbZloAwJkhPkDHkUOer1nBD7PZ6Ws
+        UTCy89mxsUgcGVaUMfuF+aycNOczi1TMfDJv7BLHeFuyEkXDSVZy1lpxkXXS
+        Tmr38PvLw28pwzKjARUCT87WyYoA8dikTeDhxaSFaLxTRopjUeTjdzhRASqv
+        JehEfZF60fR0pLGnxQeC6jDAnq0PS+qGmHLFkfvVyRPjN52u7tOAjplmwV+w
+        bEuGgcfq3EfGzaOeTyt8KGMD1vDQ6eg7UP8mZCABdzAyIAt30aawegntPVzr
+        Bga5xc9FewxMwP2FvQ3baOtYXUfSyx1INOBKA6wGbEAeXbjagGtwvQNEwQ24
+        2YGMgoKCTQVFBaaCLQUlBbcWTuYPf2PH6TMEAAA=
+        """,
+        """
+        androidx/compose/runtime/ReferentialEqualityPolicy.class:
+        H4sIAAAAAAAA/5VUW08bRxT+ZteX9WITYygBQq8hiblljUuvuDSUpoqRIShG
+        RC1PY3viDKx3nb1YifqC+lP60L70oVEfUrVShdq3/qiqZ3Zd6hqoQJbnnDnn
+        zHe+M+fM/vnXL78BWMUGQ5k7Lc+VredW0+10XV9YXugEsiOsR+KJ8ATp3L7/
+        LOS2DF7surZsvkiDMTyuHfIet2zutK2HjUPRDNZqF0LVHd71n7rBdhjwQLpO
+        jFM5C7G+xpAftqaRYLCuCJ5GiiFVkY4M1hn04vx+FgYyJpIwGRLBU+kzrF5M
+        +cLqiaEpnoWyx21yM9wpnnMTZyzzXzHM1VyvbR2KoOFx6fhUkePGlH1rJ7Rt
+        3rAFoTPOUDiLQI4GgxG49cCTTpthojg/EBVbKerm/2VxA5WIoqYvrM/AdYZk
+        R3htwbB1qeLOKfc8/pUrtnDuc/GEh3ZQ7XRtP40bDF8Xrzpjl2J7Kf5ZTON1
+        E7N4g7rQ9URPuiGNULoZel40CGne7dpStMhdadrR4JnQ1LQZ1Z363sbO5v0s
+        biGXIeNthrHakRtQmLUtAt7iAacb0jo9nR4mU0tGLaCuH5H9uVS7EmmtFQZx
+        cjxralNa/M+fHJuaoZQRkjrJUeOPb7Spk+OyWUgVElOspJXYZ2lD+/3blJbX
+        t2bziRmtlCwb+dRM5CUtHWsPJreMvEHezINJlazMsHLlK2eKdnawefSo/4mt
+        U6i4e0T3deNRDFN1etKXNPsb/04qvdBNt0UDeK0mHbETdhrC21PvQz0Nt8nt
+        fe5Jte8bcwTbPNrm3f5+bhh7l3u8IwLh/SdJtuo4wtu0ue8L2mbqsu3wIPQI
+        way7odcUX0gFN92H2z9DFCXqZpLqpY8iDQi1l+QH1KsUyUmSSfLTd4d2H9LO
+        Ug1V1oVXGHlJioaP+sEAx8e0ZuMAkrmo/6O4RlHq8B5JNQYji0vfIZ34Hgn9
+        B9rqWIvzZO6xAbRGhPZWfKKPprQxFCL/CMZJ01AhPaeRKR+li9cJvNZPutxn
+        rBemfhzi2xzgq/czDJauLmSGPApmFwn6AcbC4tLyz3hzGCuufSGOOWVrEP+Y
+        rYG3I7ZKe4c0/TSTIqxqGNeHashHwTdP7/56dJwK/xXal68w9xPuvIwMCXxC
+        q0lhs9TG94j1esROx6eRfB/3SFbJX6Rrnj+AXsVCFYtVLGGZVNytUmNLB2A+
+        VlA+gOkj5+NdH6s+Mj5GI2XMx7iPCdL/Br5SJwt/BwAA
+        """,
+        """
+        androidx/compose/runtime/SnapshotMutationPolicy$DefaultImpls.class:
+        H4sIAAAAAAAA/5VSTW/TQBB96yR1E1L6wWcotEADohwwlTiRqBIqQjJKS0Wi
+        Hspp4yzpJvautV5HRfwpzhz4AfwoxKyTCmgQIpY9++bNm5n17H7/8fUbgBd4
+        zNDmamC0HJwHkU5SnYnA5MrKRARdxdPsTNvD3HIrtTrWsYw+NV+LjzyPbZik
+        ceaDMayN+IQHMVfD4F1/JCLro8RQSYQZCobPTzoLdmh1Lhf8L2Z3nmI4bfde
+        zvP7C++p3eu19ltkpu8ufQzNjjbDYCRs33CpsoArpadJWXCUxzHvx4JkO/+S
+        aeuUpKo07ZnMGPYWHhfDcmrEROqc0jf+NgU/yo0RyhLiaRpLMWBY74y1jaUK
+        DoXlA2456bxkUqJ7wZypOgMGNnaADtQ7lw49ZwgW3KGPBkP993tDl+ZC2iWl
+        eDamvZUP9IAuzGpHKnGUJ31hem6C7p90xOMTbqTzZ2S1K4eK29wQ3nw/7R+q
+        icwkhV/9GjEd0+XoMTc8EVaYP2T1UClhDmKeZYLcWlfnJhJvpGvWmJU4mSuP
+        PXgoYzqrKipYIu8eeW/Jd7zHvjiLLbJLxAGn2Cb7dBpFDVeKbA91rBRxD1cJ
+        eQVaJVTC/QL7eDCrsUzrQ/pWykXTi6eEHbI14jzcwSYaaBaJd/GI1i3i10iz
+        /gGlEBshroW4jhshbuJWiNs/AT8TejEUBAAA
+        """,
+        """
+        androidx/compose/runtime/SnapshotMutationPolicy.class:
+        H4sIAAAAAAAA/5VTzW7TQBD+1kltx2mLC6WkKeU3NCkHnFYcEK2QEAjhKgXU
+        RBzoaZNswybOOnjtqHDKs/AYHFDEkYdCjJ1WINIDlbzz/83szox//vr2HcBj
+        bDN4XHWjUHZPvU44HIVaeFGiYjkUXlPxkf4YxodJzGMZqndhIDufLTCG2n7r
+        aaPPx9wLuOp5b9t90Yn3ns2bGNx/bRbyDI74lMgxD4SKGaq1eeC8ZfsDQ6HW
+        au3Rl8oLQxH1BMPBf6EvyHfRbZfPCqQ16DBUGmHU8/oibkdcKk3dUuGsHdp7
+        kwQBbweCwlYagzAOpPIORcy7POZkM4bjHHWZpaSQEjCwAdlPZarVSeruMHyZ
+        TlYdo2Q404ljuEQyXnQM27ZPStPJw7w9nbhs16gbB5turmzU87umu1A2nkwn
+        JJiZ8Hrrx1fTcK2DqmuX8yU28xXOg5xzoTiLXsuiF9Mb7DLsNC65A/Q41mLZ
+        ezidNoM9isRYholmsDpJFGVztfhoFEjRZdi/ZIHKS3HCkyD2h6NAW7jDsPi3
+        hbbqHNckmHg0oGqFpuwpHicR7cTG0Sy9r8ZSSxrR8z9jo1y+UiJ6EXCtBalO
+        M0yijnglA0KunyHfz+FM6hYW0jHCoA02QX8CKqkGm/QCHJJmehEPiJvkXySe
+        xxZRh7S75LuH9bOoHKoZv48a8SPyL1H+5WPkfFzx4fpYwVUScc3HKq4fg2ms
+        4cYxljRKGusaZQ0zoxsaNzUsjYLGpsYtjdsazm99oitP5wMAAA==
+        """,
+        """
+        androidx/compose/runtime/SnapshotStateKt$produceState$1.class:
+        H4sIAAAAAAAA/41TbU8TQRB+9np94TxoqYBQFVGrtkU5qCZqCiSGSNJYNaGk
+        MeHT0h5l4bpH7rYNH/sr/AH+Ak00Jn4wDR/9UcbZa2NQEEzTmWcnM888uzP3
+        4+e37wCe4DHDUy5bgS9ax07T7xz5oesEXalEx3Xqkh+F+76qK67cVyp/FPit
+        btONjvmVJBgV1w54jzsel23n7e6B21SV2r/5dOHq9nZlvcKQ+bswCZNh/uLi
+        JBIMiVUhhVpnmC6c7V5sUEKBemgQKxQbNlK4YiEOmyHe417XZcierbMxgfQY
+        DGQYTLUvQobnF9zkwpeh243ntUbBvcawY6rtqhGcKhTPtidthSKpJs2Rnawd
+        +soT0nntKt7iilPM6PRiNDSmzZg2YGCHFD8W+rRMqLXCsDboj1uDvmXMGpaR
+        Mkts0E9Zs4N+OZU1s8azQX+Zbc1kjJyG707emycfEpZlZOI5MxXLmJqkzLBw
+        yRRJTuF/XyeJewz26Sdi2DtndOdERo9w0Os4e13ZVMKXobM5QuVK8TKVNh6g
+        QLv2h6KlQ8UwVhdtyVU3IDHmht8il64J6b7pdnbdYJvvetGe+E09wkDo8yho
+        V6V0gw2Ph6FLW5J+KZueHwrZplHt+y0Gq+53g6a7KXT23NZQUEOEgspfSOmT
+        Bn0PrNC2xWmG9CEhq9eP/CIN0sAs/UF7q/fxIaFN8jpilb5ivLT4BZOforxH
+        ZCegh78EEw7lL9EPmBlmE+tVvSaEpk6xW4SmoxzN7egtIh8vfcbkx9+0iSjo
+        RHT2MGFENyS5RmcnomZRM2AOy2RN3EdxlBOjK2pfQpn8GmXOUVVuB7Eqrldx
+        o4qbmCeIW1Us4PYOWIg7uLuDRKhhPsREiOkQMyHSvwDFJnyjsgQAAA==
+        """,
+        """
+        androidx/compose/runtime/SnapshotStateKt$produceState$2.class:
+        H4sIAAAAAAAA/41TXU8TURA9d7v9YF1oqYCAiqhVt0VZqCYqBRJDIGmsmlDS
+        mPC0bNdyob1Ldu82PPZX+AP8BZpoTHwwDY/+KOPcbWNQFHjYmXMnM2fm3jn7
+        4+e37wCe4DHDU0c0A583j23X7xz5oWcHkZC849l14RyF+76sS0d6L2XhKPCb
+        kevFx0I5DUbFtQOn69htR7TsN3sHnisrtf/zqcLVnZ3KeoUh93dhGjrD3PnF
+        aaQYUqtccLnOMGmd7V5sUIJFPRRIWMWGiQyuGEjCZEh2nXbkMeTP1pkYQ3YE
+        GnIMutznIcPzc25y7svQ7UYLakbutBuDjpmWJ4dwwiqebU+zWUWammaO7Xjt
+        0JdtLuxXnnSajnQopnW6CVoaU2ZEGTCwQ4ofc3VaItRcZljr90aNfs/QpjVD
+        y+gl1u9ljOl+r5zJ63ntWb+3xLanctqsgm9P3usnH1KGoeWSs3omkdMVSZlh
+        /oIt0jjWZV8njXsM5uknYjj+x+ouFRk+y0G3Y7+LhCu5L0J7a4jKleJFc5t4
+        AIvU98eMi4eSYaTOW8KRUUDj6Rt+k1y2xoX3OursecGOs9eOleO7aqkBV+dh
+        0KwK4QUbbScMPdJNdlO4bT/kokXL2/ebDEbdjwLX2+Iqe2Z7MFCDh5zKXwjh
+        0wzqHlgm/SVpq/RrIa8ESX6BVqthmj6QkpVCHxLaIq8iRukrRksLXzD+Kc57
+        RHYMSg4r0FGh/BUs0mlqkE2sV5VwCE2cYjcITcY5ittWuiKfLH3G+MfftKk4
+        WInpzEHCkG5Aco3OdkzN4mbADJbI6riP4jAnQVdUvoQy+TXKnKGq2V0kqrhe
+        xY0qbmKOIG5VMY/bu2Ah7uDuLlKhgoUQYyEmQ0yFyP4CSN9ZzcQEAAA=
+        """,
+        """
+        androidx/compose/runtime/SnapshotStateKt$produceState$3.class:
+        H4sIAAAAAAAA/41TXU8TQRQ9s91+rQstFRBQEbXqtigLxURNgcQQmjRWTShp
+        TPq0tGsZ2M6S3WnDY3+FP8BfoInGxAfT8OiPMt7ZNgZFwYe9H5N7zz0z9+z3
+        H1+/AXiMdYYnjmgHPm+f2C2/e+yHrh30hORd164L5zg88GVdOtJ9IfPHgd/u
+        tdwoza8nwai5duj0HdtzRMd+vX/otmS59m881bixt1feKjNk/2xMQmdYvLg5
+        iQRDYoMLLrcYZqzz0wsNKrBohgpiVqFhIoUrBuIwGeJ9x+u5DLnzfSYmkUlD
+        Q5ZBlwc8ZHh2wU0ufBm63UReceSO1xhNTHVcOQ6nrcL58cTNKhBr4hzZqdqR
+        Lz0u7JeudNqOdOhM6/ZjtDSmTFoZMLAjOj/hKlulqL3GsDkcTBjDgaHNaYaW
+        0otsOEgZc8NBKZXTc9rT4WCV7c5mtQUVvjl9p5++TxiGlo0v6KlYVlcgJYal
+        S7ZIdKz/fZ0k7jGYZ5+IofOX1TX/oqXxKxz2u/bbnmhJ7ovQroyjUrlwGU0T
+        D2CR2H6jtHIkGdJ13hGO7AXERt/22+QyNS7cV73uvhvsOfteJBS/pXYYcJWP
+        D82qEG6w7Tlh6JJMMjui5fkhFx3a1YHfZjDqfi9ouRWuqud3R4QaPOTU/lwI
+        nzioe2CN5BanJdKfhJzSH/ll2qSGOfpAwlWCfEhRhbw6MYpfMFFc/oypj1Hd
+        I7KTUNvfgU5VafIrlM2Oqgn1qtIJRdNn0A2KZqIahW0rGZGPFz9h6sMv2ER0
+        WIngzFHBGG4Eco1yO4Jm0TBgHqtkddxHYVwToysqX0SJ/CZVzlPXQhOxKq5X
+        caOKm1ikELeqWMLtJliIO7jbRCJUYT7EZIiZELMhMj8ByotGl7MEAAA=
+        """,
+        """
+        androidx/compose/runtime/SnapshotStateKt.class:
+        H4sIAAAAAAAA/91Ya1cbxxl+RoAkZAHrtTEg20S2IWAwCLCT1IYSu8QYhYup
+        wdTYdZxFLLBG7Co7K2LaJnFv7v2eXtImvaT3Nm3dfolTn9PDycf+kp72L/T0
+        9J3RSgixK5DTnJPTD9LMzryX533ed2Zn9u//+evfAJzBfYZOzVy0LWPxTiJl
+        rWUsrifsrOkYa3pixtQyfMVyZhzN0cedEBiDcltb1xJpzVxOXF64radotIqh
+        flG3jXV9UUpeXmIY7JwoFRw8OeHr6Zki9UGGS0Oz53bqD3fOzu7VyBCJDpOl
+        p/zFuRsdT0iNUS3lWPbGpGav6jZpnpiw7OXEbd1ZsDXD5AnNNC2SMyzqT1nO
+        VDadJqmTe0KTXMukQ4gwBIcM03CGGRq9+JmLIoq6CPahnqF9T5ZDUBhq1rV0
+        VmdQd9qk1KxlHW0hrRdSk/Zw7c9SvgYms7ngp620kdool4bJIn/k/yX/XFbq
+        NZfUPbrOV0AwI3XDaGJoXbWctGEmbq+vJQzT0W1TSyeSpmNTgo0UD6GFMpNa
+        0VOrboanNVtb00mQocOLtq2RGWFkWebwMI5EEMPRctVRjDRXHY9FEC+f92Kd
+        EI4z9FecNoZD28uhbVFf0rJph+GV/0VZJCta9SWV0swdO5tysraWvvhCVksb
+        zkbOLMPpzjJmfLBE0YHOCAI4GcVBNIpeN62R4vgnDO6IJdG7F/MFDYKa9Cnq
+        SszkC7Rr7yoh9DFUdeY2ioEI+nGaYX9xRJNaRgTUs2ckpEAYbg2Ne8Qz955i
+        JMtDs+ODs3MySv+lUKoUwociOCsii2ZsazGbykXGsFR+BeZHitb4UtZM5Xbs
+        Ubc3UK4e84X4zzJbVqX+hnr8/U0XhTeTsjLuntWTN5mybCvrGKbOEyMWqZhZ
+        Wd9DBYGr9DIhhW4PsLvGmS+/dn+5Efksaovk2sq9D2mrdMXCbs7sMM7T63ev
+        Z4u24lS39YfwkQhGxHbYWj6KEC5SnYiXqqGl53KvwepVfaOfIb5bJTDc2VtF
+        vR819u+Kauz/ruoesTAGQpiIYFIUhsjyAMOyRwpvvC8Z+5d/xip3+IFPkKCX
+        h3HlkVN1OoTZCK6KVB3w4Id2imXdcVfs85270e9PsK0vpek5MU60ZXTbEWdT
+        D28Zn+ztRke35KMC90NdRDIpicO+s2Lw4TBu5LZFOR3GTYaDnR4Yo7iGW/sw
+        iucZ6tqMtqW2LYJYkg7ybcJc0WB895oNCRWyzxDz54vQ8YLRlTKMbDuvVZIR
+        r7sOw4sVp2Tn+b7CxIgLJB2eVlC3Dyewmid6K3yX5K2Bjj0fX1vIo27rpngT
+        lZ5fpx79vOh1BWIY8NW74ociBLrFhJNTM7MXpkborXnG37evDSpSB9lacKwz
+        vGHSaz+ekgeB+IJOPe7EHStuWmaPnHI2Mno876TXddLrOun1CzBuLe2u5G45
+        vb6c07K7QyeD4stcFJ/I3cw+yZCokPcQXqL7Vpn15n1zCeEVuryUW6feepLn
+        T9fiLj7D8PoHgGe/qxnR/DkGxdTXdVvO5Cve/7w/VSIbwhcYuv05KpWX3Hyp
+        Fl/Elxle/QBwUxo8cfJVupblN6JJ3dEWNUejVRtYW68CwMRfrfgDbe2rohOg
+        yTuG6NENL7DYzwL/2Lz7XGTzbiTQHIgEwtWyLTxWeT0GwvRTxKDoNBf9lMCW
+        oLKf2mD+OXaMFGJhtVoNjAX62PHq8OZdJTAQVKpiNDAWevfNYECpjh1UagpC
+        QVdoLBSLK6FYvRyulf+RvnBuspYapkRIpF/ZV9CMlpgfqA8HlLrCdL3rriGm
+        KsrWqKsUW1T2FwbVLUsHpKWwcjBW3cz6Gql3yO31KE2xk2GmRtS8Wku+33e4
+        L6YGVSnX1yy8ho+43o/Gru/N0aOZb42tlDN/SHksFlXDZDanHD/+XpwdIyaP
+        72RSVU7sHDyjtAkE7mNXASFF3O5GHFEejwVVqpq+jrF370Wki87YkHIyRiBK
+        FaPeioXSyhvoEvU+UPZFW/J1mM0ynKrse02Z7cXjawgbpx8dUCA+qbqruPja
+        WMb5jrP7YNFF1OfgTiKteZGLdxzd5DSY9ze7IW0o22D2rjp0Qh+xFumA0jBB
+        Bqeyawu6PSuOIwKzlRKXYdsQz+5g7YyxbGq0g1P/8JUc2qS5bnCDpi9s3eXp
+        ol86W/gIuk2sjpCkVokw10E0aZq6PZLWONdpOjJjZe2UPmqIuRbX5NwOd+hH
+        ANViJ0QdWlCDIKrwK3p6klrKAKIPsW++6200bGL/fbFR4tf0H5RzKn4jJHJy
+        9HSA2t9KmRB+R6345BcWWy39WsQ3QPIkbI+S7YDQ71abH6D1IeLCw7FNnNju
+        IYhW6eFQTtr1IHpNaKP5nK9DO3z9XrQBubvTo1KLdjxOfeH6rBuucqTm5dcQ
+        eoCuia7uBziVc/wW/VPYEYmgHuJ1cJhQHCXrhymCHvS67MQlIiD8EP3zb+PM
+        felsi5ljLraEBw9PSG5LrJwlK+dKrbS7Vp7ysDKIIZfNabImkKqn1AuSzRHB
+        5jObGC1ls1eyGc9J41KBzTHq5fJ5HknSyHn9cMHrcBGvDfIFiqfz7Eooz7pQ
+        rpNpwa7a40KZFFCmPKCck1C6ctKeUC5TL1AAVeWCGvcE1VhdBGo7tGkX2pzL
+        UnO3OkPQ8lxdFQDndgCM4mIRV80FgM24go9JgM3buPpoOa5qiwBdw7yb/Jtu
+        JTZ2qR+XgJ6j/6rhrnegMWxHU4+pAl31tLYWkJK4GrEIXeJqxJJLXCMZXi7g
+        ui5xHKgqoCgmZwWGi2WNRGuobdqG5cnqrp53kA7gzwU0IsIGXKU1NycRnSG1
+        BqrKNUIkgmmCCUsiaioganIRiZ5YwflU3s6nbic2gS6DThdduwyWNqi/4MV5
+        deMBPrWJl0vXyi3X6gsyE8FCkB1eZj47r37e28yKj5l7Xma+Mq9+zdtMxtNM
+        Ff5A/zFqR9wgJ932qtv+UWr9En+i9i3S+jrx+40bqErim0l8K4lv4ztJvIrv
+        JvE9fP8GGMcP8NoNdHPUcPyQ40ccKkeQo4fjdY4nON7g+DHHTzgOclgcTRxt
+        HI0c9zgGOXSOSxxjHD/luMxxnuNnHG9y/FyO/ILjWY4hjivycZojw9HBcY1j
+        ieMmxzLHPMcKh/FftSsUaNEeAAA=
+        """,
+        """
+        androidx/compose/runtime/SnapshotStateList.class:
+        H4sIAAAAAAAA/41QTUsjQRSs7smHGaMZdd2Nun7gSYM4KsKCK8IqCIFRYRNy
+        yamTabRN0i3THfE4v2X/wZ4WPCyDR3/Usm+iF3cvXuq9qi7ee9XPfx5/AzjE
+        BkND6DgxKn4I+2Z0Z6wMk7F2aiTDlhZ39sa4lhNORsq6MhjD1nH7KLoV9yIc
+        Cn0dXvVuZd99PflfYgj+1cooMJSOlVbuhMHb2u5UUULZRxFTDAV3oyzDTvT+
+        i2jJXDQwbqh0eCGdiIUTpPHRvUf5WA6VHMDABqQ/qJztURfvU5Qsrfq8zv0s
+        9XlAkKX1LG0UprI0YAd8j58Wn36UeODl/gMa0Wb5pODNGbsDR6efmVgy1CKl
+        5eV41JNJW/SGpMxHpi+GHZGonL+KlZa61sKNE+r9lhknfXmu8oel7y9BO8oq
+        cn7T2tAKZbTFPjj90muU/NMIl4mFEw4UG79Q+UkNxwphaSJu4jNh9cUAH9NU
+        PaxOXB7WJnUJ61S/kKdKnpkuvCZmm6g1EWCOWsw3sYAPXTCLRXzsomAxbfHJ
+        om5R/gvbVDsvSgIAAA==
+        """,
+        """
+        androidx/compose/runtime/SnapshotStateMap.class:
+        H4sIAAAAAAAA/41QyW4TQRB91eN1YpJJ2Bx2LogEiUkiTsGKBEhIViYgYTQX
+        n9qeVtKx3W1Nt6Mc51v4A05IHNAox3wUosbJheXAoV5VvX5d2+XP7z8AvMJT
+        wpY0WW51dh6P7WxunYrzhfF6puKBkXN3Yv3AS6+O5LwJIvR6h/vJqTyT8VSa
+        4/jj6FSN/ev0H9zB3xQh+pNrokZo9LTR/oAQPN9KO2igGaKOFqHmT7QjvEj+
+        e0jusZ5MrJ9qEx8pLzPpJXNidhbwxlRBuwIQaML8ua6yHY6yXUJcFquh6IpQ
+        tNiisgjLolsW27VWWUTEjiKxJ3aCt/WLLw0R1apve1zpkC2lqmj020AvJ56X
+        eGczRVhLtFEfFrORyj/L0ZSZjcSO5TSVua7ya7I90MdG+kXOcTiwi3ys3uvq
+        YfPT1cqpdpqVb4yx3EJb47ALwfe63qo6H+N9zuJlDtS3v6H9lQOBB4yNJfkM
+        Dxk7VwKEWGEf4NFSFeDx0t/DE/b7rOmw5sYQQR+rfaz1EWGdQ2z0cRO3hiCH
+        27gzRN1hxeGuQ9dh06H5C310h9RqAgAA
+        """,
+        """
+        androidx/compose/runtime/State.class:
+        H4sIAAAAAAAA/31QPU8bQRB9c18+XwKciQHjIERpp8g5KEWUGKQ0SJYcRcIW
+        iuRqsRez+LyHvGuL8n5LivyIFNGJMj8qYs6kShDNvHlvdmbfzO8/P38BeI8D
+        wqHQk0WmJnfJOJvfZkYmi6W2ai6TgRVWVkCEVnf4sX8jViJJhZ4mXy9v5Nh+
+        Ov1fIsT/ahV4hHAq7YVIl5JQb7Wf6vNb7eGQsdafZTZVOvkirZgIK1hz5iuX
+        7VIZqmUAgWas36mSdTibvCN0i3wzchpOVOSRE5chdMOrRpG/CcIij+mIjp2O
+        c74du03nQ5F/u//h3X8PgqYXerFfzjgmHPWfPwe7oSGVBvzV4z7xQItbc53Z
+        df3tzBKqAzXVwi4XXI4G2XIxlmcqZbJ//jjrQhl1mcrPWmfcpDJtAv4fPta7
+        8b0C8N2xz8xBCPdv5qK5xgZeM57wiyr3RCO4Pbzo4WUPG9jkFFs9xKiNQAbb
+        eDVCYFA32DHYNdgzJa08ADaVmL0DAgAA
+        """,
+        """
+        androidx/compose/runtime/StructuralEqualityPolicy.class:
+        H4sIAAAAAAAA/5VVW08bRxT+ZteX9WLAcVJqCE2ThjbmljWkdygtIVQxciiq
+        I6qWp7E9dcasd53dWStRX1B/Sp/70KgPiVqpQu1bflTVM7suIQYikOU5Z845
+        c+Y7t9mX//7xF4APscmwxL1W4MvWE6fpd3t+KJwg8pTsCqeugqipooC7m48j
+        7kr1dMd3ZfNpFozhu1qH97njcq/tfNPoiKZaqZ3tyeO98JGvHkSKK+l7iZ/V
+        ky7WVhgKw9IsUgzOBZ1nkWHIrEpPqjUGszy7m4eFnI00bIaUeiRDhjtvgHxG
+        8ATQFo8j2eeu8BTDrfIpiTghmf2BYabmB22nI1Qj4NILKSDPTxCHznbkurzh
+        CvJ+bd9XrvScTr/rSE+JwOOuU/VUQGdkM8ziEoPFAxHDyuMyxm0UcYWBcYbi
+        yatJ0aATyq9rF22GK+XZY1aJlKxuvgmerzRCsiqdlRcL0wzprgjagmHrXEk5
+        JU2nwV+9YOVn7okfeeSqarfnUrquM/xUvmhrngvtufDncQ3v2biBm1SEXiD6
+        0o+o87LNKAjiBsryXs+VokXq1aYb96sNQzepVd2uP1zf3tjMYw6jORLOM1yq
+        DfrjgVC8xRWnDBndvknjzPSS0wuo6PskfyL1rkJca4lBHB5M20bJSP6FwwPb
+        sDQzQtQkOmb987NROjxYtouZYqrEKkaF3c1axt+/ZIyCuTVdSE0ZlfSyVchM
+        xVrisgl3f2LLKlikzd2f0Jct07Ny4ZQzDTt/vHj0FvxvWydTcXuf8nX128RN
+        1evLUNLMrL9qVBrsDb9FDThek57YjroNETzUc6Unw29yd5cHUu8HwplhXzs8
+        4F1BQ/ea03zV80Sw4fIwFLTN1WXb4zQD5MGu+1HQFF9L7W5y4G73BDBUqHpp
+        io/eTkzqchJdpdpkiF4lmiY9PU+0+4J2ji6gls49x8gzYgysDYyBDr6kNZ8Y
+        EB2N6z2GcbLSh+8R1WXPzC+8wFu/Dp3ej09fTywGpzU3gbdjfQYl4gx8Rfyo
+        QaJC7D5ZJzE1uGRxgNAsvvPb0A3uMXzm4IbjodITh3dJo93sIEU/wJqbX1h8
+        gZlhX0msc4nNEVoL7w/QWvggRqu5W8SZRzdpwDqGy+ZQDIXYuHyU6+Q4MPIn
+        jO+fY/Z3LDyLBSms02qT2Q0q2+cU/N0YnYmNmK5QpoEq6RepDrf3YFbhVFGp
+        YgnLxOJOlb6wH+2BhfgYn+zBDjEa4tMQn4XIhRiLmYkQpRCTxP8H9SluIpUH
+        AAA=
+        """
     )
 
     val Effects: TestFile = bytecodeStub(
         filename = "Effects.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0xb63b1aec,
+        checksum = 0xade9931f,
         """
             package androidx.compose.runtime
 
@@ -1129,156 +1127,155 @@
             }
         """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMuSSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeJ0TUtLTS4p9i4R4gpKzU3NTUot8i7h4uNiKUktLhFiCwGS3iVK
-                DFoMAHVSFrpbAAAA
-                """,
-                """
-                androidx/compose/runtime/DisposableEffectImpl.class:
-                H4sIAAAAAAAA/51TS08UQRD+enbZx4iyLPJGQEFZQJgFvS0hUYRkkxUNS4gJ
-                p2a2gV5me8h0L8Eb0Yu/w3/gwWg8GMLRH2Ws3ocgxgAmM9VV1f1VfV1V/ePn
-                t+8AnuIJwxxXlSiUlWPPD2uHoRZeVFdG1oT3Qmqy+U4gVnd3hW+KtcMgCcaQ
-                qfIj7gVc7Xmvdqq0k0SMIbEklTTLDBO50kFoAqm86lHN260r38hQaW+tpS0U
-                prcYPlx1ammudG1qZT88FIXZ6wM2hK4HprDcoDJRCqM9ryrMTsQlUeBKhYY3
-                6ayHZr0eBAW6n2ggU0gzjF6gLpURkeKBV1QmIrj0dRK3GHr9feEftPCvecRr
-                gg4yTOVKl+tXuOAp2yB7xKsTt3HHRSe6GGI5a3eg20UcWYbxqyrciTTupuGg
-                lyFu9qVm8K5fHdtpuvH7qzp00wb9R38YutssXgrDK9xw8jm1oxgNMLMiZQUY
-                2AH5j6W18qRVFhii05MR1xlwXCdzeuLS19Av/KcnKWfg9GTRybPno9n+jDPU
-                k41nnXy8ITvysbOPCSeVsDKT3Bj71/6bs3dxq1E8m3mRWT7ZNu/zrjDkb1oy
-                hoUbV43ms5179dgIGslQtUlsvm0EdZsAPX9gGNJluae4qUeCYXijGbuojqSW
-                FPnZ+WOgUVoJK3SoqySVWK/XdkS0abPby4Y+D7Z4JK3dck5ejvX7FfwR1C2H
-                9cgXa9JiBluYrb+yI0/jHG+0Omunm6xZshwM4jGtCfKnmoNADyWBGObIKtG+
-                Q2tmNut+RWbmC3pmZj+j71MDOU/yDp1MUAwXQ+ii1SNfXxODfgzY2SLN5mOt
-                fEliAiRZK6GDhYacwSKtK+QdIgLD24gVMVLEvSJGMUYqxou4jwfbYBoTmNxG
-                SmNA46FGWuORxpRGTmNaI/ELZm5MUZ8FAAA=
-                """,
-                """
-                androidx/compose/runtime/DisposableEffectResult.class:
-                H4sIAAAAAAAA/5VPzU4CMRicrwvsuiou/qIPQPTiAjHx4MlEjWswJphw4VTY
-                YgrL1tBCOPJcHgxnH8r4LTyBSTOd+X4605/fr28ANzgjxDJPZ0any3hopp/G
-                qng2z52eqvhBW9ZykKnH0UgNXVfZeeZ8ECEay4WMM5l/xG+DMfd8eAQ/3Wwo
-                gnd51SPUOhPjMp3Hr8rJVDp5RxDThcfWVEBQAAg04fpSF6rJLG0RGutVNRR1
-                EYpovQr5iEgEo/p61RZNegkicSGa3nOjmG4TWp1/foKDsG+4LdnriWPxbuaz
-                oXrSGec/727Xe9pqXr3Pc+Ok0ya3FbZECZvgJUIZFWYCJxs8xinft/y0z52g
-                Dy/BToIwwS72mGI/QRUHfZBFhFofJYtDiyOLMuMfURqWxJYBAAA=
-                """,
-                """
-                androidx/compose/runtime/DisposableEffectScope$onDispose$1.class:
-                H4sIAAAAAAAA/8VUXVPTQBQ9mxZaQoHwIQIqVkFtA5Km4hcwzDBYxmpRh2p9
-                4CltQ1mabpgk7fDk9CfpjI6jD06f/VGON0mRjjry8eJD9t69e/bs3bP35vuP
-                r98ALGOVYcUQVcfm1SOtYjcObdfUnKbweMPUnnCX5kbZMnN7e2bFK1bsQ3Pe
-                FmHcnNdjYAzKgdEyNMsQNe1l+YBgMUQYtDOz7phu06JNfQz9a1xwb51hLlWo
-                257FhXbQamh7TVHxuC1cbavrZVbTJYbsaai14/U3RLu6HmxSTi4Qns+QPO2w
-                BGQMDkBCgiGSSpcSiGFYRhQjDFFvn7sMa4WLy0iPEKuGE4bZf+cSwwTpxEXL
-                rhN4IpUu/C4/ZTuJy4O4hCl6hnMqxDB6HNk2PaNqeAbFpEYrQuXC/CHuD2Bg
-                dYofcX/2nryqzpDqtEfkTluWpqTAKJLKOu24PNVpZ6UMexZXpBkpE3k66eOz
-                DPrZNQuLhFKhk5fOp3QMKYaBX3IzFE8vrnMnloCKBQY5DLpLdSortfcYLjzT
-                EYalFe2mUzGfmOVmLXfkmcKlE+lefS3DalJy74rbG696aOTnAYesFpPH3pa8
-                kNSTPZCLV56sFmR9Tl/U9eUVmuRkUqrIa8Lwmg4lE920q2RGClyYL5qNsum8
-                9skYxgp2xbBKhsP9eTeYyAthOpuW4bomdcRITlQs2+WiRpW0b1dJnfDuW9xH
-                T/xNCIbpnTD3Enc5sW4IYXtG8D4MV7predH6YxU6tWeUqqMfTFH8fiVfp+KU
-                MEMfdRjiZLMUWScrkZXVhU8YUj9D+RDg7tFIu9GHYfozgrooQGEUY37Jk9fL
-                OkDeOCFZwPnY7wiyg+pHDH3BNMPbE1I5IFICKp84EUK7xP24H2BYgAKm8YDG
-                KNJYxMOA4y4ekf3PlUFXBOVDr0ACXd1FJI9reczmcR1JcnEjj5uY2wVzMY9b
-                u4i6vnvbxbiLO1ihzb5WS/RpASjzE1u+Yp2EBgAA
-                """,
-                """
-                androidx/compose/runtime/DisposableEffectScope.class:
-                H4sIAAAAAAAA/51UW2/TSBT+xrnYNaVJw603CgsBWgq1E9gLpCBBF7RBoSAC
-                lVCfJs60TOuMkcep+ljxsP9hX/cX7D4VLdIqKm/8KMQZJy3d7kMpljzn/p05
-                c87Mp8///AvgNu4wzHPVjiPZ3vKCqPM20sKLuyqRHeH9KjXJvBWKR6urIkia
-                QfRW2GAMxXW+yb2QqzXvWWudTDYyDPkFqWRynyEzM7s8jBzyLrKwGbLJG6kZ
-                /MbxUtUYhiLVNwmG5kxjI0pCqbz1zY632lVBIiOlvccDzq/NfnuCF0J3w4Qy
-                tI5CXdizv6Liave/K8nlRhSveesiacVcEjhXKkp4P9FSlCx1w5C8CvvF9sMd
-                FBimD+xOqkTEiodeXSUx4chA2xhlOBO8EcHGAOg5j3lHkCPDtZnG4UbVDmia
-                BmStZnp1CqddlHCG4e7xelTe33O5YuMclXp0l9LZGHcxhgkG75inaWOKYaQs
-                y6vlA7PB6gwXj0rMMLrn8lQkvM0TTjqrs5mhu8DM4pgFBLdB+i1pJJ+4doVh
-                pbc94VpjlmsVe9uu5VipYNhUZ431tquWzx7mdv/Mk/hkqpiZsPxsdcTJFnMT
-                Tilbsnzbz/+2+7vz8T3rbe++s2w35+z+UfWZSVFlJnHlO4artFfUwUrdvpOe
-                30jo/i1GbTqkQkMqsdTttET80uCY0Cjg4TKPpZEHyqGmXFM86cbET77oZ6+r
-                TaklmR98nVyG8mHr/uz9x224rpSIF0OutSDRbUbdOBCPpUk2PoBY/h88KrDo
-                +TCfRSdDrwmtPkmeaRDR3PUdOH+n5gqt+VR5AlVah/sOGIJLdJS0wwRlgpeR
-                gWnr6blS8T3OZu59wNjruR1M9nD+r30sl6iDEboWpRTvIsU4hDGNC2Sh6AGy
-                4QpkZbiVxp6kJ7W/kxGiP9Jvs4GQwU8pMKOxN984fk5DPPxCdJH0P9CGL60g
-                U8flOsp1XMFVYnGtjhnMroBpXMfcChwNV+OGRl7jhMZNjYLGPGm+AB149ZDV
-                BQAA
-                """,
-                """
-                androidx/compose/runtime/EffectsKt.class:
-                H4sIAAAAAAAA/+1Y21Mb1xn/Vhe0LALL4q6kjmJIA8JYWnExWBjH5hKrljGV
-                bKhL63QRC16QdhXtSgYnbdxmOtOX/APpQ2f63Je8JG4z43qat/5Rnf7O0UpI
-                aAHBOEwfyoz2fHvOd/l9t3P28O///OM1EU3S7wW6quhbRUPb2o9mjXzBMNVo
-                saRbWl6NLm1vq1nLvG/5SBAosKuUlWhO0XeiDzd3seAjt0BSRttSK4wCDY2k
-                9gwrp+nR3XI+ul3Ss5Zm6GZ02aZiidE1geKncc1V1x/rmpWY50IfpI6FucDf
-                lc2cmgCElFHcie6q1mZR0aBU0XXDUioGVgxrpZTLgatN5YhFkgS6UgdG0y21
-                qCu5aFK3ihDXsqaP/AL1Zp+p2T1bflUpKnkVjAJ9OJI6GpVE3UyGKdkBfj91
-                0SWJOinQaM/BeR8FgU/Ty8aeKlDPyGizBT/1UG8HdVOfQOHTIo7ELWqmHaBW
-                EyXzmP/pNK658eOzctRoJmsU1MRY6wJp1SzlqunvriJZVAtFNatY6hY88+VV
-                01R2EKeB1aJRRiWGFSucUxXTChu6Gt5TDwTy5tSymhNo8KgKeJBiS1DkXUqn
-                H6YFeu8w1slcTt1RchkUj7q0n1ULjN9HV6HoOFvXRRoWSLSMSt6PZs+uBj/9
-                lD6UyEMjyPOchhKfR4GNOJdNhMYkGqJrpyZahhdTTtXYQp6/PrvcxWV++KSG
-                RjfafT/esvZkvpDzUZzFNiTRBE0KNDasDSvD40U1r+Y31eJ4beMbPio8LAsk
-                JAXqhMT2cFVAIA/Sj6VgcyAF+vjkTeIMifrb29B0cak7Q1jjlRBieNKaj+eK
-                3+sfR/f/ZEQnKhHFMD2ycb5w/fkcghcXC+adKdJS9cukZGm56J1iUTnAmf0x
-                9lZoP3i4LdCokxvJUYdJPyXpZxLdo/tnCjV2kHZNL5Qsc1gr46xy0CxQV0pB
-                jJ6pW9UzWGvhdLUZskbRgHu6auJjB6HRS3wDPGSwP5TGmg1XYuXdzBnZPZHS
-                Il0R6LNz7fdvC8vYselujFBln16TaJ1t0aPHpqNRim3QX72lbfJtedwydmx/
-                f/nRtqgL9wZbz+fn20EuHCoK7HJV6QPVUrYUS0HPuvJlN65JAnuI7EE4/fcY
-                4cLivsaoGKgtWXD98ObltPTmpeQKuPgw4Gr48RX2EN0gLldGtiZ62Rh6H4sh
-                V0yI9wdcoe6gJ+iKefjTG3P/669tLrHtni80VmUSA76QZ0CIiSeyTzWzi4H2
-                FgRvnyQoBqQWVMxXVfQFOkL+oCgKQS4U8189VZiNgc5QKtDVAoh3A5dCA9Au
-                BUWuR4gFgm22Lfc93w+vhDcvucLLobsnKGxZTTA006SmZeHu0LItfFxYWlbV
-                Gbpuq2pZpCfUF+jlIn4Ev8rch4D/weVBJQ6yUsYeROxD1u6G+vtF7KxHu0Dy
-                mQ93XJCrtpf2LRV3cEOvgnh0wJWGT9kgEg742UVYsvv/+h6O30j9NlS792eM
-                UjGrLqqbpZ2adXY/LCu5kioIZubBndU6NdJ9rkOKZMJValkaC8vhOpbT/70C
-                iXg4bW9SJ4pUmSATSUnykHxNlidvypI8MRS/KctTUjzGiWkpPsOJG9LEJCdm
-                qjyzNk88ZvPEZZsnHj/0g0fgfM4A2GRsSOZwJmc5MS1NVYgb0vQNTsxIM1Oc
-                mJVmJxkBOHKsQsEdOc4pAFqS8KW3YGzhjn8phUyvlJj/j1jZsCwbWSW3phQ1
-                9m5Ptme0HV2xSkXQ76Qr8JJ6WTM1LN85vD3ianl0tfafnQY26fB/Drj82zJr
-                DvqkSvUsawxGj1MpkUwu3PzZXwcNkpfa8PYcb3OYR+NRVyTY8YouR/5O/QKt
-                f8NOGtrHU8LYRiJ1Ujsd4N1f4cb8AMYXnM9Hn2Fsw4qI8XP8fDiuIEAwNUgh
-                LDFTt8jNhbsrpr6noSfBD76l0e9o/J81e0yLRO/X2erG+/WarXfot9yL3+EX
-                xPq7mPuJSVfoPZXCkDsRSdR2Og8kLBi9YxyJ+5Z7/nuaeDL2HU3V+97H4zQC
-                XSYwjMCeST00yrFFoEDCyjTdgDIRUZ0B5WJKaZZucoy9HLlgI481YetkoZf5
-                4V5FmLAR7kOpl0G4VkE47572MIjXHCHKUGkBgoxgWTAb5xAnsdaBlVsA5sHo
-                5xDdXKoKsY/mQQmcYmBdNti5JrDd7hrYRsi3bchfQnUbxv7xCuRpj3vayzCP
-                O2JOQEEJmBIIaQlzcxzzPFb8sHkHSL3gqGBmueqvYe6vYe6nu6BcnGLo3Tb6
-                j5rQD3qOoG/0YcH24Y922IciwWX4UCmPSOT1K0o9qOXAqUz8UNFLZTTFAsqw
-                TFdpsZaDAaB4wL3oreWgGy20Qg859iFaAkWcqi+YReeCaa9DvurUXJlqcz1y
-                bq6VhuZK1zXXz8/fXKtOzZWpNdc6i9ovmqvgMXQ9B6bHsPcclbDW0FxPTmyu
-                dF2sHp/eXKtOzZU5bK511lwOEJ9C5T4gPEWw9mH2k4bm2mixudJ1zfXLVptr
-                1am5MnXNtc6aywHzM75b+zH2YOwjraG5fn3m5krXNdevztZcq8c3V6apuZzL
-                xE8FxP0FGqmAMnyB5vq0obk+abG56gvm6WnN5aEvOKNJLzH1/++vi//+4ttQ
-                Aen4DfKsbJA7SZtJyiZpi9QkbdNOEvWtbSA5tEt7G9Rv0qBJOZzVJuVN0k0y
-                TCqYNMsn5026a9ISpxdMWjUpbdKnJt02KWFS1KSQSV6TirwuumDVwq/EtZf/
-                C7XJpgW2HAAA
-                """,
-                """
-                androidx/compose/runtime/LaunchedEffectImpl.class:
-                H4sIAAAAAAAA/5VSW08TURD+znbZbleUsgKWi4iCUKiwhfhWQqJETJOKBpSY
-                8HS6Xcppt2fJXhoeG179F/4DH4zEB9Pgmz/KONuLIKiEZPfM5Xwz852Z+fHz
-                6zcAT7HKkOOy4nuicmzZXuPICxzLj2QoGo5V4pG0D53Ki4MDxw6LjSM3CcaQ
-                rvEmt1wuq9brco1ukkgwaOtCinCDYTZbqnuhK6RVazasA0oRCk8G1lZPWy0s
-                7jGI61Dry32A7fleFArpBNamR8xkxGPEOeAdFS5sFHKly8TIGdeaLXl+1ao5
-                YdnngmpwKb2Qd+tte+F25LoFBjXkQV1HimH6AjMhQ8eX3LWKMvQpWNhBErcY
-                Rqkxdr0X/Yb7vOEQkGEhe5XFBc9unKRKrAZxG3cMDGKIIZGN7QEMG1BhMsxc
-                18BBpDCSgoLRmPahCBiWSzcYI722cl37b9r9vzWfYbiPeuWEvMJDTj6l0UzQ
-                8rH40OMDDKxO/mMRW3nSKrSXH9qtCUPJKIaSbrcM+jp6x6ZfV/R2K9NurSl5
-                9nzenEorExmdmYapm6qp5AfyqqmZaoblWT7x/ZS1W2cfNSWt7Sz+D/j+7ETt
-                g1Wqkzw7UUjq4zGlNRYTNfsPOp/GhYH9o1kEMbrdD1bqIUNqV1QlDyPfYZjc
-                6Y6pKJsiEGXXeXa+nTTdTa9CoKES5dyOGmXHf8sJE/PwbO7ucV/Eds85dznX
-                78X8I6mx60W+7WyJOGa8F7N3pTpWacPUznjMeOHIWiRLwTiWSGrk17vDo93V
-                kECOrBLdKyTTOdM4RXrpC+4u5T5j7FMn8gmddwipYQsGXmKI5DL5xroxuIdM
-                vA+kxfVYr14SKySTrFdQgdU5s8iT3CTvBBGY3EeiiKki7hcxjQekYqaIh3i0
-                DxZgFnP70ANkAjwOkAowH2Cho2sBRn4Bxaa1HQ8FAAA=
-                """
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgMuSSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFeJ0TUtLTS4p9i4R4gpKzU3NTUot8i7h4uNiKUktLhFiCwGS3iVK
+        DFoMAGDKMaZbAAAA
+        """,
+        """
+        androidx/compose/runtime/DisposableEffectImpl.class:
+        H4sIAAAAAAAA/51TS08UQRD+enbZx4iyLPJGQEFZQJgFvS0hUYRkkxUNS4gJ
+        p2a2gV5me8h0L8Eb0Yu/w3/gwWg8GMLRH2Ws3ocgxgAmM9VV1f1VfV1V/ePn
+        t+8AnuIJwxxXlSiUlWPPD2uHoRZeVFdG1oT3Qmqy+U4gVnd3hW+KtcMgCcaQ
+        qfIj7gVc7Xmvdqq0k0SMIbEklTTLDBO50kFoAqm86lHN260r38hQaW+tpS0U
+        prcYPlx1ammudG1qZT88FIXZ6wM2hK4HprDcoDJRCqM9ryrMTsQlUeBKhYY3
+        6ayHZr0eBAW6n2ggU0gzjF6gLpURkeKBV1QmIrj0dRK3GHr9feEftPCvecRr
+        gg4yTOVKl+tXuOAp2yB7xKsTt3HHRSe6GGI5a3eg20UcWYbxqyrciTTupuGg
+        lyFu9qVm8K5fHdtpuvH7qzp00wb9R38YutssXgrDK9xw8jm1oxgNMLMibQUY
+        2AH5j6W18qRVFhii05MR1xlwXCdzeuLS19Av/KcnKWfg9GTRybPno9n+jDPU
+        k41nnXy8ITvysbOPCSeVsDKT3Bj71/6bs3dxq1E8m3mRWT7ZNu/zrjDkb1oy
+        hoUbV43ms5179dgIGslQtUlsvm0EdZsAPX9gGNJluae4qUeCYXijGbuojqSW
+        FPnZ+WOgUVoJK3SoqySVWK/XdkS0abPby4Y+D7Z4JK3dck5ejvX7FfwR1C2H
+        9cgXa9JiBluYrb+yI0/jHG+0Omunm6xZshwM4jGtCfKnmoNADyWBGObIKtG+
+        Q2tmNut+RWbmC3pmZj+j71MDOU/yDp1MUAwXQ+ii1SNfXxODfgzY2SLN5mOt
+        fEliAiRZK6GDhYacwSKtK+QdIgLD24gVMVLEvSJGMUYqxou4jwfbYBoTmNxG
+        SmNA46FGWuORxpRGTmNaI/EL6pV/cp8FAAA=
+        """,
+        """
+        androidx/compose/runtime/DisposableEffectResult.class:
+        H4sIAAAAAAAA/5VPzU4CMRicrwssrIqLv+gDEL24QEw8eDJR4xqMCSZcOBW2
+        mMKyJbQQjjyXB8PZhzJ+C09g0kxnvp/O9Of36xvALc4JkcySudHJKhqa6cxY
+        Fc0XmdNTFT1qy1oOUvU0Gqmh6yq7SJ0PIoRjuZRRKrPP6H0w5p4Pj+An2w1F
+        8K6ue4RaZ2JcqrPoTTmZSCfvCWK69NiacqjkAAJNuL7SuWoyS1qExmZdDURd
+        BCLcrAM+IhTlUX2zbosmvZZDcSma3ksjn24TWp1/foKDsG+wK9mbiWPxYRbz
+        oXrWKee/6O7We9pqXn3IMuOk0yazJbZEAdvgBUIRJWYCp1s8wRnfd/y0z51y
+        H16MSowgxh72meIgRhWHfZBFiFofBYsji2OLIuMfte9Y6pYBAAA=
+        """,
+        """
+        androidx/compose/runtime/DisposableEffectScope$onDispose$1.class:
+        H4sIAAAAAAAA/8VUXVPTQBQ9mxZKQ4HwIQIqVkFtA5Km4hcwzDBYxmpRh2p9
+        4CltQ1mabpgk7fDk9CfpjI6jD06f/VGON0mRjjry8eJD9t69e/bs3bP35vuP
+        r98ALGOVYcUQVcfm1SOtYjcObdfUnKbweMPUnnCX5kbZMnN7e2bFK1bsQ3Pe
+        FmHcnNdjYAzKgdEyNMsQNe1l+YBgMUQYtDOz7phu06JNfQz9a1xwb51hLlWo
+        257FhXbQamh7TVHxuC1cbavrZVbTJYbsaai14/U3RLu6HmxSTi4Qns+QPO2w
+        BGQMxiEhwRBJpUsJxDAsI4oRhqi3z12GtcLFZaRHiFXDCcPsv3OJYYJ04qJl
+        1wk8kUoXfpefsp3E5UFcwhQ9wzkVYhg9jmybnlE1PINiUqMVoXJh/hD3BzCw
+        OsWPuD97T15VZ0h12iNypy1LU1JgFEllnfaAPNVpZ6UMezagSDNSJvJ00sdn
+        GfSzaxYWCaVCJy+dT+kYUgzxX3IzFE8vrnMnloCKBQY5DLpLdSortfcYLjzT
+        EYalFe2mUzGfmOVmLXfkmcKlE+lefS3DalJy74rbG696aOTnAYesFpPH3pa8
+        kNSTPZCLV56sFmR9Tl/U9eUVmuRkUqrIa8Lwmg4lE920q2RGClyYL5qNsum8
+        9skYxgp2xbBKhsP9eTeYyAthOpuW4bomdcRITlQs2+WiRpW0b1dJnfDuW9xH
+        T/xNCIbpnTD3Enc5sW4IYXtG8D4MV7predH6YxU6tWeUqqMfTFH8fiVfp+KU
+        MEMfdRgGyGYpsk5WIiurC58wpH6G8iHA3aORdqMPw/RnBHVRgMIoxvySJ6+X
+        NU7eOCFZwPnY7wiyg+pHDH3BNMPbE1I5IFICKp84EUK7xP24H2BYgAKm8YDG
+        KNJYxMOA4y4ekf3PlUFXBOVDr0ACXd1FJI9reczmcR1JcnEjj5uY2wVzMY9b
+        u4i6vnvbxbiLO1ihzb5WS/RpASjzE60KhHSEBgAA
+        """,
+        """
+        androidx/compose/runtime/DisposableEffectScope.class:
+        H4sIAAAAAAAA/51UW2/TSBT+xrnYdbtNGm5tYaFAgJZC7YT7hkXaLVsRFAoi
+        UAn1aeJMy7TOuPI4FY8VD/wHXvkF8AQCCUXljR+12jNOWgo8dIslz7l/Z86c
+        M/P134+fAVzFLYY5rtpxJNsvvCDqbERaeHFXJbIjvLtSk8xbofhnZUUESTOI
+        NoQNxlBc45vcC7la9R621shkI8OQvy2VTO4wZKZnlkaQQ95FFjZDNnkuNYPf
+        OFiqGsNQpPomwdCcbqxHSSiVt7bZ8Va6KkhkpLS3MOD82sz/T/BY6G6YUIbW
+        fqi3d+xPqbjanV9KcrYRxavemkhaMZcEzpWKEt5PtBgli90wJK/CbrH9cAcF
+        hpN7didVImLFQ6+ukphwZKBtjDEcCZ6LYH0A9IjHvCPIkeHCdOPHRtX2aJoG
+        ZLVmenUIh12UcIThj4P1qLy753LFxjEqdf8upbMx4WIckwzeAU/TxgmG0bIs
+        r5T3zAarM0ztl5hhbMflgUh4myecdFZnM0N3gZllyCwguHXSv5BG8olrVxiW
+        e1uTrjVuuVaxt+VajpUKhk111nhvq2r57O/c9ps8ifdPFDOTlp+tjjrZYm7S
+        KWVLlm/7+Xvbr5wvH1hva/ulZbs5Z/t11WcmRZWZxJVfGK7STlF7K3X7Tnpu
+        PaH7Nx+16ZAKDanEYrfTEvETg2NCo4CHSzyWRh4oh5pyVfGkGxN//HE/e11t
+        Si3J/Ne3yWUo/2jdnb3v3EbqSol4PuRaCxLdZtSNA7EgTbKJAcTST/CowKLn
+        w3wWnQy9JrT6JHmmQURzF9/DeZeaK7TmU+UwqrSO9B0wBJfoGGlHCMoELyED
+        09bDs6XiBxzN/PkJ489m3+N4D7+/3cVyiToYpWtRSvGmKMYhjJM4RRaKHiAb
+        rkBWhitp7G/0pPZ3Mkr0Gv02GwgZXE+BGY29+SZwIw3xcJPoPOlP04bPLCNT
+        x9k6ynWcw3licaGOacwsg2lcxOwyHA1X45JGXmNY47JGQWOONP8BWe15VNUF
+        AAA=
+        """,
+        """
+        androidx/compose/runtime/EffectsKt.class:
+        H4sIAAAAAAAA/+1Y3VMb1xU/qw+0LALL4ltJHcWQBoSxtOLDYGFcB3CsGmMq
+        2VCX1ukiFryw2lW0KxmctHGn05m+9B9IHjqT5770pUmbGTfTx/5Rnf7u3ZWQ
+        YAHBOEwfCiPds3vPOfd3Pn539+rf//nHGyKapN8JdF0xtsqmtrWfLJjFkmmp
+        yXLFsLWimlza3lYLtvXQDpEgUGRXqSpJXTF2ko83dzERIr9AUl7bUh1FgYZG
+        lvdMW9eM5G61mNyuGAVbMw0red+VUpnRNYHSZ2nN1eafGpqdmedGHyyfCHOB
+        XyubupoBhGWzvJPcVe3NsqLBqWIYpq04C6yY9kpF16HVpnLEIkkCXWsAoxm2
+        WjYUPZk17DLMtYIVorBAvYUXamHPtV9VykpRhaJAH44sH81KpuFOnjnZAf4w
+        ddEViTop0ryeR/AhigKfZlTNPVWgnpHR4yuEqYd6O6ib+gSKn5VxFG5Rs9wE
+        tVoomef8j2dpzY2fXJWji+YLZknNjLVukFOtil4rf3cNyaJaKqsFxVa3EFmo
+        qFqWsoM8DayWzSo6Ma7YcV1VLDtuGmp8Tz0QKKirVVUXaPCoC0SwzKbgKLiU
+        yz3OCfTeYa6zuq7uKHoezaMu7RfUEtMP0XU4OmmtmyINCyTaplP3o9VzuyFM
+        P6YPJQrQCOo8p6HF59FgI95tk6AxiYboxpmFlhHFlFc3tlDnL89vd3mVHz6N
+        0GCjy/vxlr1niyU9RGmW25hEEzQp0NiwNqwMj5fVolrcVMvj9Y1v+KjxsCyQ
+        kBWoExbbwzUDgQIoP6aixxMp0MenbxLnKNRf3oanyyvdOdKadlKI4VlrMV4o
+        f29+GN//kxmdcDKKYXpk42Lp+uoChpeXCxadJdJS7c2kYmt68l65rBzgmf0x
+        9lZ4P3i8LdCoVxjZUY+bYcrSTyV6QA/PlWrsIO2aUarY1rBWxbPKw7NAXcsK
+        cvRC3ao9g7UWnq6uQsEsmwjPUC287CA1RoVvgIcK7ovS2PGFnVwFN3WzsCdS
+        TqRrAn12of3+bWEZO7HczRly9uk1idbZFj16YjmardgG/ae3tE2+rYhbxo7t
+        788/2BZ16dFg6/n8YjvIpUNFg12tOX2k2sqWYivgrK9Y9eOYJLCvdvZFePrv
+        McGHyX2NSSlIW7Lg+/r719PS968lX8THhwFf04fPsC/RD+GqM7I5McjG2PuY
+        jPlSQro/4ot1RwNRXyrAv4Mp/7++bvOJbQ9CsbGakhgJxQIDQko8VX3quLoY
+        aW/B8O5phmJEasHFfM1FX6QjFo6KohDlRqnw9TON2RjpjGUjXS2AeDdyJTYA
+        71JU5H6EVCTa5q7ld31dRUQn+2rFQxTJPOqhFbvu2IJrd1IeWvHSico7XlrR
+        7on1RXq5dhg5run1PQixTsUWQ+w91W32xuND6rxPboHkcz+7cf6trb20b6s4
+        YptGDcSTA+40fgb/Mx742TlXcul9cw9P10TjLlM/1ufNSrmgLqqblZ366uz4
+        V1X0iioIVv7RvdUGN9JD7kNK5OM16b40FpfjDSpn/3oCi3Q85+5Bp5rUlGCT
+        WJbkIfmGLE/eliV5Yih9W5anpHSKC9NSeoYLt6SJSS7M1HRmXZ10ytVJy65O
+        On0YB8/AxYIBsMnUkMzhTM5yYVqacoRb0vQtLsxIM1NcmJVmJ5kAOHLKkRCO
+        nOYSAC1JeJFbMLdwhL+yjEqvVFj8T1jbsCqbBUVfU8oau3Zvtue1HUOxK2XI
+        7+QceFmjqlkapu8dHg5xcjw6W//hpklNOvxJAWd712bNw5/kdM99jcHo8Wol
+        ksmHgz3766BBClIbrl7iag73QTzqSkQ7vqWrib9Tv0Drf2UPEtrHt4SxjUTq
+        pHY6wHXY0cb9AYyvuF6IPsPYhhkR4+f4gNDIB4RB/McwxZa6Q35u3O0s9R0N
+        PYt+8Dca/YbG/1lfj3mR6P2GtbpxfbO+1jv0Gx7Fb/GJYv5d3PuRRdfoPZXi
+        sDsVSdINuggkLBm9YxyJ/45//juaeDb2DU01xt7H8zQCXxYwjGA9i3polGNL
+        wIGEmWm6BWcisjoDycec0izd5hh7OXLBRZ46hq2TpV7mz+4awoyLcB9OgwzC
+        DQfhvH86wCDe8IQow6UNCDKSZWPZNIc4ibkOzNwBsADGMIfo51Y1iH00D0ng
+        EgPrc8HOHQPb7a+DbYZ814X8e7huw9g/7kCeDvingwzzuCfmDBxUgCmDlFZw
+        b45jnsdMGGveA9IgNBzMrFb9dcz9dcz99BEkH5cYer+L/ifH0A8GjqBvjmHB
+        jeEPbtqHEtH7iMFpj0Tizbe0/KheA682CcNFL1VBigW0YZWu02K9BgNA8YhH
+        0VuvQTcotEKPOfYhWoJEXGpsmEXvhmlvQL7qRa58jVxPvMm10kSuXAO5fnZx
+        cq16kStfJ9c6y9rPj3fBU/h6CUxPsd5LdMJaE7menUquXEOunp5NrlUvcuUP
+        ybXOyOUB8Tlc7gPCcyRrH8t+0kSujRbJlWsg1y9aJdeqF7nyDeRaZ+TywPyC
+        79ZhjD0Y+0hrItevzk2uXAO5fnk+cq2eTK78MXJ5t0mYSsj7KxCphDZ8BXJ9
+        2kSuT1okV2PDPD+LXAH6gita9Bq3/v/+dfnvX3wbKqEcv0adlQ3yZ2kzS4Us
+        bZGapW3ayaK/tQ0Uh3Zpb4P6LRq0SMez2qKiRYZFpkUli2b5zXmLPrJoicsL
+        Fq1alLPoU4vuWpSxKGlRzKKgRWXeF11Y1canwr1X/wvUiR6dlRwAAA==
+        """,
+        """
+        androidx/compose/runtime/LaunchedEffectImpl.class:
+        H4sIAAAAAAAA/5VSW08TURD+znbZtitCWQHLRUSLUKiwhfhWQqJETJOKBpSY
+        8HS6Xcppt2fJXhp8a/wp/gMfjMYHQ3j0RxnntEUQVEKyO7f9Zubbmfnx89t3
+        AE+wylDgshb4onZsO37ryA9dO4hlJFquXeGxdA7d2vODA9eJyq0jLwnGkGnw
+        Nrc9Luv2q2qDviSRYDDWhRTRBkMuX2n6kSek3Wi37AMqEQlfhvZW31otLe4x
+        iOtQ68tnAMcP/DgS0g3tTZ+YyZgrxDngLTUubZQKlcvEKKh65Sp+ULcbblQN
+        uKAeXEo/4r1+2360HXteiUGPeNhMIc0wc4GZkJEbSO7ZZRkFlCycMIlbDGM0
+        GKfZz37NA95yCciwkL/K4kJkVxWpE6tB3MaQiUEMMyTyyh/AiAkdFsPsdQMc
+        RBqjaWgYU7QPRciwXLnBGulva9eN/6bT/9vwGUbOUC/diNd4xCmmtdoJOj6m
+        RFoJMLAmxY+F8opk1egu3590Jk0tq5la5qRj0tO1uz69KS110smedNa0InuW
+        s6Yz2mQ2xSzTSlm6pRUHirplWHqWFVkxcfrR0DLGzvz/MO9OP+iE06l6UhFY
+        Y4qWdUb/fPYX1vOP0RDE7M06XGlGDOldUZc8igOXYWqnt5SybItQVD336fkt
+        0i43/RqBhitUcztuVd3gDSeM4uE73NvjgVB+Pzh3udbvM/yjqLnrx4HjbgmV
+        M9HP2bvSHat0T3p3GZY6L/IWydMwgSXSBsVTvVXRpRpIoEBehb5rpDMFy/yK
+        zNIX3FkqfMb4p27mY5JDhDSwBRMvMEx6mWLjvRzcRVZtnyzVj/X7JbFCOsn6
+        DTXYXZlHkfQmRSeJwNQ+EmVMl3GvjBncJxOzZTzAw32wEDnM7SMVIhviUYh0
+        iPkQC13bCDH6C4u/Nd/9BAAA
+        """
     )
 
     val Dp: TestFile = bytecodeStub(
         filename = "Dp.kt",
         filepath = "androidx/compose/ui/unit",
-        checksum = 0x9e27930c,
+        checksum = 0xe65966ab,
         """
             package androidx.compose.ui.unit
 
@@ -1290,65 +1287,65 @@
             inline val Int.dp: Dp get() = Dp(value = this.toFloat())
         """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAGNgYGBmYGBgBGJ2KM3ApcAlkZiXUpSfmVKhl5yfW5BfnKpX
-                mqlXmpdZIsTiUuBdosSgxQAA2sByTDoAAAA=
-                """,
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/3XNOwvCQBAE4JUExFUQrhARQbERLGIjWIt26QzYyiVZkoN7
+        hMsG/PmeqFV0YZphPhYAIgAYhIzgc3jAhbSld6p8JIUzjWspkVYZycpZMcuU
+        rTTdpO7o9G1Txj2u/qvQeBKT917mmgI44rwHfGdZGRJ4JUMmJ5+ymGZWNm3t
+        OGPJL7jFZQ92Kqm8bGpVtGJ4dtoFiesfH8Kws4pFfGnCYowxU8siuqe8gR08
+        AekscysQAQAA
+        """,
         """
-                androidx/compose/ui/unit/Dp.class:
-                H4sIAAAAAAAAAH1V3VMbVRT/3c3XZlnKkrZA6KektgGkCVihSsG2UFoQWi2I
-                /dDWJdnCQrKbZjdMxyfGF/0L+uCbPnc6OqOUsTMO0jf/IJ8cx3M2NyENkZnk
-                fpx7Pn7nd869+9e/v/8B4BI2BU6YTr7s2vlnmZxbLLmelanYmYpj+5npUgxC
-                4Ob8urlpZgqms5q5s7Ju5fzxBskUGZllc6VgXZk/xNP45LiA0ewohrDAsVbO
-                YogKqKuWv2wWKpZAKN0/IxDZrO7EjA4NbXEo0AXC/prtCZw6NL5AZy7wbi25
-                Q9nRy9n1x5fIYXpmpn9WoGMfw0zBNQlYQiAmDXQcQ6eGozhOsczyapbsXH/N
-                KtM2TeY6DD5X0CvQ7ruLftl2VofsYqkgcJwUGtiqnhGY7mbZ9YpdyFvlGE4L
-                RK/YhHoyyHpZx1m8o+EM+gTi06V0QMGEinOkZ5ZKlpMXGEofjHEwrAwxruM8
-                LrDHtMDJVvgaFQdYcZAVpw5XHGLFi1S0GgNU2XSL3HVkMcy6IzpO4hTzRoVo
-                XzO9tSk3b0ne1NpexxiSTP7lgA4ie5T3CojENutpxSx40qQrPXOwU/sfCGgV
-                Z8V9Fmjp+Bhxtr5K5Q2YvPOEcb5FQtABhPM6pjjwtMDpDdcv2E5mfbOYsR3f
-                KjtmITPrcEKenfNioN5UqVNuMB6BC+lDr0wdmo5bmNVwE3MCiYMKVOBqgtxG
-                re0nMMnZ3Kl24rKGCLeJkXMdzy9Xcr5bluTwMYOsESFwlpM+7MZw433G3r+g
-                C0cPhd7AdlZeHWJXKQ3zMELdWb9g/wM4uClB8b6mcs03kDq3WZx1aGPxPa0d
-                LFi+mTd9k2RKcTNED5bgIUZwNkj0zOYdIVHyhODv3a2LmtKjaIrRoe1u0RTT
-                FDVCs0pzmOY2+vOBGqXFEZoVde+7qz27WyNqIpxQsrtbWXE9kYgaSq+SDb3Z
-                Ebtbez9Fw2rYiMydNlQSxkeihtbLmrf2niukIfa12gx9rtdop9MjIypphXtE
-                tuPWm+eh4NQwOucMI8E+SCYC2VHjGMmOk6yrLus2eu52VgHQXqVEesNq1Ijt
-                fS+UaqxvFcpDTWoRde/H01nB2RP1oHpMly5u+FRpvjX0os0Tm7crxRWrvMQP
-                KneYmzMLy2bZ5r0Uti/6Zm5jwSzJfXzRXnVMv1KmtbboVso5a8bmg+TdiuPb
-                RWvZ9mzSvOY4rm/6NjUahqmgEUJAXwsk+F2msnSgEyriJHFpl6GZQCIy8Cva
-                X9JCQYnGaFWIpzTqcn2ETEGG9KRK449IW2HtvtQOul40WUcD666qBrqD4Lzq
-                oRUHpYaTfiaknziDIFcnDnMVl0B4VXUV59dKuhojHbZIvsaZ+6+QSry7jf6+
-                bbxn9G8js433f+ZmbcgrKZEJfvykk/OSFJXx7OCDZhu1zsVoPYdUjci+HXz4
-                oskgUg8yRqS1DHKl2WY/CD0l0uYeZcdXKzX4J5QfEAm9GNyFso1rNyjqjXP0
-                38EngTxcpbDMtxJK/B90Kw0cpurlSBGH8wGSBdyWUYYbyzG4g0/3obUqAZkb
-                Cr9I0nxSmmsDr3B3IPUb2n9p2VdVX1rdlxY0KJdzEUvS11lJktL3sokepdrO
-                RhKfY1lqXyBy+Cz+Gsr9vle411y4OO4HRp38sWkuXO0GiBZdn8QDPJQGl2R+
-                OnOeqnLezJCOLyXBOr7irIxreITH0sPVmocBWb5tmM0tH37LW40jXZYrBC/Q
-                D8EPZgcVmr+h1QrNOcKdf4jQLKxZPKERqzyszcLGOqXhYQOFh0h66PBQ9KAF
-                46KHJQ+qh7iHR4Gkx4PhodPDQrCl34SHSQ9jHkY9Ns8GwpMeTv0H1Ho+rbgK
-                AAA=
-                """,
+        androidx/compose/ui/unit/Dp.class:
+        H4sIAAAAAAAA/31U31MbVRT+7s2v3WWBTdpSQktbQ20DSBOwQpWCUGhKEFot
+        iLaodUlWWEiyMbthOj4xvuhf0Bn7Vl986XR0RiljZxykb/4d/hmO47mbS8iE
+        yExyf5x7vu+c+52z969/f/8DwHUUGc6ZpXzFsfOPUzmnWHZcK1W1U9WS7aVm
+        yxEwhjsLm+a2mSqYpfXUvbVNK+eNN1hmCGRWzLWCdXPhBKbxyXEGo5kogiDD
+        6VZkEYQZlHXLWzELVYshkOzPMIS2azuW0aGhTQWHzhD0NmyXoffE+AzRnM9u
+        LTtD6dEb6c1H14kwmcn0Zxk6j3LIFByTEosxRCRAx2lENZzCGYplVtbThHO8
+        DatC2yTBdRjinKOHod1zlryKXVofsovlAsMZcmhQq3ZGyZxttt2q2oW8VYng
+        AkP4pk1ZT/q3XtFxCW9ouIgEgzpbTvoSTCi4TH5muWyV8gxDyeMxjoeVIcZ1
+        XMFVwZhkON8qv0bHAeE4KBxnTnYcEo7XqGiHClBlky3uriONYeE7ouM8eoVu
+        VIj2DdPdmHHyltRNOdzrGENciH/Dl4PEHhV7DhKxzfq6ahZcCelKZo53av9D
+        Bq1aWnMe+1463ocq0FMMsePeJGmNUhSuFZmOCUwK/O1a7Vc0hERhjJxTcr1K
+        Nec5FZmOOKaWVQ5DM1wSWp/Uo6LUdwT7IrX4NoPecL+0bFa6Dy8Pi2GE+qHe
+        0v+TsN+bvlwrJNDCluMV7FJqc7uYmt8uZku0scSXcXiwaHlm3vRMsvHidoCe
+        CCYGVQygnLbI/tgWO0qH5ymNv/d3rmm8m2vc6NT2d2iKaFwJ0azQHKS5jf7i
+        QAnTooNmrhx8N9W9vzOixIIxnt7fSbNbnbGwwXt4OnDwYzioBI3Q/DlDob06
+        Eja0HuE0d/CEv95j+zu+R5uhz/cY7XTSMaKQR7CbpTvnXj+p4Q0jOm8YMYEn
+        G/Ntp4zTZDtDtq667azRfT9aj6tQ/j1BJWxEDr5n/OBbHtFCysGzC2km7kpq
+        kwKh2fK1LY+KK1qTno0FEvButbhmVZbFqyWaysmZhRWzYou9NLYveWZua9Es
+        y726ZK+XTK9aobW25FQrOStji4P4/WrJs4vWiu3a5DldKjme6dnUWximGoYo
+        A3qSEROPHxWhE1EoUMnyFe1SokI0hwZ+RfsLWnCs0xiuGbFBoy7XHQSlsop3
+        S4LfI28uvBN9e+h63oQO++iumgfO+sHFqptWIij1mOSZkDyqSIKozp1EpcpE
+        xKpGpYonQVKNkY9AxF/h4oOX6Iu9uYv+xC7eMvp3kdrF2z/7TXl0r7jMjIkX
+        RpJckaIoIp89vNOMUepajNbv0HcoZGIP7z5vAoTqQcZItJZBbjZjjoLQ6yEx
+        9+l24kPqHfwT/ClCgeeD++C7mL6duEwV+EFYgjXxbBoj4Oo/iPIG9Xrrhegl
+        9W75OcxgVvIPNxZicA+Zo6RaiU9wg4vnR8InJVwbeIm5gb7f0P5Ly46qcWl1
+        Ls1vTVHILOYl1yUpD0+8aBKG1xrZiOMDLEjvqySLOFNfgT9IvMTd5pKpuOeD
+        ouItby7ZYe+zFv0ex4f4SAKm5f06/H5/ikjwJwQDR3qHwPWpRrk6qGI1tTuw
+        JK5oTGMZH0u6KUmnD8gq7uKT5s4PNrDpdcF0WbsANn3/ALb82UKB5m9o9SnN
+        Dyihh6sIZLGaxWdZfI4vaIlHWXwJcxXMxRpyq4i76HSRd6H5Y9bFvAvFhepi
+        2bd0uzBcRF3M+Fv6TbiYdDHmYtQV8LRvPO+i9z+OvdduJAoAAA==
+        """,
         """
-                androidx/compose/ui/unit/DpKt.class:
-                H4sIAAAAAAAAAH1Qz0/UQBT+ZtrtlopQUJBdXH9gD0CiXYwHg1yMm00aV02U
-                cNnTbFtx2LbTtFPCccOBP8Q/wDPxYDZw848yviGcmcP3vve9N9/Me3///f4D
-                4A0Chp4okkrJ5CyMVV6qOg0bGTaF1OGg/KjbYAz+iTgVYSaK4/DL5CSNSbUY
-                WsepHpQM9na0M2TYvMOnjTa5xKqoddXEWlUvZV5m5upwZ7iIBXgeXNxj8AIZ
-                fA9ujVnE4Ab6h6yDhNKV0VTpTBbhp1SLRGjxjoHnpxYNwgzQE2xqCCf9TBrW
-                J5bsMezPZ0vefObxDe5x3/W4y7c6/nzW5X22y/v87fUFv75k89nVT8fp2q7l
-                21fn3Ka+jnF4bYB+0BvdMSP9BrSUQflqqmmyDypJGZZHskg/N/kkrQ7FJCNl
-                daRikR2JSpr8VvS+qaaK06E0SedrU2iZp0eyllR9XxRKCy1pedgDhw1zqA0t
-                OBSfUnZAkVN0rYPuxSUWf5kt4Bmhc1NZwHPi68Q4KfexRCp1Y5mY6dy6wSd4
-                QXGfaj55r4xhRViN8IAQDyOsYT3CI2yMwWp6vTtGq8Zmjcc1erXhzn8XAJq+
-                VwIAAA==
-                """
+        androidx/compose/ui/unit/DpKt.class:
+        H4sIAAAAAAAA/31Qy27TQBQ9M04cx5TWLVCalPAoRqJIxSligaAbRBTJIoBE
+        UTdZTWxTprE9lmdcdZlVP4QPYI1YoAh2fBTiTum6m3PPPfc1Z/78/fETwHM8
+        YhiIMq2VTM+iRBWV0lnUyKgppYlG1VvTAWMITsSpiHJRHkcfZidZQqrD0D7O
+        zKhiaD2Od8cM21fs6aBDWxJValM3iVH1niyq3I6Od8cr6ML34eEagx/K8HN4
+        uZjFDF5ovkgdppSuT+bK5LKM3mVGpMKIVwy8OHXICLPQtQAam1vCqXgmLRsS
+        S/cZ9paLVX+58PkW93ng+dzjO5vBctHnQ/aED/mL3+f811fX7bc8J2jZoWcW
+        6PJgcoU3egUdbY+qp3NDjt6oNGNYm8gye98Us6z+JGY5KRsTlYj8SNTS5pei
+        f6iaOsnG0ia9j01pZJEdSS2p+roslRFG0qdhHxwt/LfXQxsuxfuUHVDkFD3n
+        oH/+HSvfrHE8IHQvKl3sEN8kxkm5jlVSqRtrxGznwwu8h5DiS6oFtHt9CifG
+        RowbMW7iVkzjt2NsoTcF0+hje4q2xh2NgcZdbbn7D0kxfkBPAgAA
+        """
     )
 
     val Animatable: TestFile = bytecodeStub(
         filename = "Animatable.kt",
         filepath = "androidx/compose/animation/core",
-        checksum = 0x68ff47da,
+        checksum = 0xb1ce1ffe,
         """
             package androidx.compose.animation.core
 
@@ -1366,81 +1363,85 @@
             fun Animatable(initialValue: Float): Animatable<Float, Any> = Animatable(initialValue)
         """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAGNgYGBmYGBgBGJ2KM3Apc8ln5iXUpSfmVKhl5yfW5BfnKqX
-                mJeZm1iSmZ8HFClKFeJxBPMTk3JSvUu4tLkkMDQUleaVZOamCvEH5yUWFGfk
-                lwSXJJYAFSsxaDEAAKFdFhZ2AAAA
-                """,
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/3XLvQvCQAwF8IiiGEThBhERBBfBoS6Cszh2s+KetqE9uI9y
+        TcE/3xN1KgZehsf7AcAQAAYxU/gennBNrgxel8+k8LbxLSfktCXR3qllpl1l
+        +EGm48uvTQWPuP2vYhNYzT57yg1HcMZVD4TOibas8MaWbc4hFbXIHDVt7SUT
+        kjfc46YHO51UgZpaF62aXL3xUeIcR8KtqPE9/lR2cIAXLlZThPEAAAA=
+        """,
         """
-                androidx/compose/animation/core/Animatable.class:
-                H4sIAAAAAAAAAI1VXW8aRxQ9syywrAEv1EkwidvEcRrATtZ20tYNlNZxGgkF
-                ksimqJLzsoaNswZ2rZ0BpS8V6m/oS1/7C1qpUdo+VCiP/VFR7yzEMYZUfti5
-                M/fj3DP33oF/3/79D4C7+JahYLkt33NaL82m1z32uG1artO1hOO5pPFtczs4
-                WgcdOwrGUCrV71WPrL5ldiz30HxycGQ3RbExQ1eeVjEYZ3VRqAyRkuM6osxw
-                MzcdNK3JNxhiuXq9WG8E+5Wq5x+aR7Y48C3H5XQD1xPBFbj5uNfpSPKUO5TL
-                N+KIQNcRxhxDQvxwbO94bt/2he0zpKczxZFAMgYF8wy5qUr5PVc4Xdvcc61j
-                /sITe5TUfkRXSjEku72gaIHuyXOG4oyr5asfxKydCicaH2FBRxoXiLXjElvX
-                6gQmKtm5MS4hI6+yyKCKFw5nWJsO/WDzqX5x2STH6jSsTo8SN87Vq0q17YmO
-                45pH/a75jrr5wH5u9TqCis+F32sKz69Zftv2i6MORXXi+QlNy6Et6pNNWsjl
-                Z81VOJenYWDQKGLMT6rqpLpxrvpE8WkcK1iew03kaFYCtBkFmhVbojxlcr/+
-                f3PoCTmK5JV6V5GaLawWVZd0SrcfohfJ5BJlYG1SvXTkaZ12rQ2Gn4eDjK5k
-                FF3R6DOGA9qoY0U4MxwUVG04MBgJZiibynro/mI6YqhZZWs4SOuaYoSzaoZt
-                sTe/RhQjsrtgRLNaWk1L87r2/ZufktKgDwe7F0556pRpLqtqMUPfTRnxAGzr
-                IRkipEwYuuS2SXTr9NE7BBW9Pyp+4v3k3G4Leq57zqFriZ5Ptsu7oxpW3L7D
-                HfLYfl8nms0dr0VO81XHtR/3uge2X5co8nl6TTl8viPPY+XKWaynlm91bRqV
-                CdAE9anZrlnH4zB9z+v5TfuhIw+LY4zGFBts0ByGqQsKvT36JSBZCk4FfEUy
-                QheOBWd6Wie21RPbGkmVJA00QijT6RnZZVfThdeIF9ZewSis/omLr5D9PYj9
-                WtooRsar0AhdR4r235Dm6igSl3EFCHZLxIgFu9PcNGyTjClyniQ9QxL4mPaS
-                QIlA5IXml8I//oIwqxVW117j6ij7fVpDYNoEjQgBarQmKUkK17A8vopJiDJ5
-                uPAHjN9O2EcCpRYwjo8cxoxH7K5PVC4lnxxpy8Hf0QhQJ8DsX8gznEWNn0LV
-                J1BvEKnRLoSdQBbxgOR35HuLGNzeR6gCs4J1WrEhl80K7uDuPhjHZ/h8H0mO
-                KxxfcGxxfMmxxJHgiHJc4shwXONY5tLnHsfKfxpFtNlABwAA
-                """,
+        androidx/compose/animation/core/Animatable.class:
+        H4sIAAAAAAAA/41VXXPaRhQ9KyQQMtiC2gkmcZs4pAHsRo775Qbq1HHqGaYm
+        ydiU6YwfOjIojoyQPFrBJC8t09/Ql772F7QzzaTtQ4fJY39Up3cl4hhDWj9o
+        9+7d3XPPvfcs/P3Pn38B+Ag7DGXTbfue3X5mtLzuicctw3TtrhnYnkse3zK2
+        wqV56FgJMIZqtXF399jsm4ZjukfGo8NjqxVUmlN8m5MuBv28LwGZIV61XTvY
+        ZLhVnLw06Sk1GZLFRqPSaIZ2Ydfzj4xjKzj0TdvllIHrBWEK3HjYcxxBnmLH
+        iqVmCnFoGhTMMKSD5yfWtuf2LT+wfIbsZKQU0phNQsIcQ3GiUn7PDeyuZey7
+        5gl/6gX7FNT6ilLKMFzq9sKihb5HTwpt64nZcwKG76el+L/Q9V6U0GPPsVvP
+        K7UpRXk7SP0MFUrpHcxryGKBKmC7lLlrOuEWlf/CGJeRE2VZZJCDpzZnWJ28
+        +lYhUS9SouG26TRNp0eBmxfqe2234wWO7RrH/a7xmrrxIKosNZIHfq8VeH7d
+        9DuWX4m6ndCI53ukvCMraIw3fL5YmqZRpVgiYTGodGPET7ga5Lp5ofok8H4K
+        BSzP4BaKpLsQbUqBpt2tUpxNOn7jvzTtBULWdCrzuiJ1KzDbVF3ySd1+jF43
+        E0NSDGBgHfI/s8Vqjaz2HYYfh4OcJuUkTVLp04cDMuSRQ8kNB2VZHQ50RhPT
+        pXVpLXZ/MRvX5by0MRxkNVXSlbycYxvs1c9xSY/vzeuJvJqVs2J7Tf3m1Q+z
+        YkMbDvYWzpzUKNJMXlaTuraX0VMh2MYObcTJmdY1wW2d6Dboo4dNzJV+1IH0
+        G/nc7tAzSu7bR64Z9Hzau7IXFbLm9m1u04mtN8UigW57bTo0t2u71sNe99Dy
+        GwJFvHevJRTo22I9chbOYz02fbNrkV7GQNPUrFanbp6Mrmn7Xs9vWTu2WCyO
+        MJoTbHCHxKhQFyR6gPTTQvPn4aqMTZrjlHAyXNP7Ot1bOd1bpVmmmVSNGO7R
+        6ltCE11dKL9Eqrz6Anp5hSnsd1x6gfyv4fUvaMzSNQEhQ6UAGubJ3iLPtegy
+        ruCqEApZS0SKhdZZeiruCzVJoZiIoS44vEu24FAlEJHT3JLy3U9QWL28svoS
+        16Lo2zTGwNQxGnECVGmcpSAZXMfyKBtDSJVmpfwb9F9O2cdDpxoyTkUHRowj
+        djfGipcRT4+898K/uAhQI8D8HygxnEdNnUHVxlBvEqnIiuFBOFfxJc1f09kP
+        iMHtA8RqMGpYq1Fb18nEhzWK+PEBGMcn+PQAsxxXOTY4PuO4y7HEkeZIcFzm
+        yHFc51jm4kyFo/Avb5BXyJQHAAA=
+        """,
         """
-                androidx/compose/animation/core/AnimatableKt.class:
-                H4sIAAAAAAAAAJVRTW/TQBB9a+eDuqFxw1ebAoVyoRJi08KJIKQKKZKFCRKt
-                eslpE6+iTezdyl5HPeYncUQcUM78KMSsGykSXKi1np33/GY8H79+//gJ4C2O
-                GF4JneRGJdd8YrIrU0gutMqEVUYTk0t+VkExTuUn2wRjCGdiIXgq9JR/Gc/k
-                hFifIdjoGPjLwXH8/4n7DBe3i3gfb4oYpEbYfvx3Vf0PlPZFbPIpn0k7zoXS
-                BSXUxlYZCz40dlimab+FOhoBPGwxtJRWVon0UqQl9cEGDLvx3NhUaf5ZWpHQ
-                7ymtly18GiBzpkmyuXM84q+V83rkJScMb1bLMFgtA2/PC7ywSS+B1bLbpbu7
-                06l1vJ5XWb/HThthrUvYhZ7SWm43PjDc3RCv55ah9tEk1EI7VloOy2ws84ub
-                5XRiM3Ed5srhNbl1rqZa2DIn/+Brqa3KZKQXqlD0+WwzNVr0uSnziRwoF7a/
-                ll7+I8QJTbQG95DMjRg+DghxwlQw6kffEXxzc8Njso2KbOMJ2daNANvkAU8r
-                TROHa9WdCj+rbBfP6X7n2if9zgh+hHaEkCx2I3RwL8J9PBiBFXiIRyPUC3f2
-                CuxXZ/sPX0TSqAsDAAA=
-                """
+        androidx/compose/animation/core/AnimatableKt.class:
+        H4sIAAAAAAAA/5VRy27TQBQ9Y+dB3NC44dW4PNsNSAinhRVBSBVSJAsTJFp1
+        k9UkHkWT2DPIHkdd5pNYIhYoaz4KcceJFAk2VBqf+5hzr+ee++v3j58A3uCE
+        4SVXSa5lch1OdfZVFyLkSmbcSK0ok4vwvAr5JBUfTROMwZ/zJQ9Trmbh58lc
+        TCnrMng7HkP4fPgi/v/GA4bLm1W8i3ePGKaam0H896sG76ntSazzWTgXZpJz
+        qQpqqLSpOhbhSJtRmaaDNupoeHDQYmhLJY3k6RVPS5qDDRkO4oU2qVThJ2F4
+        Qr+ntk62dElAZqFlAcRdWMehy2tpvT55ySnD6/XK99Yrzzl0PMdv0kfBehUE
+        ZIP9bq3r9J0K3T47a/i1gGJbeka7uZmG9Ijbu8SrhWGofdAJzdGJpRKjMpuI
+        /HKzoW6sp3bMXNp4m2xdyJnipszJP/pSKiMzEamlLCRdn++ko21f6DKfiqG0
+        Zb0t9eofIk5J1ho2AvWsznDxkKLQCka2fvwd3jerGx4RNqpkB48J2xsC9sgD
+        nlScJp5uWbeq+FmFRzgm+9aOT/z9MdwInQh+hAN0I9zB3Qj3cH8MVuABDseo
+        F/b0CgTV2fsD4lpb1BADAAA=
+        """
     )
 
     val IntOffset: TestFile = bytecodeStub(
         filename = "IntOffset.kt",
         filepath = "androidx/compose/ui/unit",
-        checksum = 0xfd7af994,
+        checksum = 0xe18c78ef,
         """
             package androidx.compose.ui.unit
 
             class IntOffset(val x: Int, val y: Int)
         """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAGNgYGBmYGBgBGJ2KM3ApcAlkZiXUpSfmVKhl5yfW5BfnKpX
-                mqlXmpdZIsTiUuBdosSgxQAA2sByTDoAAAA=
-                """,
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/3XLOwvCQBAE4JUI4ioIV4iIINgIFrERrMUynQFb2SRLcnCP
+        cNmAP98TtQoOTDPMBwAJAIxip/ANnnBNrgpeV8+09Lb1HafktCXR3qllrl1t
+        +E6m58tvzQSPuP2v4hJYzT9/KgxHcMbVAITeibas8MaWbcEhE7XIHbVd4yUX
+        kjfc42YAe53WgdpGl52aXL3xUeIMx8KdqOSRyQ4O8AJoAzD57gAAAA==
+        """,
         """
-                androidx/compose/ui/unit/IntOffset.class:
-                H4sIAAAAAAAAAI1QTWsTURQ9781HJuO0mUwbTdOqtVZts3DS4k4RVCgMpBZq
-                CUo2TpJpfU0yI3kvJe7yW1y7ESyCCwku/VHifZMgCAWFmXPvuffcj3d//vr2
-                HcAjPGDYitPeKBO9SdjNhu8zmYRjEY5TocIoVUenpzJRBTAG/zy+iMNBnJ6F
-                R53zpEtRg8F+Ikj6lMHaiaLdFoOxs9vyYKHgwoTDwCb0Rx5cXCuCwyP2wcPy
-                nJUYTPVOSIbt5r/XeEzqs0S9zodEc/KGodzsZ2og0vAwUXEvVjHp+PDCoAcy
-                DQUa2afQRGjWIK+3x/B2Ng1cXuUu92dTlz7uOy53rOpsus8b7HklsH1e4w2D
-                rKntj482963j8jxKzKGqmunYfoGC5t9Bxy/oOfuMdoD35wUP+4rWfpH1EoZS
-                U6TJy/Gwk4xO4s6AIkEz68aDVjwSmi+C7qtsPOomB0KTteNxqsQwaQkpKPss
-                TTMVK5GlEnt0TpPexxHoW5MX6CuTNWgFCzbhFrFDUug7lOpfUayvX2KpvnEJ
-                /3NeepdQC0Gttgk351KUqRlyT7dmuaebc8qsYHXROiSrc1b9C5Y+XdnQmwsW
-                DcuoXFns/08xx70c7+A+2QPKXafcjTaMCNUIa4SoaViPsIGbbTCJW7jdRlEi
-                kNiUcHNclrAlViRWJSq/AaJQvyMZAwAA
-                """
+        androidx/compose/ui/unit/IntOffset.class:
+        H4sIAAAAAAAA/41QTWsTURQ9781HJuO0mUwbTdOqtVZNs3Da4k4RVCgMpBZq
+        CUo2TpJpfU0yI3kvJe7yW1y7ESyCCwku/VHifZMgCAWFmXvvOffcj3d//vr2
+        HcAj1Bm24rQ3ykRvEnaz4ftMJuFYhONUqDBK1dHpqUxUAYzBP48v4nAQp2fh
+        Uec86RJrMNhPBEmfMlj1KNppMRj1nZYHCwUXJhwGNqE/8uDiWhEcHqEPHpbn
+        qMRgqndCMmw3/73GY1KfJep1PiSagzcM5WY/UwORhoeJinuxiknHhxcGPZBp
+        U9QGNLdP/ERotEtRb4/h7WwauLzKXe7Ppi593Hdc7ljV2XSf77LnlcD2eY3v
+        GuRN7X98tLlvHZfnLCGHqmqmY/sFIs2/Sccv6Dn7TE/3/jzjYV/R7i+yXsJQ
+        aoo0eTkedpLRSdwZEBM0s248aMUjofGCdF9l41E3ORAarB2PUyWGSUtIQdln
+        aZqpWIksldijm5r0Po5AH5yiQJ+avEErWLDJ3iV0SAp9h1LjK4qN9UssNTYu
+        4X/OS7fJaiGo1T2ym3MpytQMeaRbszzSzTllVrC6aB3qS5O3Gl+w9OnKht5c
+        sGhYRuXKYv9/ijnu53YLD8gfUO465W60YUSoRliLUMM6hdiIcBO32mASt7HZ
+        RlEikLgj4eZ2WcKWWJFYlaj8BpHq1rYeAwAA
+        """
     )
 }
 
diff --git a/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/PrimitiveInCollectionDetectorTest.kt b/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/PrimitiveInCollectionDetectorTest.kt
index 251dd7d..9dc2cee 100644
--- a/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/PrimitiveInCollectionDetectorTest.kt
+++ b/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/PrimitiveInCollectionDetectorTest.kt
@@ -451,45 +451,45 @@
         val SimpleValueClass = kotlinAndBytecodeStub(
             filename = "SimpleValueClass.kt",
             filepath = "test",
-            checksum = 0xc2548512,
+            checksum = 0x8b98db3a,
             source = """
                 package test
 
                 @JvmInline
                 value class SimpleValueClass(val value: Int)
             """.trimIndent(),
-            """
+        """
             META-INF/main.kotlin_module:
-            H4sIAAAAAAAA/2NgYGBmYGBgBGIOBihQYtBiAABw+ypgGAAAAA==
+            H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgkucSTcxLKcrPTKnQS87PLcgvTtXL
+            ycwrEWILSS0u8S5RYtBiAAC6aGYHOQAAAA==
             """,
             """
             test/SimpleValueClass.class:
-            H4sIAAAAAAAA/31U31MbVRT+7s2vzWaBTaBAFtT+0DbhR5NirVUKUtDapaGt
-            UKMUfVjCTlhINpjdZOob44v+BT74ouOLfeBBZxTQzjhI3/ybHMdzN5uEWTLO
-            ZPbee+75zvnOd87N3//+8SeAm/ic4YJrOm5uzaruVcyiUWmYSxXDcWJgDOqO
-            0TRyFcMu5x5t7pglN4YQg1Q2Xc+RIZTJ6gyRZuvEdAUxSHFwxBnC7rblMIwU
-            esafZehza2tu3bLL0+KOiGT0bKGbsXVHfiNB22LDqmyZ9RgGGKJ3LNty5z0q
-            RQVJpGSoGCRUMGPGYzkn4QKhjL09095imM6cz3iehJ9wVsEIRkX8NMN4L7Zn
-            HceE47hwXPp/x1eF42uka1sPhqFMDyUUXMJl4XuFxDXq5byCPvTLpPZVEnPb
-            cLaXalumL2aY6FFrkt0ouu2aZaHaBKVqeyuYQlbGJKYVZMSOI8eQML9oGBXH
-            DzWc0QvBQZjNPmWQG/Zm7ZnnpeBNRAX6Jo1Dzd026wyp8yhSvhVadLtXUAU3
-            MCPivNsqoSgjLLqplmq249YbJbdW92lJ7dwMmuhF7zETI3FHBLxL89lkUM6U
-            lieuGV0XpfC9G+IzQ9UWdmtuxbJzO81qbrlZ1W06mMQ82b5YMV1jy3ANsvFq
-            M0TviImPJD6gLLtkf2aJEyXgWxT495P9yzIf5TJXT/Zl+nFVkrkUoTVBa5TW
-            flpD0unXC6Mn+zM8zxZTqajKNZ4PvTxmJ/unP0bDUliNLGuqRMb4jKTKWniU
-            5dn9l9+GvNuEqiyrap+AkI15tn5CqOoA2dSOLammVpOt0HSWiI4WlqJq7PQb
-            xlu5vuJhYpM+fR4dFAWQKFSW+sCr/nHF+LJcrzXE4xkMqn1916W2ibliGCiQ
-            bA8b1U2z/sTYrJhiHmolo1I06pY4+8a+Ndco7a4Ye/5ZXqs16iXzniUO6dWG
-            7VpVs2g5Ft3ete2aa7gWjQKNCafJEMRS4j+HdqLTEUTJ8gmdcqITtEYmfoV8
-            QBuOT+kb9YyDWPcAngMStAPi4jH54LfJW9ylX0BdP8JQavgQmnaIV9TsIS4e
-            4vWfvczdIGm84XFg4on6Qa76DCTB4BjXghipk5geno+50matHeP6QQAQ6SSZ
-            6pQZSJIPYrpJ6F35mEdUnZhObfIv8O8QCR1MnoAf4q05bfx7cQy39HpK3xh4
-            /B/0t0IOk5FgPg2xu0VSCQK38Y4fXPRFeMUFocljzHYZteBxn5HYeXCViyfq
-            w+d9uDxxhLmJsd8g/9Kzd61YcieW7A0Bo5jzHTEv+tpwLagKb42MmsZ7WPC9
-            r5Em4i7+AnxdO8JisF9xLHmgpPirC/arPWWsx2Sl8T4+CNSX0MZ+QCz8E8Kh
-            rtgREnvhrFYJ3POlTuBDrz6ODc+9iM9o3aXdfVp1gi5vIKTjgY6CjhU8pC0e
-            6XiMjzbAHKxibQNDDhQHTxzEvO+8g6yDiIOog9ue5Ra9KwczDqYcZBxc8ox9
-            DvodfPwfuO9oETMIAAA=
+            H4sIAAAAAAAA/31U31MbVRT+7s0m2Ww2sAktkAW1P7RN+NGkWGuVghS0djEU
+            hRql+LKEHVhINpjdZPrIm/4FPviiow++8KAzCoydcRDf/Jscx3M3m4RZMs5k
+            9t577vnO+c53zs3f//7+B4B7+ILhqme5XmHdrh1UrbJZbVpLVdN142AM2p7Z
+            MgtV09kprG7tWRUvjgiDvGN5viNDJJc3GKKt9okZKuKQE+BIMEjeru0yjJT6
+            xp9lSHn1da9hOzvT4o6I5Ix8qZexfUd+I2HbYtOubluNOAYZYg9tx/bmfSpl
+            FWlkFGgYIlQ4Y85nOSfjKqHMgwPL2WaYzl3OeJlEkHBWxQhGRfwsw3g/thcd
+            x4TjuHBc+n/HV4Xja6RrRw+GK7k+Sqi4jhvC9yaJazZ2iipSGFBI7Vsk5q7p
+            7i7Vt61ATInoUWvSvSiG41k7QrUJStXxVjGFvIJJTKvIiR1HgSFpfdk0q24Q
+            ajhnlMKDMJt/zqA0na36C99LxZuICfQ9Goe6t2s1GDKXUaR8O7Todr+gKu5i
+            RsR5t11CWYEkuqlV6o7rNZoVr94IaMmd3Ay66EX/MRMj8VAEfETz2WJQL5RW
+            JK45wxCl8IO74jND1Zb2617Vdgp7rVphuVUzHDpYxDzduVixPHPb9Eyy8Vor
+            Qu+IiU9CfEBZ9sn+whYnSsC3KfCPZ4c3FD7KFa6dHSr045qscDlKa5LWGK0D
+            tHL5/KuF0bPDGV5ki4OZmMZ1Xoyc/xCTZEmLLuuaTOfEjKwpujTKiuzJX9+0
+            b5OauqxpKeFNNubbBgihaYNk07q2tJZZS3ejysREl+SYFj//mnFBlcqnAobC
+            It7Z96gbYlwYBkukxtNmbctqPDO3qpZoc71iVstmwxbnwJha98zK/op5EJyV
+            9XqzUbEe2+KQXWs6nl2zyrZr0+0jx6l7pmdTh6n7nBouWGTEXwntRAOjiJGl
+            TKeCEJjW6MSvUI5ow/EZfWO+UcLnPsB3QJJ21BXxRgLw2+Qt7rIvoW2c4Epm
+            +Bi6foxXtPwxrh3j9Z/9zL0gWbzhc2Di5QVBbgUMZMHgFLfDGLmbmN5TgLnZ
+            Ya2f4s5RCBDtJpnqlhlKUgxjeknouQSYVapODJ0++Sf4t4hGjibPwI/x1pw+
+            /p04Sm29NugbB0/8g4F2yGEyEiygIXb3SSpB4AHeCYKLvgivhCA0eYrZHqM2
+            PBEwEjsfrnHx8gL4fABXJk4wNzH2G5Rf+vauHUvpxlL8IWAUc74r5rVAG66H
+            VeHtkdGyeA8Lgfdt0kTcJV6Cb+gnWAz3K4ElH5QW/2DhfnWmjPWZrCzexweh
+            +pL62PeISz9BivTEjpLYCxe1SuJxIHUSH/r1cTz33T/FJq27tHtCq0HQ5U1E
+            DHxkoGRgBU9pi1UDH+OTTTAXa1jfxJAL1cUzF3H/O+8i7yLqIubigW+5T+/K
+            xYyLKRc5F9d9Y8rFwH8DJohDBwgAAA==
             """
         )
     }
diff --git a/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt b/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt
index 6c011af..c512441 100644
--- a/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt
+++ b/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt
@@ -42,7 +42,7 @@
         private val stub = kotlinAndBytecodeStub(
             filename = "Stub.kt",
             filepath = "test",
-            checksum = 0xdbff73f0,
+            checksum = 0x8a5a4526,
             source = """
                 package test
 
@@ -67,29 +67,29 @@
             """,
             """
             META-INF/main.kotlin_module:
-            H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AJcbFUpJaXCLEFlxSmuQNpEOAPO8S
-            JQYtBgBDd0xtMAAAAA==
+            H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgEuNiKUktLhFiCy4pTfIG0iFAnneJ
+            EoMWAwBxHEvpMAAAAA==
             """,
             """
             test/StubKt.class:
-            H4sIAAAAAAAAAJ1UW08TQRT+ZnvZpRRZKigtCqhVCl621GuEmBgTQmNFI4gP
-            PE23Cw5tZ83utOGR+OJv8MnEf+Cb+mAIvvmjjGe2FLlUUZvsnJlzvu9858yl
-            3398+QrgFu4x9CsvVM6yalUfKxOMwd7kbe40uNxwnlY3PZe8MQZrvSVdJXzJ
-            ECtMrzJkHvnN137Iqw1vYT90qVCp+6ohpLPZbjpdSuh0EcU5TS2dhJrvxl9I
-            oeYeRKTLFS5rgS9qW44bKXtO0JJKND3nVyVzVELFDzacTU9VAy4oKZfSV7wj
-            sOSrpVajQSjT9aXypLKQZhg/UI0gdyB5wylLFRBfuKGJUwwj7ivPre8leMYD
-            3vQIyDBVqBzdr7kDnmWdZIMaSMPGUAqDyBzW69G9iWGGpJBtv+4xDBemjyuk
-            cQZn+zGCUYbJk7acYbQsCeD1OrHzeZFfz/8+zsoM2eeeWBderVd8cX7l/vH6
-            HvzPCY9HpfxBa6hLeuIpXuOKU2tGsx2jq8z0kKBy63pikH9L6FmRZrVZhvc7
-            28Opne2UYRuRGTU6nxXPjdk72zmjyEpDtpEbyMQzNC/Gdj8kKbho5ibsxG+j
-            u2+tb58Y0afspAZdTFo727Y5egI6aVsavfvGMFMJa/ddqch0mSVGfSDTbfLg
-            AbIVurL6jd6oK4b4I79GN2OwQme21GpWvWBFb5Tm+i5vrPJA6PWes29ZbEiu
-            WgHNx553nkxZtkUoKPzw1+tgyB+N7t/zQ7DUst8KXG9B6OzZPc7qsXyYhYE4
-            9C+OLBJIUndFWmXR+bGPeiAYopAeszBhEVzD5omuvadmMgOfcHrmM7IMLzXH
-            iDgpskkaB9CPEq3THTTZHNmbEa6P/uM62VNkb9Nn0mYSQVcxti+1SFCDrN2R
-            is33FLPo9Q7SM9ZiZ6K1hXM4H8nafylrZzFOtNg/yQ6T7Mgh2cmeshOHZA3c
-            iUYHd8kukPcCHcLFNcTKuFRGnkZcLuMKpsooYHoNLMQMrq6hL4QZ4lqIdIjr
-            IVIhxkKMh7gRIvETuPI3KzoGAAA=
+            H4sIAAAAAAAA/51UXU8TQRQ9s4XuUoosFZQWxa8iBT+21G8hJoaEsLGiAcQH
+            nqbbBYe2s2Z32vhIfPE3+GTiP/BNfTAE3/xRxjtbiiBV1CZ7Z+bec+bcO3em
+            375//gLgJu4x9Cs/Us6KalYeKROMwd7iLe7Uudx0nlS2fI+8CQZroyk9JQLJ
+            kChMrTFk5oPGyyDilbq/sB+6VCjXAlUX0tlqNZwOJXI6iOKsppaOQ8114s+k
+            ULMPYtJEmctqGIjqK8eLlX0nbEolGr7zM5NZSqEchJvOlq8qIRe0KZcyULwt
+            sBSopWa9TijTC6TypbKQZhg/kI0gdyh53XGlCokvvMjECYYR74Xv1fY2eMpD
+            3vAJyDBZKP96XrMHPCt6k00qIA0bQykMInNYr0v1JoYZkkK2gprPMFyYOqqQ
+            ximc7scIRhnOH3fkDKOuJIDfrWNn8yK/kf99nLkM2WVfbAi/2i2+OLd6/2h+
+            D/6nw+NxKn/QGuqQHvuKV7niVJrRaCXoKjNt+rQB5VzTE4OCr4SeFWlWnWF4
+            t7M9nNrZThm2EQ+jRvuzenJj9s52ziiy0pBt5AYyPRmaFxO775MUXDRz5+ze
+            30Z331hfPzKiT9pJDbqYtHa2bXP0GHTStjR697Vhpnqt3belItNplpiuINOp
+            9GAX2SrdW/1Qr9cUQ898UKXrMVimxi01GxU/XNWnpbmBx+trPBR6vefsWxGb
+            kqtmSPOx5fa7cWVLRILCD38+EYb8r9H9y34IlloJmqHnLwi9e3aPs3ZkP8zA
+            QI9uC9ksepGk6mZolUX7xz7ELSuR1SFtszBhEVzD5oiuvSemMwMfcXL6E7IM
+            zzXHiDkpGpNkB9CPG7ROt9E05uI/OI3rw6293VM03qbPpMMkgs5ibF9qkaAG
+            jXZbKjHXVcyiJzxIb1mLnYrXFs7gbCxr/6WsncU40RL/JDtMsiOHZM93lT13
+            SNbAndgWcZfGBfJeoCZcXEfCxSUXeRcTuOxiEgUXU5heB4twBVfX0RfBjHAt
+            QjrC9QipCGMRxiM4EXp/AGJveMs/BgAA
             """
         )
 
diff --git a/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ColorsDetectorTest.kt b/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ColorsDetectorTest.kt
index 34438f0..d04646c 100644
--- a/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ColorsDetectorTest.kt
+++ b/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ColorsDetectorTest.kt
@@ -47,7 +47,7 @@
     private val ColorsStub = kotlinAndBytecodeStub(
         filename = "Colors.kt",
         filepath = "androidx/compose/material",
-        checksum = 0x2f84988c,
+        checksum = 0x73db7d2,
         """
             package androidx.compose.material
 
@@ -129,65 +129,66 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcolmZiXUpSfmVKhl5yfW5BfnKqX
-        m1iSWpSZmCPE4Zyfk19U7F3Cpc4li1OZXlp+vhBbSGpxCVihDIbC0ky99KLE
-        gozM5GIhdrCR3iVKDFoMAMec7K6RAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        TSxJLcpMzBHicM7PyS8q9i7hUueSxalMLy0/X4gtJLW4BKxQBkNhaaZeelFi
+        QUZmcrEQO9hI7xIlBi0GAPW9qnSRAAAA
         """,
         """
         androidx/compose/material/Colors.class:
-        H4sIAAAAAAAAAJVUTW8TSRB9Pf6YeGzHdownNmGWrwBJgExA3LJCgrArBZnd
-        1QblQA6oMx6Sju3uqHscwS3aH7BnzvwDTlntYRXBAYkfhahpTwYQhxUzo3qv
-        uqq763W1/fHTv/8BuIe7DJe4HGglBi/DSI0PlYnDMU9iLfgo3FAjpY0LxtA8
-        4Ec8HHG5F/6+exBHiYsCQ/lnIUVyn8JLj796ni1vMxSWlrdrKMH1UMQMQzHZ
-        F4bhSv//9ltncA+1GHP9ioE9ZpjNvG1OWTJhqJg4UnJgE5o5z8PeLo+Ge1pN
-        5ICWMhP9gkcxQynWWmmareQfZ8tXldz6slZNyYdfTaXErbPJrpK/TKe7wvTF
-        3j7tw54x3P9WeH+okpGQ4cHROBSSZEmS9Sh+wSejZENJk+hJlCj9hOthrNen
-        B1T24OACQ3sx+pLxfGxTGFZ/bEmG1tmEJ3HCBzzhNOaMjwrUb5aaEhU+pKGX
-        IvXWiA3uMLw5Pe56TtfxnObpsUef5TM18qvkdk+P7zpr7OHhXLnpnHfWCoTF
-        DEsZljN0M5zJsJKhl2E1w1qG9QxnM2wQNt//w06P370pO83Wu7+cIpXSSyul
-        +wqGxe/v0ESEe5of7ovITK8Rqa5M79PqkHpV3FADamOjL2T822S8G+unfHdE
-        I3N9FfGRvTvkZ4PelproKP5VpE7vz4lMxDjeFkZQ9IGUKuGJoKPHHepcEenj
-        0EutpOJuk/eW8Hx61isnqLy14VWyaTi1Idm/MZsmwEPVLlBCDXUbL1GkDtsq
-        NIiVLGsScy1rEatYNkesalmbWN2yc4QNyzrEWpb5xNqWzRPrWNYlNm9Zj0rt
-        Nen3gYWs/A80skAYrFy87Jd816/4Vb/uN/yW3/Y7/nynd4IglcWslNd2wyCX
-        EuRSglxKkEsJcilBLiXIpQS5lCCXEuRSglxKkEsJcinBVIplP+EicQdr9vBv
-        UacATjVdohou76CwiSubuEoWi6m5tonruLEDZrCE5R3MGVQNVgxqBjcNZg0a
-        hv5q0DJpqG1wzqBj4BvMG3QNejZ54TP/Je0LWAUAAA==
+        H4sIAAAAAAAA/5WUT28TRxjGn1n/2Xhtx3aMNzbp8jdAkrbZkPYGQippKwWZ
+        tmpQDuSAJuslmdg7E82sI3rLJ+CGxJlvkBNSD1XEBYkPhXh3vFmoeqiwrHl+
+        M+87M+8zM/aHj3//A+BH/MBwjcuRVmL0IoxUcqxMHCY8jbXgk3BLTZQ2LhhD
+        +4if8HDC5UH4+/5RHKUuSgzV+0KK9AGFVx598Xm6ustQWlndbaAC10MZcwzl
+        9FAYhhvD/9vvHoN7rEXC9V8M7BHDfN7b5ZQlU4aaiSMlRzahXXAR9vZ5ND7Q
+        aipHtJSZ6uc8ihkqsdZK02wl/7hYvq7kzue1Gko+/GIqJe5cTHaV/GU23RVm
+        KA4OaR/2lOHBv40PxyqdCBkenSShkGRLkq2f4+d8Okm3lDSpnkap0o+5Hsf6
+        3uyAqh4cfMPQXY4+ZzxLbArD+tctydC5mPA4TvmIp5zGnOSkRPfNsqaWNaDq
+        xzT+QmS9DaLRXYZX56d9z+k7ntM+P/Xoa3muQf06dfvnp5vOBnuYLFTbzmVn
+        o0RazrWSazVXN9e5XGu5ernWc23k2sx1PtcWafvdm6rT7mTFbbKs5OX/vp2p
+        CA80Pz4UkZk9H3Jbm72j9THdUXlLjej6WkMh49+myX6sn/D9CY0sDFXEJ/bN
+        UD8f9HbUVEfxryLrDP6cylQk8a4wgqI/SalSngo6ctylGytnx0jqZFdIxa1T
+        74z0Mmll7S1qZzYcUpuFs3aD2peYzxLgoW4XqKCBpo1XKNJEyVKLqGKpTeRa
+        6hDVLC0Q1S11iZqWLpG2LPWIOpZ8oq6lRaKepT7RoqUBlTpo0+8CS3n572lk
+        iTRYu3rdr/iuX/PrftNv+R2/6/f8xd7gLYIz+3oyK6/thkFhJSisBIWVoLAS
+        FFaCwkpQWAkKK0FhJSisBIWVoLASFFaCmRVLV3CV2KEbyg7/e2yScqrpGtVw
+        fQ+lbdzYxs1tLOMWIW5v4w5W9sAMVrG2hwWDusG3Bg2D7wzmDVqG/mLQMVmo
+        a3DJoGfgGywa9A0GNnnpExMAv0xQBQAA
         """,
         """
         androidx/compose/material/ColorsKt.class:
-        H4sIAAAAAAAAAM1WzU8cZRj/vct+sSzLsN2dLvQLC7VgW5ZCC7XbUgr9Wlho
-        LS1tQW2G3YUOLDM4M0vaxhg0scYYLx5M9GCiHjx4sFGjxBpDMPHgxZuH/hGe
-        PBr1NzMwbAFTvHUO7/N7nnk+3nme3/vu/vr3Dz8BOIbbAvsVrWDoauFuOq/P
-        zetmMT2nWEVDVUrpAb2kG+aQFYIQkGaUBSVdUrTp9OXJmWKe1iqBHSV1+o7l
-        Oh7pfG185Ob9EwIdrYMVT1vuaSUyAs053ZhOzxStSUNRNTOtaJpuKZaqE4/o
-        1ki5VKJX09MyhRAWCJ5SNdXqFeh9Yh/juVndKqlaemZhLq1qjNMYd644pZRL
-        /ATNtIxy3tKNYcWYLRqZtrEoIqiJoBpRgdC8oc4pxj0BMSgQW9XGFNbWLIFq
-        s5jXtYLjIHnYex2ZVPKz04Ze1gpMZZaNKSVfFAgUDUM3GK1rV9bS1+ja6Hqu
-        qK71V4TScXQtOKRr593wXVsMoaXgfpfAwBNNyOY2zjGzjfkEyBb8M4k/BFo2
-        OZfV9LShzN9R86brbzNmH7/OUQT8rYNtg1E8h/0RNKHZzdWDb1xQ9fgXF4h3
-        HmzFxk3ZQzjERgzwtaKRHgLtm/e/KajF889EcQTt1TiMtMDh/xMZwlEOd7po
-        3bijWsUjHYWe20Mz1wWqWu3P68KxCDpx3P2Yh2hyfftLHN+abxQvul4nowgg
-        GIEPpwTiHPXsxiPUuNm4NlK3wqMHf7kgHo+74Lepe1H0umkvCNSv0X24aCkF
-        xVJ4fnxzC1V0FfYSIJVnbeCj/a5qow6iwlEhcsuLUmR5MeJL+daEL1zXuPKe
-        kJYXG30dojMc9kk+oioH+T0U8FDQQyEPhT1U7aGIh2o8FPVQrYdiNvp5SSwv
-        chErnwX94TpJcvZU/+xsKS5JK2/5atiuhkggvPLp3g5h97STV8D6QEnz7VyJ
-        LdvgNd1qKk6/czBs0D7Lk+8f0Au8KOpyqlYcKc9NFo1rymSJlnhOzysl53ai
-        vmrcdbWsWepcMastqKZK09n1K1igdtQikYeV+VXvyKheNvLFC6qtNKyGjm0K
-        xFGS0W/Tk2uDTXrqN6n9id1IUTY9QvWtvU2yXw7KYTkiR+WYLMlxOSHLfvE9
-        ah/aBMUtrv2QuDYzTwvzHGCm5xHGQd7RrYiiDTG8QI9DiPNoJ3jGZbSzQhqN
-        6GCtZuzjXsaZ4T69WZf+dc6+mhhVxxo2qifyOyhOFHTQDqKwgxJEEQclidws
-        MlHMQTuJJAeliOIOaiBKOKiRSMYEcRC8uwGpGru4L2F3Q0wxppHvHidT/jc+
-        QiSBPUtoOZNMBVztALWzyVSIWk0CB6n1+JMpKezqbbYepC7Z+tfo+A7dPWHq
-        TRV6hHqf699j+0eTqXosVjjEaBDwDJkeiQZfpSFOg7/SkKAhjIoc8taTXMJp
-        d44vc40hGquN1fGR7MeZ7RQ7BfYnxC7GKJPsx27KZtoPUXaxOxnKAfZsiHKU
-        byco89iDWUoLe/E65duc8vuUH7Ljn1B+wV+dryiXsB/LlA32/bh9BlZtxcA+
-        MuQsGdjPTANkxjly4jzZcIE7v0iPS5x9llMfZL0hVshx78Os1ce9jTxjDDzj
-        MXB8lYG/ewzs2y4DQ7J/nX0J9NvvPPat6hXsO7cF+zJPZV/3RvZ1b2Rf5r/Z
-        d3Ej+2qeYN+r7BzIsRD/EccokzjOvnSRfd1kXxe7dIKT7cJl/nzfoLyNk5im
-        nCcn71K+iVN4l/IDnMbHlJ+TZV9SfsvIHyl9eMWpf4OVgAI7fon8yU6gKovB
-        LIa4IpclSUayrHFlAsLES7g6gR0mRk1cMxEzcd3kH0vUm4ibtj1hImlCNrHT
-        RMpEg4lGE70mgibGTAT+BZIgXWjiCwAA
+        H4sIAAAAAAAA/81WS1McVRT+7jDMDMMwNJOZzkBeGIgBExjCJBBDQgjkNbyi
+        ISEP1NjMNKRh6MbuHipJWRZaZdSFGxdW6cIqdeHChSm1lDKWRWGVCzfuXORH
+        uHJpqV93QzMBrOAuPVX3fOfcc8+5fc53b8+vf//wE4CjUAT2K3rBNLTCnUze
+        mJs3LDUzp9iqqSnFzIBRNExryA5DCEgzyoKSKSr6dObS5Iyap7VCYEdRm75t
+        e45tna/dHL1+77hAR8tg2dM6/KQUPQJNw4Y5nZlR7UlT0XQro+i6YSu2ZhCP
+        GvZoqVikV+OTIoUREQid1HTN7hXofWwfN4dnDbuo6ZmZhbmMpnOdznVn1Sml
+        VOQr6JZtlvK2YY4o5qxq9rSOxxBFdRRViAmE501tTjHvCohBgfiqNq4wt24L
+        VFlq3tALroPkY386OqnkZ6dNo6QXGMoqmVNKXhWoVE3TMLna0F9YC19t6GPr
+        sWKG3l+2lI5ja4vDhn7OW75riyY0F7z3Ehh4rAi54Y197NlGfyrJFvwziT8E
+        mjc5l7TMtKnM39bylufvMGYf385VBIItg62DMTyD/VE0osmL1Y1vPFDx6BcP
+        iHfub8XGTdHDOMRCDHBa0UkPgfbN+9+0qNn374mhDe1VOIyMwOH/szKMI2zu
+        tGpfu63ZaltHofvW0MxVgYoW5/WyOBpFJ455L/MAjZ5vf5HtW/ON4XnP60QM
+        lQhFEcBJgQRbPbvxCDVsNq611Mvw8P5fHkgkEh74bepuDL1e2PMCdWt0H1Ft
+        paDYCs9PYG6hgq7CGaqcAeTzrAMCnLyjOaiDqHBEiL7lRSm6vBgNpANrIhCp
+        bVh5V0jLiw2BDtEZiQSkAFGFi4I+qvRRyEdhH0V8VOWjqI+qfRTzUY2P4g76
+        eUksL658FgpGaiXJ3U/d07GdhCStvBUIRysjK5/u7RBOHTt59tc7SX5v5y5s
+        3gah6VZdduzdE+GA9lke+eCAUeANUTus6epoaW5SNa8ok0VaEsNGXim61xL1
+        VeOuyyXd1ubUnL6gWRpNZ9bvXoGaMZsMHlHmV71jOV1XzYGiYlkqp6NjRsnM
+        q+c1Z65+NdL4pjg4QlIGHcJxrHfIT/0GtT+xG2nKxoeourG3UQ7KITkiR+WY
+        HJclOSEnZTkovkfNA4ejuMmxHxLHJsZpZpwDjPQsIjjIu7oFMbQijufocQgJ
+        HvEkz7qMdmbIoAEdzNWEfdzLBCPcozfz0r/W3VcjV9Uyh4PqiIIuShCFXLSD
+        KOKiJFHURSkiL4pMFHfRTiLJRWmihIvqiZIuaiCS8RJxiGcvDEhV2MV9Caca
+        YoprGjj3KJUOvvERoknsWULz6VS60tMOUDuTSoepVSdxkFp3MJWWIp7e6ugh
+        6pKjf42O79DVHaHeWKZHqfd5/t2OfyyVrsNimUOcBgHf0NMt0RAoNyRoCJYb
+        kjREUBZD3rqTSzjl9fFljnHE4jXxWj6S87i9nWKlwPqEWcU4ZYr12E3ZRPsh
+        yiyr00M5wJoNUY5xdoIyjz2YpbSxF69Tvs0uv0/5ISv+CeUX/Pp8RbmE/Vim
+        rHfuye0zsGIrBvaRIWfIwH5GGiAzzpIT58iG89z5BXpcZO9z7Pog8w0xwzD3
+        PsJcfdzb6FPGwNM+AydXGfi7z8C+7TIwLAfX2ZdEvzPns29VL2Pf2S3Y1/NE
+        9nVtZF/XRvb1/Df7LmxkX/UW7MuyJkc5n2Vtj7EuWbKvi+zL8tfNX5bVOs4O
+        Z3GJn/NrlLdwAtOU8+TmHco3cRLvUX6AU/iY8nOy7UvKb7nyR8oKvMI8UVa8
+        k3dUG7Pecvd1Ha9SFmi/SF7lJlCRw2AOQzlyZyRH0lzK4QW8OAFh4TLGJrDD
+        whULVy3ELYxb/OOJOgsJy7EnLaQsyBZ2WkhbqLfQYKHXQsjCNQuV/wJPDAsN
+        AgwAAA==
         """
     )
 
diff --git a/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ScaffoldPaddingDetectorTest.kt b/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ScaffoldPaddingDetectorTest.kt
index 65d5116..d581caf 100644
--- a/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ScaffoldPaddingDetectorTest.kt
+++ b/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ScaffoldPaddingDetectorTest.kt
@@ -43,7 +43,7 @@
     private val ScaffoldStub = bytecodeStub(
         filename = "Scaffold.kt",
         filepath = "androidx/compose/material",
-        checksum = 0x2dde3750,
+        checksum = 0x7045eee1,
         """
             package androidx.compose.material
 
@@ -60,74 +60,75 @@
             ) {}
 
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGI2BijgUueSTMxLKcrPTKnQS87PLcgvTtXL
-        TSxJLcpMzBHiCk5OTEvLz0nxLuHi5WJOy88XYgtJLS7xLlFi0GIAACJwI+tQ
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUueSTMxLKcrPTKnQS87PLcgvTtXL
+        TSxJLcpMzBHiCk5OTEvLz0nxLuHi5WJOy88XYgtJLS7xLlFi0GIAADDzNLNQ
         AAAA
         """,
         """
         androidx/compose/material/ScaffoldKt$Scaffold$1.class:
-        H4sIAAAAAAAAAKVU604TQRT+Zlt6xxZEuYj3qi0o2+LdNiSEQNxQMLHYxPBr
+        H4sIAAAAAAAA/6VU604TQRT+Zlt6xxZEuYj3qi0o2+LdNiSEQNxQMLHYxPBr
         2t3C0N1Z091t8B8P4RP4BKKJJJoY4k8fynhmaQ2GiBo32bMn53zfmXOb/fb9
         0xcA9/CEQefS7LrC3NVbrvPK9Szd4b7VFdzW6y3ebru2uernB2q+HAdjWK11
         XN8WUt/pObqQhJeEr3GnafLKcV87kC1fuNLTV/paqTrwv5DCryxUGKZ+HyyO
         KMOl0wPGEWOIVQWFW2CIFIoNhmjBKDYySCCVwhDSZPC3hcdQrv1juZReTMie
         27EYxgrF2g7vcd3mckt/1tyxWn4lgyySKWgYYUgfqyyOswwJY72+sbi+tMww
         /EvZGZzD+STGME6gassOk1f5hqGmlPtMkrRphpEBcc3yucl9TilpTi9CA2RK
-        xJQAA+soJULOXaG0EmlmmWH6cC+ROtxLaTmNPrnDvSmtxJ6mvr6NaQlNYeYp
+        JJUAA+soJULOXaG0EmlmmWH6cC+ROtxLaTmNPrnDvSmtxJ6mvr6NaQlNYeYp
         8SqXrnztuIFHLaRg+b9pUxy3GXI/e2VabR7YPsObwskuB0Jfc03RFlb3Twvy
         n/5yxTg5JbUMc9Cp0kG6cx3KNLrkmjTY0Zrb4naDU31N29pQgiFbE9JaD5ym
         1e1bMoaUVnfJ5p5n0S5ll2XLdj0ht2gy267JkKyLLcn9oEvgVN0Nui1rRSjm
-        5PNA+sKxGsITFGpRStfnYdoo0ZSHqON0rzCpxk6ji9JLq0CWedLyhGBq0DOR
-        A2T2w2HfJZk5smI45IyoPewzZkMMvQqs0T1XMGVIHyOyI2JukYi5PnFe7ZE6
-        fOYjRt9j4t0p/ET/4ASlPTh4nNDqSX+G9vIAFz7g4n5oGMJ9kimCHQEm8CCs
-        8w7V/zA8JIJH4beMx+Gvia49sS5vImLgioGrBq7hukHNuGHgJm5tgnkooEh+
-        DzMeZj1kfwB7t1DT1wQAAA==
+        5PNA+sKxGsITFGpRStfnYdoo0ZSHqON0rzCpxk6ji9JLq0CWedLyhKChIDYT
+        OUBmPxz2XZKZIyuGQ86I2sM+YzbE0KvAGt1zBVOG9DEiOyLmFomY6xPn1R6p
+        w2c+YvQ9Jt6dwk/0D05Q2oODxwmtnvRnaC8PcOEDLu6HhiHcJ5ki2BFgAg/C
+        Ou9Q/Q/DQyJ4FH7LeBz+mujaE+vyJiIGrhi4auAarhvUjBsGbuLWJpiHAork
+        9zDjYdZD9geSTRPs1wQAAA==
         """,
         """
         androidx/compose/material/ScaffoldKt$Scaffold$2.class:
-        H4sIAAAAAAAAAKVU604TQRT+Zlt6WYotiHIR71VbULatd9uQECJxQ8HEYhPD
-        r2l3C0O3s6a72+A/HsIn8AlEE0k0McSfPpTxzNIqhogaN9mzJ+d835lzm/36
-        7eNnAHfwiMHg0uq6wtoxmm7npevZRof7dldwx6g1eavlOtaKnx2o2VIcjGGl
-        2nZ9R0hju9cxhCS8JHyVdxoWLx/1tQLZ9IUrPWO5rxUqA/9zKfzyQplh+vfB
-        4ogyXDg5YBwxhlhFULgFhkguX2eI5sx8PYUEdB1DGCaDvyU8hmL1H8ul9GJC
-        9ty2zTCey1e3eY8bDpebxtPGtt30yymkkdShYZRh+EhlcZxmSJhrtfXFtaXH
-        DCO/lJ3CGZxNYhwTBKo0nTB5lW8Yalq5TyVJm2EYHRBXbZ9b3OeUktbpRWiA
-        TImYEmBgbaVEyLkjlFYgzSoyzBzsJvSDXV3LaPTJHOxOawX2RP/yJqYlNIUp
-        UeIVLl35quMGHrWQgmX/pk1x3GTI/OiVZbd44PgMr3PHuxwIY9W1REvY3T8t
-        yH/6i2Xz+JTUMszDoEoH6c63KdPokmvRYMeqbpM7dU71NRx7XQmGdFVIey3o
-        NOxu35IypbS7Sw73PJt2Kf1YNh3XE3KTJrPlWgzJmtiU3A+6BNZrbtBt2stC
-        MaeeBdIXHbsuPEGhFqV0fR6mjQJNeYg6TvcKU2rsNLoovbQKZCmRliUEU4Oe
-        jewjtRcO+zbJ1KEVIyFnVO1hnzEXYuhVYI3uuYKxkPKTyA6JmUUiZvrEktoj
-        dfjsB4y9w+TbE/iJ/sEJSntw8ASh1TP8CdqLfZx7j/N7oWEId0nqBDsETOJe
-        WOctqv9+eEgED8JvEQ/DXxNde2Jd3EDExCUTl01cwVWTmnHNxHXc2ADzkEOe
-        /B5mPcx5SH8Hm6I3JNcEAAA=
+        H4sIAAAAAAAA/6VU604TQRT+Zlt6o9iCKBfxXrUFZdt6tw0JIRI3FEwsNjH8
+        mna3MHR31nR3G/zHQ/gEPoFoIokmhvjThzKeWVrFEFHjJnv25JzvO3Nus1+/
+        ffwM4A4eMehcml1XmDt6y3Veup6lO9y3uoLber3F223XNlf83EDNleNgDCu1
+        juvbQurbPUcXkvCS8DXuNE1eOeprB7LlC1d6+nJfK1YH/udS+JWFCsP074PF
+        EWW4cHLAOGIMsaqgcAsMkXyhwRDNG4VGGgmkUhjCMBn8LeExlGr/WC6lFxOy
+        53YshvF8obbNe1y3udzUnza3rZZfSSODZAoaRhmGj1QWx2mGhLFWX19cW3rM
+        MPJL2WmcwdkkxjFBoGrLDpNX+YahppX7VJK0GYbRAXHV8rnJfU4paU4vQgNk
+        SiSVAAPrKCVCzh2htCJpZolh5mA3kTrYTWlZjT7Zg91prciepL68iWkJTWHK
+        lHiVS1e+ctzAoxZSsNzftCmOmwzZH70yrTYPbJ/hdf54lwOhr7qmaAur+6cF
+        +U9/qWIcn5JahnnoVOkg3fkOZRpdck0a7FjNbXG7wam+pm2tK8GQqQlprQVO
+        0+r2LWlDSqu7ZHPPs2iXMo9ly3Y9ITdpMluuyZCsi03J/aBL4FTdDbota1ko
+        5tSzQPrCsRrCExRqUUrX52HaKNKUh6jjdK8wpcZOo4vSS6tAljJpOULQUBCb
+        jewjvRcO+zbJ9KEVIyFnVO1hnzEXYuhVYI3uuYKxkPKTyA6J2UUiZvvEstoj
+        dfjsB4y9w+TbE/iJ/sEJSntw8ASh1TP8CdqLfZx7j/N7oWEId0mmCHYImMS9
+        sM5bVP/98JAIHoTfEh6Gvya69sS6uIGIgUsGLhu4gqsGNeOageu4sQHmIY8C
+        +T3MepjzkPkOclh0G9cEAAA=
         """,
         """
         androidx/compose/material/ScaffoldKt.class:
-        H4sIAAAAAAAAAMVVS3PbVBT+rl+SFSd1lThN3BJK49I0jyo25elQSE3Titim
-        g9tssrqWZaNYusrokSkbJgx/gQ1b/gGsOiwYD0v+BX+E6ZFshzTupGTKDAvd
-        e173nO+ce+7Rn3//9juAu2gwlLjoeK7VeaYZrnPo+qbm8MD0LG5rLYN3u67d
-        2Q0kMIb8AT/ims1FT/uqfWAaJE0yyGMrhu9X6hPOQktruB2ra5letd53A9sS
-        2sGRo3VDYQSWK3xtZ0RtvqG+XL29x/DXm2HYGuufCiuo3vtvzctbG5Pgum4o
-        OjxSU2m/dcNAe8w7HUv09rgdmn71TIQox5uTXrxQBJZjarWY523brDIs112v
-        px2YQdvjFuHgQrgBH2JqukEztG2ykp1RbWQoDEunMrAENYKgRtBF4JEDy/Al
-        5BgKxjem0R95eMw97phkyHBrpX62RaqnJK3ISY8yyGEGlxRMI8+QCdzD+5xi
-        qwzZthsErhOzcwyS4RIAEciYJ1znXyvD9dd1z2tNymSSH3dzqWN2eWgHDD/+
-        z12tTxY1aoJr54GS8BaVM2oGLsgJw/k5lE4sqzm8jetZLOEdBu3fjIbSScXK
-        EpapnfRm68l2s/aAoTwZ9HwHFP0m3s2ihFsvd+Ir6ibh9oURViSsXRxWJYa1
-        kcU67uSQRkZBApsMl8c31zADTk+YU/8knKMkTVYWLZloAQPrR0SClM+siKKj
-        iU6Z4YfB8Q1lcKwk8ol4WzjZ4k9OjOni0/zguJjYZBVZJmOikpVZolLFaTWl
-        knwz/cfPmYSciaXShPRKXi7OxjJlpMkONY+kCEqFRSjVcTanX8yEMHojlYsP
-        MYapcTnv9OlNpWpux2S4VLeE2Qydtuk9iWZWFNA1uL3H6TKIHwmzLasneBB6
-        RF/9ejjpdHFk+Rapt/8ZavQzO6s9mU4vmU23Am70G/xwFCCnC2F6NZv7vklq
-        peWGnmHuWJFuceRybyIcytQHqeiOaV+MGoO4GnF8JF9cVaee4/KaOkvrulqg
-        dUO9Qusv8ZEvoh6hyi/QOHxA9OrwEBSSIKZU+lhMzdGXiKl5FJHETuxBwsOR
-        D5n2R5E+RUw2brszaz6Lq7hGdITQoVAZ2iuFVOq7n6D8ihsDLO0WUukhtzLA
-        ar2QkoacRlxjdW194znKQ+g6rWkkZ6an4yyWCAkoiETYZ2gvYIpCZbGMHGWV
-        Jbxfkl6lg6U4swV6SsN9N3Z3H3Xa6wSuQm7f20dSx10d7+v4AB/q+Agf6/gE
-        1X0wH1v4dB9TPtI+7vlQfCz4UH185kP2Medj3sfnPrZfADvMWafjCAAA
+        H4sIAAAAAAAA/8VVS3MbRRD+RpK1D0uJIluOrQQnxEri+JG1RHjKBBwRk8WS
+        kkKJLz6NViux1u6sax+ucKFM8Re4cOUfwCnFgVJx5F/wR6j0riTjWJQTV6ji
+        sD39mu6vZ3p6//z7t98B3MNjhhIXHc+1Os81w3UOXN/UHB6YnsVtrWXwbte1
+        OzuBBMaQ2+eHXLO56GmP2/umQdokgzz2Yvh+uT4RLLS0htuxupbpVet9N7At
+        oe0fOlo3FEZgucLXtkfcxlvay9U7uwx/vR2GzbH9mbCC6v3/1r28uT4JruuG
+        osMjMx3tt24YaE94p2OJ3i63Q9OvnsoQ1XhzMooXisByTK0Wy7xtm1WGpbrr
+        9bR9M2h73CIcXAg34ENMTTdohrZNXrIzOhsZKsPiiQosQY0gqBF0EXgUwDJ8
+        CRmGgvGNafRHEZ5wjzsmOTLcXq6fbpHqCU0rCtKjCjK4gIsqssgxpAP34AGn
+        3HkGpe0GgevE4iyDZLgEQAQy5gjX2dfKcP113fNalzK55MbdXOqYXR7aAcOP
+        /3NX65OHGjXB1bNASXiHjjNqBi4oCMPZNZSOPasZXMN1BYt4l0F7k9FQOj6x
+        soQlaie92Xq61aw9ZChPJj07AGW/iVsKSrj9aif+y7lJuHNuhBUJq+eHVYlh
+        rStYw90MppBWkcAGw6XxzTXMgNMT5tQ/CecwSZOVRUSJCBhYP2ISZHxuRRxt
+        TXTKDD8Mjm6ogyM1kUvEy/zxEn9yYswXn+UGR8XEBqvIMjkTl6zMEJcqZvOp
+        POk3pv74OZ2Q07FWmtBezsnFmVinjizK0PJIiqBUWIQyP67m5IuZUEZvpHL+
+        IcZw6836T8IDhunx0d/t0/tL1dyOyXCxbgmzGTpt03sazbcInGtwe5fTxZE8
+        Uiotqyd4EHrEX/l6OBV1cWj5Fpm3/hmA9OM7bT2eZK+4ZVsBN/oNfjBKkNGF
+        ML2azX3fJLPackPPMLetyLYwCrk7kQ5l6plU1A+0LkRNRNJDkvhIv7CSn36B
+        S6v5GaJr+QLR9fxlor/EW7aJpumW5ml0fkn8ynATVNIg5vL0sZibpS8Rc3Mo
+        IolHcQQJ+iiGTOtXkT1FghK36CmaU3AFV4mPEDqUKk1rpZBKffcT1F9xY4DF
+        nUJqaigtD7BSL6SkoaSR1FhZXVt/gfIQ+g7RKSQvZLNxFYuEhN4GUZVqUVDA
+        NKVSsIQMVaUQ3jrZI9yluLJ5enbDtUZ7r1FVjTjsF2jSWieQFQr/3h6SOu7p
+        eF/HB/hQx0f4WMcnqO6B+djEp3uY9jHl474P1ce8j7yPz3zIPmZ9zPn43MfW
+        S5104ZQXCQAA
         """
     )
 
diff --git a/compose/material/material-ripple/api/current.txt b/compose/material/material-ripple/api/current.txt
index 6dba36f..273c732 100644
--- a/compose/material/material-ripple/api/current.txt
+++ b/compose/material/material-ripple/api/current.txt
@@ -14,23 +14,24 @@
   }
 
   public final class RippleKt {
-    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple(optional boolean bounded, optional float radius, optional long color);
+    method public static androidx.compose.ui.node.DelegatableNode createRippleModifierNode(androidx.compose.foundation.interaction.InteractionSource interactionSource, boolean bounded, float radius, androidx.compose.ui.graphics.ColorProducer color, kotlin.jvm.functions.Function0<androidx.compose.material.ripple.RippleAlpha> rippleAlpha);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple(optional boolean bounded, optional float radius, optional long color);
   }
 
-  public interface RippleTheme {
-    method @androidx.compose.runtime.Composable public long defaultColor();
-    method @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
-    field public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
+  @Deprecated public interface RippleTheme {
+    method @Deprecated @androidx.compose.runtime.Composable public long defaultColor();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
+    field @Deprecated public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
   }
 
-  public static final class RippleTheme.Companion {
-    method public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha(long contentColor, boolean lightTheme);
-    method public long defaultRippleColor(long contentColor, boolean lightTheme);
+  @Deprecated public static final class RippleTheme.Companion {
+    method @Deprecated public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha(long contentColor, boolean lightTheme);
+    method @Deprecated public long defaultRippleColor(long contentColor, boolean lightTheme);
   }
 
   public final class RippleThemeKt {
-    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
-    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> LocalRippleTheme;
+    method @Deprecated public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
+    property @Deprecated public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> LocalRippleTheme;
   }
 
 }
diff --git a/compose/material/material-ripple/api/restricted_current.txt b/compose/material/material-ripple/api/restricted_current.txt
index 6dba36f..273c732 100644
--- a/compose/material/material-ripple/api/restricted_current.txt
+++ b/compose/material/material-ripple/api/restricted_current.txt
@@ -14,23 +14,24 @@
   }
 
   public final class RippleKt {
-    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple(optional boolean bounded, optional float radius, optional long color);
+    method public static androidx.compose.ui.node.DelegatableNode createRippleModifierNode(androidx.compose.foundation.interaction.InteractionSource interactionSource, boolean bounded, float radius, androidx.compose.ui.graphics.ColorProducer color, kotlin.jvm.functions.Function0<androidx.compose.material.ripple.RippleAlpha> rippleAlpha);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple(optional boolean bounded, optional float radius, optional long color);
   }
 
-  public interface RippleTheme {
-    method @androidx.compose.runtime.Composable public long defaultColor();
-    method @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
-    field public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
+  @Deprecated public interface RippleTheme {
+    method @Deprecated @androidx.compose.runtime.Composable public long defaultColor();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
+    field @Deprecated public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
   }
 
-  public static final class RippleTheme.Companion {
-    method public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha(long contentColor, boolean lightTheme);
-    method public long defaultRippleColor(long contentColor, boolean lightTheme);
+  @Deprecated public static final class RippleTheme.Companion {
+    method @Deprecated public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha(long contentColor, boolean lightTheme);
+    method @Deprecated public long defaultRippleColor(long contentColor, boolean lightTheme);
   }
 
   public final class RippleThemeKt {
-    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
-    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> LocalRippleTheme;
+    method @Deprecated public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
+    property @Deprecated public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> LocalRippleTheme;
   }
 
 }
diff --git a/compose/material/material-ripple/benchmark/src/androidTest/java/androidx/compose/material/ripple/benchmark/RippleBenchmark.kt b/compose/material/material-ripple/benchmark/src/androidTest/java/androidx/compose/material/ripple/benchmark/RippleBenchmark.kt
index 958ec5cf..597fbd0 100644
--- a/compose/material/material-ripple/benchmark/src/androidTest/java/androidx/compose/material/ripple/benchmark/RippleBenchmark.kt
+++ b/compose/material/material-ripple/benchmark/src/androidTest/java/androidx/compose/material/ripple/benchmark/RippleBenchmark.kt
@@ -16,14 +16,17 @@
 
 package androidx.compose.material.ripple.benchmark
 
-import androidx.compose.foundation.Indication
+import androidx.compose.foundation.IndicationNodeFactory
+import androidx.compose.foundation.indication
 import androidx.compose.foundation.interaction.HoverInteraction
 import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
-import androidx.compose.material.ripple.rememberRipple
+import androidx.compose.material.ripple.RippleAlpha
+import androidx.compose.material.ripple.createRippleModifierNode
 import androidx.compose.runtime.Composable
 import androidx.compose.testutils.ComposeBenchmarkScope
 import androidx.compose.testutils.LayeredComposeTestCase
@@ -31,9 +34,12 @@
 import androidx.compose.testutils.benchmark.benchmarkFirstCompose
 import androidx.compose.testutils.doFramesUntilNoChangesPending
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.drawWithContent
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.node.DelegatableNode
 import androidx.compose.ui.platform.ViewRootForTest
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -53,71 +59,17 @@
     @get:Rule
     val benchmarkRule = ComposeBenchmarkRule()
 
-    /**
-     * Composition cost of rememberRipple() - this is just a remembered factory object so it
-     * doesn't do much.
-     */
     @Test
-    fun rememberRippleFirstComposition() {
+    fun firstComposition() {
+        val interactionSource = MutableInteractionSource()
         benchmarkRule.benchmarkFirstCompose {
             object : LayeredComposeTestCase() {
                 @Composable
                 override fun MeasuredContent() {
-                    rememberRipple()
-                }
-            }
-        }
-    }
-
-    /**
-     * Composition cost of creating a ripple instance - this is what actually allocates
-     * ripple-related machinery and is later responsible for drawing ripples.
-     */
-    @Test
-    fun initialRippleRememberUpdatedInstanceFirstComposition() {
-        benchmarkRule.benchmarkFirstCompose {
-            object : LayeredComposeTestCase() {
-                val interactionSource = MutableInteractionSource()
-                var ripple: Indication? = null
-
-                @Composable
-                override fun ContentWrappers(content: @Composable () -> Unit) {
-                    // Create a ripple from outside the measured content
-                    ripple = rememberRipple()
-                    content()
-                }
-
-                @Composable
-                override fun MeasuredContent() {
-                    ripple!!.rememberUpdatedInstance(interactionSource = interactionSource)
-                }
-            }
-        }
-    }
-
-    /**
-     * Composition cost of creating a second ripple instance, after one has already been created,
-     * discounting any first-ripple performance costs.
-     */
-    @Test
-    fun additionalRippleRememberUpdatedInstanceFirstComposition() {
-        benchmarkRule.benchmarkFirstCompose {
-            object : LayeredComposeTestCase() {
-                val interactionSource = MutableInteractionSource()
-                var ripple: Indication? = null
-
-                @Composable
-                override fun ContentWrappers(content: @Composable () -> Unit) {
-                    // Create a ripple from outside the measured content
-                    ripple = rememberRipple()
-                    // Create another ripple and call rememberUpdatedInstance()
-                    rememberRipple().rememberUpdatedInstance(interactionSource = interactionSource)
-                    content()
-                }
-
-                @Composable
-                override fun MeasuredContent() {
-                    ripple!!.rememberUpdatedInstance(interactionSource = interactionSource)
+                    Box(Modifier.indication(
+                        interactionSource = interactionSource,
+                        indication = TestRipple
+                    ))
                 }
             }
         }
@@ -260,24 +212,19 @@
 }
 
 /**
- * Test case for a manually-drawn ripple (no [androidx.compose.foundation.indication]) that allows
- * emitting [Interaction]s with [emitInteraction].
+ * Test case a ripple that allows emitting [Interaction]s with [emitInteraction].
  */
+@Suppress("DEPRECATION_ERROR")
 private class RippleInteractionTestCase : LayeredComposeTestCase() {
     private val interactionSource = MutableInteractionSource()
 
     @Composable
     override fun MeasuredContent() {
-        val instance = rememberRipple().rememberUpdatedInstance(interactionSource)
-
         Box(
             Modifier
                 .size(100.dp)
-                .drawWithContent {
-                    with(instance) {
-                        drawIndication()
-                    }
-                })
+                .indication(interactionSource, TestRipple)
+        )
     }
 
     suspend fun emitInteraction(interaction: Interaction) {
@@ -313,3 +260,47 @@
     // Still not stable
     throw AssertionError("Changes are still pending after '$maxAmountOfFrames' frames.")
 }
+
+private val TestRipple = TestIndicationNodeFactory({ TestRippleColor }, { TestRippleAlpha })
+
+private val TestRippleColor = Color.Red
+
+private val TestRippleAlpha = RippleAlpha(
+    draggedAlpha = 0.1f,
+    focusedAlpha = 0.2f,
+    hoveredAlpha = 0.3f,
+    pressedAlpha = 0.4f
+)
+
+private class TestIndicationNodeFactory(
+    private val color: ColorProducer,
+    private val rippleAlpha: () -> RippleAlpha
+) : IndicationNodeFactory {
+    override fun create(interactionSource: InteractionSource): DelegatableNode {
+        return createRippleModifierNode(
+            interactionSource = interactionSource,
+            bounded = true,
+            radius = Dp.Unspecified,
+            color = color,
+            rippleAlpha = rippleAlpha
+        )
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as TestIndicationNodeFactory
+
+        if (color != other.color) return false
+        if (rippleAlpha != other.rippleAlpha) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = color.hashCode()
+        result = 31 * result + rippleAlpha.hashCode()
+        return result
+    }
+}
diff --git a/compose/material/material-ripple/build.gradle b/compose/material/material-ripple/build.gradle
index 523195f..da5ee4a 100644
--- a/compose/material/material-ripple/build.gradle
+++ b/compose/material/material-ripple/build.gradle
@@ -36,6 +36,7 @@
                 api(project(":compose:foundation:foundation"))
                 api(project(":compose:runtime:runtime"))
 
+                implementation(project(":collection:collection"))
                 implementation(project(":compose:animation:animation"))
                 implementation(project(":compose:ui:ui-util"))
             }
diff --git a/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RememberRippleTest.kt b/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RememberRippleTest.kt
new file mode 100644
index 0000000..bdcc72a
--- /dev/null
+++ b/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RememberRippleTest.kt
@@ -0,0 +1,585 @@
+/*
+ * 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.compose.material.ripple
+
+import android.os.Build
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Indication
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.HoverInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.compositionLocalOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.asAndroidBitmap
+import androidx.compose.ui.graphics.compositeOver
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test for (the deprecated) [rememberRipple] and [RippleTheme] APIs to ensure no regressions.
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(
+    // Below P the press ripple is split into two layers with half alpha, and we multiply the alpha
+    // first so each layer will have the expected alpha to ensure that the minimum contrast in
+    // areas where the ripples don't overlap is still correct - as a result the colors aren't
+    // exactly what we expect here so we can't really reliably assert
+    minSdkVersion = Build.VERSION_CODES.P,
+    // On S and above, the press ripple is patterned and has inconsistent behaviour in terms of
+    // alpha, so it doesn't behave according to our expectations - we can't explicitly assert on the
+    // color.
+    maxSdkVersion = Build.VERSION_CODES.R
+)
+@Suppress("DEPRECATION_ERROR")
+class RememberRippleTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    private val TestRippleColor = Color.Red
+
+    private val TestRippleAlpha = RippleAlpha(
+        draggedAlpha = 0.1f,
+        focusedAlpha = 0.2f,
+        hoveredAlpha = 0.3f,
+        pressedAlpha = 0.4f
+    )
+
+    private val TestRippleTheme = object : RippleTheme {
+        @Deprecated("Super method is deprecated")
+        @Composable
+        override fun defaultColor() = TestRippleColor
+
+        @Deprecated("Super method is deprecated")
+        @Composable
+        override fun rippleAlpha() = TestRippleAlpha
+    }
+
+    @Test
+    fun pressed() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(LocalRippleTheme provides TestRippleTheme) {
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        rememberRipple(),
+                        bounded = true
+                    )
+                }
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.pressedAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
+            expectedColor
+        )
+    }
+
+    @Test
+    fun hovered() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(LocalRippleTheme provides TestRippleTheme) {
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        rememberRipple(),
+                        bounded = true
+                    )
+                }
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.hoveredAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            HoverInteraction.Enter(),
+            expectedColor
+        )
+    }
+
+    @Test
+    fun focused() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(LocalRippleTheme provides TestRippleTheme) {
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        rememberRipple(),
+                        bounded = true
+                    )
+                }
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.focusedAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            FocusInteraction.Focus(),
+            expectedColor
+        )
+    }
+
+    @Test
+    fun dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(LocalRippleTheme provides TestRippleTheme) {
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        rememberRipple(),
+                        bounded = true
+                    )
+                }
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.draggedAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            DragInteraction.Start(),
+            expectedColor
+        )
+    }
+
+    /**
+     * Test case for changing LocalRippleTheme during an existing ripple effect
+     *
+     * Note: no corresponding test for pressed ripples since RippleForeground does not update the
+     * color of currently active ripples unless they are being drawn on the UI thread
+     * (which should only happen if the target radius also changes).
+     */
+    @Test
+    fun themeChangeDuringRipple_dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        fun createRippleTheme(color: Color, alpha: Float) = object : RippleTheme {
+            val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
+            @Deprecated("Super method is deprecated")
+            @Composable
+            override fun defaultColor() = color
+
+            @Deprecated("Super method is deprecated")
+            @Composable
+            override fun rippleAlpha() = rippleAlpha
+        }
+
+        val initialColor = Color.Red
+        val initialAlpha = 0.5f
+
+        var rippleTheme by mutableStateOf(createRippleTheme(initialColor, initialAlpha))
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        rememberRipple(),
+                        bounded = true
+                    )
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    initialColor,
+                    rippleOpacity = initialAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newColor = Color.Green
+        // TODO: changing alpha for existing state layers is not currently supported
+        val newAlpha = 0.5f
+
+        rule.runOnUiThread {
+            rippleTheme = createRippleTheme(newColor, newAlpha)
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    newColor,
+                    rippleOpacity = newAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    /**
+     * Test case for changing a CompositionLocal consumed by the RippleTheme during an existing
+     * ripple effect
+     *
+     * Note: no corresponding test for pressed ripples since RippleForeground does not update the
+     * color of currently active ripples unless they are being drawn on the UI thread
+     * (which should only happen if the target radius also changes).
+     */
+    @Test
+    fun compositionLocalChangeDuringRipple_dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        val initialColor = Color.Red
+        var themeColor by mutableStateOf(initialColor)
+
+        val expectedAlpha = 0.5f
+        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
+
+        val localThemeColor = compositionLocalOf { Color.Unspecified }
+
+        val rippleTheme = object : RippleTheme {
+            @Deprecated("Super method is deprecated")
+            @Composable
+            override fun defaultColor() = localThemeColor.current
+
+            @Deprecated("Super method is deprecated")
+            @Composable
+            override fun rippleAlpha() = rippleAlpha
+        }
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(
+                LocalRippleTheme provides rippleTheme,
+                localThemeColor provides themeColor
+            ) {
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        rememberRipple(),
+                        bounded = true
+                    )
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    initialColor,
+                    rippleOpacity = expectedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newColor = Color.Green
+
+        rule.runOnUiThread {
+            themeColor = newColor
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    newColor,
+                    rippleOpacity = expectedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    /**
+     * Test case to ensure that CompositionLocals are queried at the place where the ripple is
+     * consumed, not where it is created (i.e, inside the component applying indication).
+     */
+    @Test
+    fun compositionLocalProvidedAfterRipple() {
+        val interactionSource = MutableInteractionSource()
+
+        val alpha = 0.5f
+        val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
+        val expectedRippleColor = Color.Red
+
+        val localThemeColor = compositionLocalOf { Color.Unspecified }
+
+        val rippleTheme = object : RippleTheme {
+            @Deprecated("Super method is deprecated")
+            @Composable
+            override fun defaultColor() = localThemeColor.current
+
+            @Deprecated("Super method is deprecated")
+            @Composable
+            override fun rippleAlpha() = rippleAlpha
+        }
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            CompositionLocalProvider(
+                LocalRippleTheme provides rippleTheme,
+                localThemeColor provides Color.Black
+            ) {
+                // Create ripple where localThemeColor is black
+                val ripple = rememberRipple()
+                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                    CompositionLocalProvider(localThemeColor provides expectedRippleColor) {
+                        // Ripple is used where localThemeColor is red, so the instance
+                        // should get the red color when it is created
+                        RippleBoxWithBackground(interactionSource, ripple, bounded = true)
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(PressInteraction.Press(Offset(10f, 10f)))
+            }
+        }
+
+        rule.waitForIdle()
+        // Ripples are drawn on the RenderThread, not the main (UI) thread, so we can't wait for
+        // synchronization. Instead just wait until after the ripples are finished animating.
+        @Suppress("BanThreadSleep")
+        Thread.sleep(300)
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    expectedRippleColor,
+                    rippleOpacity = alpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    /**
+     * Asserts that the resultant color of the ripple on screen matches [expectedCenterPixelColor].
+     *
+     * @param interactionSource the [MutableInteractionSource] driving the ripple
+     * @param interaction the [Interaction] to assert for
+     * @param expectedCenterPixelColor the expected color for the pixel at the center of the
+     * [RippleBoxWithBackground]
+     */
+    private fun assertRippleMatches(
+        scope: CoroutineScope,
+        interactionSource: MutableInteractionSource,
+        interaction: Interaction,
+        expectedCenterPixelColor: Color
+    ) {
+        // Pause the clock if we are drawing a state layer
+        if (interaction !is PressInteraction) {
+            rule.mainClock.autoAdvance = false
+        }
+
+        // Start ripple
+        rule.runOnIdle {
+            scope.launch {
+                interactionSource.emit(interaction)
+            }
+        }
+
+        // Advance to the end of the ripple / state layer animation
+        rule.waitForIdle()
+        @Suppress("BanThreadSleep")
+        if (interaction is PressInteraction) {
+            // Ripples are drawn on the RenderThread, not the main (UI) thread, so we can't wait for
+            // synchronization. Instead just wait until after the ripples are finished animating.
+            Thread.sleep(300)
+        } else {
+            rule.mainClock.advanceTimeBy(milliseconds = 300)
+        }
+
+        // Compare expected and actual pixel color
+        val centerPixel = rule.onNodeWithTag(Tag)
+            .captureToImage()
+            .asAndroidBitmap()
+            .run {
+                getPixel(width / 2, height / 2)
+            }
+
+        Truth.assertThat(Color(centerPixel)).isEqualTo(expectedCenterPixelColor)
+    }
+}
+
+/**
+ * Generic Button like component with a border that allows injecting an [Indication], and has a
+ * background with the same color around it - this makes the ripple contrast better and make it
+ * more visible in screenshots.
+ *
+ * @param interactionSource the [MutableInteractionSource] that is used to drive the ripple state
+ * @param ripple ripple [Indication] placed inside the surface
+ * @param bounded whether [ripple] is bounded or not - this controls the clipping behavior
+ */
+@Composable
+private fun RippleBoxWithBackground(
+    interactionSource: MutableInteractionSource,
+    ripple: Indication,
+    bounded: Boolean
+) {
+    Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
+        Box(
+            Modifier.padding(25.dp).background(RippleBoxBackgroundColor)
+        ) {
+            val shape = RoundedCornerShape(20)
+            // If the ripple is bounded, we want to clip to the shape, otherwise don't clip as
+            // the ripple should draw outside the bounds.
+            val clip = if (bounded) Modifier.clip(shape) else Modifier
+            Box(
+                Modifier.padding(25.dp).width(40.dp).height(40.dp)
+                    .border(BorderStroke(2.dp, Color.Black), shape)
+                    .background(color = RippleBoxBackgroundColor, shape = shape)
+                    .then(clip)
+                    .indication(
+                        interactionSource = interactionSource,
+                        indication = ripple
+                    )
+            ) {}
+        }
+    }
+}
+
+/**
+ * Blends ([contentColor] with [rippleOpacity]) on top of [RippleBoxBackgroundColor] to provide
+ * the resulting RGB color that can be used for pixel comparison.
+ */
+private fun calculateResultingRippleColor(
+    contentColor: Color,
+    rippleOpacity: Float
+) = contentColor.copy(alpha = rippleOpacity).compositeOver(RippleBoxBackgroundColor)
+
+private val RippleBoxBackgroundColor = Color.Blue
+
+private const val Tag = "Ripple"
diff --git a/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleContainerTest.kt b/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleContainerTest.kt
index 511207f..fcb8d67 100644
--- a/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleContainerTest.kt
+++ b/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleContainerTest.kt
@@ -17,10 +17,7 @@
 package androidx.compose.material.ripple
 
 import androidx.activity.ComponentActivity
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.compose.ui.unit.Dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth
@@ -43,7 +40,7 @@
         val activity = rule.activity
         val container = RippleContainer(activity)
 
-        val instance = createRippleIndicationInstance(container)
+        val instance = TestRippleHostKey()
 
         with(container) {
             val hostView = instance.getRippleHostView()
@@ -57,8 +54,8 @@
         val activity = rule.activity
         val container = RippleContainer(activity)
 
-        val instance1 = createRippleIndicationInstance(container)
-        val instance2 = createRippleIndicationInstance(container)
+        val instance1 = TestRippleHostKey()
+        val instance2 = TestRippleHostKey()
 
         with(container) {
             val hostView1 = instance1.getRippleHostView()
@@ -73,12 +70,12 @@
         val activity = rule.activity
         val container = RippleContainer(activity)
 
-        val instance1 = createRippleIndicationInstance(container)
-        val instance2 = createRippleIndicationInstance(container)
-        val instance3 = createRippleIndicationInstance(container)
-        val instance4 = createRippleIndicationInstance(container)
-        val instance5 = createRippleIndicationInstance(container)
-        val instance6 = createRippleIndicationInstance(container)
+        val instance1 = TestRippleHostKey()
+        val instance2 = TestRippleHostKey()
+        val instance3 = TestRippleHostKey()
+        val instance4 = TestRippleHostKey()
+        val instance5 = TestRippleHostKey()
+        val instance6 = TestRippleHostKey()
 
         with(container) {
             // Assign the maximum number of host views
@@ -109,12 +106,12 @@
         val activity = rule.activity
         val container = RippleContainer(activity)
 
-        val instance1 = createRippleIndicationInstance(container)
-        val instance2 = createRippleIndicationInstance(container)
-        val instance3 = createRippleIndicationInstance(container)
-        val instance4 = createRippleIndicationInstance(container)
-        val instance5 = createRippleIndicationInstance(container)
-        val instance6 = createRippleIndicationInstance(container)
+        val instance1 = TestRippleHostKey()
+        val instance2 = TestRippleHostKey()
+        val instance3 = TestRippleHostKey()
+        val instance4 = TestRippleHostKey()
+        val instance5 = TestRippleHostKey()
+        val instance6 = TestRippleHostKey()
 
         with(container) {
             // Assign some initial views
@@ -148,11 +145,7 @@
     }
 }
 
-private fun createRippleIndicationInstance(container: RippleContainer) =
-    AndroidRippleIndicationInstance(
-        true,
-        Dp.Unspecified,
-        mutableStateOf(Color.Black),
-        mutableStateOf(RippleAlpha(1f, 1f, 1f, 1f)),
-        container
-    )
+private class TestRippleHostKey : RippleHostKey {
+    override fun onResetRippleHostView() {
+    }
+}
diff --git a/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleModifierNodeTest.kt b/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleModifierNodeTest.kt
new file mode 100644
index 0000000..a108a27
--- /dev/null
+++ b/compose/material/material-ripple/src/androidInstrumentedTest/kotlin/androidx/compose/material/ripple/RippleModifierNodeTest.kt
@@ -0,0 +1,523 @@
+/*
+ * 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.compose.material.ripple
+
+import android.os.Build
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Indication
+import androidx.compose.foundation.IndicationNodeFactory
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.FocusInteraction
+import androidx.compose.foundation.interaction.HoverInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.graphics.asAndroidBitmap
+import androidx.compose.ui.graphics.compositeOver
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test for [createRippleModifierNode].
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(
+    // Below P the press ripple is split into two layers with half alpha, and we multiply the alpha
+    // first so each layer will have the expected alpha to ensure that the minimum contrast in
+    // areas where the ripples don't overlap is still correct - as a result the colors aren't
+    // exactly what we expect here so we can't really reliably assert
+    minSdkVersion = Build.VERSION_CODES.P,
+    // On S and above, the press ripple is patterned and has inconsistent behaviour in terms of
+    // alpha, so it doesn't behave according to our expectations - we can't explicitly assert on the
+    // color.
+    maxSdkVersion = Build.VERSION_CODES.R
+)
+class RippleModifierNodeTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    private val TestRipple = TestIndicationNodeFactory({ TestRippleColor }, { TestRippleAlpha })
+
+    private class TestIndicationNodeFactory(
+        private val color: ColorProducer,
+        private val rippleAlpha: () -> RippleAlpha
+    ) : IndicationNodeFactory {
+        override fun create(interactionSource: InteractionSource): DelegatableNode {
+            return createRippleModifierNode(
+                interactionSource = interactionSource,
+                bounded = true,
+                radius = Dp.Unspecified,
+                color = color,
+                rippleAlpha = rippleAlpha
+            )
+        }
+
+        override fun equals(other: Any?): Boolean {
+            if (this === other) return true
+            if (javaClass != other?.javaClass) return false
+
+            other as TestIndicationNodeFactory
+
+            if (color != other.color) return false
+            if (rippleAlpha != other.rippleAlpha) return false
+
+            return true
+        }
+
+        override fun hashCode(): Int {
+            var result = color.hashCode()
+            result = 31 * result + rippleAlpha.hashCode()
+            return result
+        }
+    }
+
+    @Test
+    fun pressed() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                RippleBoxWithBackground(
+                    interactionSource,
+                    TestRipple,
+                    bounded = true
+                )
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.pressedAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
+            expectedColor
+        )
+    }
+
+    @Test
+    fun hovered() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                RippleBoxWithBackground(
+                    interactionSource,
+                    TestRipple,
+                    bounded = true
+                )
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.hoveredAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            HoverInteraction.Enter(),
+            expectedColor
+        )
+    }
+
+    @Test
+    fun focused() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                RippleBoxWithBackground(
+                    interactionSource,
+                    TestRipple,
+                    bounded = true
+                )
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.focusedAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            FocusInteraction.Focus(),
+            expectedColor
+        )
+    }
+
+    @Test
+    fun dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                RippleBoxWithBackground(
+                    interactionSource,
+                    TestRipple,
+                    bounded = true
+                )
+            }
+        }
+
+        val expectedColor = calculateResultingRippleColor(
+            TestRippleColor,
+            rippleOpacity = TestRippleAlpha.draggedAlpha
+        )
+
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            DragInteraction.Start(),
+            expectedColor
+        )
+    }
+
+    /**
+     * Test case for changing a color captured by the color lambda during an existing ripple effect
+     *
+     * Note: no corresponding test for pressed ripples since RippleForeground does not update the
+     * color of currently active ripples unless they are being drawn on the UI thread
+     * (which should only happen if the target radius also changes).
+     */
+    @Test
+    fun colorChangeDuringRipple_dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        val initialColor = Color.Red
+        var themeColor by mutableStateOf(initialColor)
+
+        var scope: CoroutineScope? = null
+
+        val ripple = TestIndicationNodeFactory({ themeColor }, { TestRippleAlpha })
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                RippleBoxWithBackground(
+                    interactionSource,
+                    ripple,
+                    bounded = true
+                )
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    initialColor,
+                    rippleOpacity = TestRippleAlpha.draggedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newColor = Color.Green
+
+        rule.runOnUiThread {
+            themeColor = newColor
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    newColor,
+                    rippleOpacity = TestRippleAlpha.draggedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    /**
+     * Test case for changing the ripple alpha captured by the ripple alpha lambda. Currently this
+     * is only reflected when moving to a new state layer, we don't dynamically retarget existing
+     * interactions (this should be a very rare case).
+     *
+     * Note: no corresponding test for pressed ripples since RippleForeground does not update the
+     * alpha of currently active ripples unless they are being drawn on the UI thread
+     * (which should only happen if the target radius also changes).
+     */
+    @Test
+    fun rippleAlphaChange() {
+        val interactionSource = MutableInteractionSource()
+
+        var rippleAlpha by mutableStateOf(TestRippleAlpha)
+
+        var scope: CoroutineScope? = null
+
+        val ripple = TestIndicationNodeFactory({ TestRippleColor }, { rippleAlpha })
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                RippleBoxWithBackground(
+                    interactionSource,
+                    ripple,
+                    bounded = true
+                )
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    TestRippleColor,
+                    rippleOpacity = TestRippleAlpha.draggedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newRippleAlpha = RippleAlpha(0.5f, 0.5f, 0.5f, 0.5f)
+
+        rule.runOnUiThread {
+            rippleAlpha = newRippleAlpha
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            // Alpha shouldn't have changed, since we don't retarget existing interactions
+            val expectedColor =
+                calculateResultingRippleColor(
+                    TestRippleColor,
+                    rippleOpacity = TestRippleAlpha.draggedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(FocusInteraction.Focus())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            // Now that we animate to a new state layer, the new ripple alpha should be used
+            val expectedColor =
+                calculateResultingRippleColor(
+                    TestRippleColor,
+                    rippleOpacity = newRippleAlpha.focusedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    /**
+     * Asserts that the resultant color of the ripple on screen matches [expectedCenterPixelColor].
+     *
+     * @param interactionSource the [MutableInteractionSource] driving the ripple
+     * @param interaction the [Interaction] to assert for
+     * @param expectedCenterPixelColor the expected color for the pixel at the center of the
+     * [RippleBoxWithBackground]
+     */
+    private fun assertRippleMatches(
+        scope: CoroutineScope,
+        interactionSource: MutableInteractionSource,
+        interaction: Interaction,
+        expectedCenterPixelColor: Color
+    ) {
+        // Pause the clock if we are drawing a state layer
+        if (interaction !is PressInteraction) {
+            rule.mainClock.autoAdvance = false
+        }
+
+        // Start ripple
+        rule.runOnIdle {
+            scope.launch {
+                interactionSource.emit(interaction)
+            }
+        }
+
+        // Advance to the end of the ripple / state layer animation
+        rule.waitForIdle()
+        @Suppress("BanThreadSleep")
+        if (interaction is PressInteraction) {
+            // Ripples are drawn on the RenderThread, not the main (UI) thread, so we can't wait for
+            // synchronization. Instead just wait until after the ripples are finished animating.
+            Thread.sleep(300)
+        } else {
+            rule.mainClock.advanceTimeBy(milliseconds = 300)
+        }
+
+        // Compare expected and actual pixel color
+        val centerPixel = rule.onNodeWithTag(Tag)
+            .captureToImage()
+            .asAndroidBitmap()
+            .run {
+                getPixel(width / 2, height / 2)
+            }
+
+        Truth.assertThat(Color(centerPixel)).isEqualTo(expectedCenterPixelColor)
+    }
+}
+
+/**
+ * Generic Button like component with a border that allows injecting an [Indication], and has a
+ * background with the same color around it - this makes the ripple contrast better and make it
+ * more visible in screenshots.
+ *
+ * @param interactionSource the [MutableInteractionSource] that is used to drive the ripple state
+ * @param ripple ripple [Indication] placed inside the surface
+ * @param bounded whether [ripple] is bounded or not - this controls the clipping behavior
+ */
+@Composable
+private fun RippleBoxWithBackground(
+    interactionSource: MutableInteractionSource,
+    ripple: Indication,
+    bounded: Boolean
+) {
+    Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
+        Box(
+            Modifier.padding(25.dp).background(RippleBoxBackgroundColor)
+        ) {
+            val shape = RoundedCornerShape(20)
+            // If the ripple is bounded, we want to clip to the shape, otherwise don't clip as
+            // the ripple should draw outside the bounds.
+            val clip = if (bounded) Modifier.clip(shape) else Modifier
+            Box(
+                Modifier.padding(25.dp).width(40.dp).height(40.dp)
+                    .border(BorderStroke(2.dp, Color.Black), shape)
+                    .background(color = RippleBoxBackgroundColor, shape = shape)
+                    .then(clip)
+                    .indication(
+                        interactionSource = interactionSource,
+                        indication = ripple
+                    )
+            ) {}
+        }
+    }
+}
+
+/**
+ * Blends ([contentColor] with [rippleOpacity]) on top of [RippleBoxBackgroundColor] to provide
+ * the resulting RGB color that can be used for pixel comparison.
+ */
+private fun calculateResultingRippleColor(
+    contentColor: Color,
+    rippleOpacity: Float
+) = contentColor.copy(alpha = rippleOpacity).compositeOver(RippleBoxBackgroundColor)
+
+private val TestRippleColor = Color.Red
+
+private val TestRippleAlpha = RippleAlpha(
+    draggedAlpha = 0.1f,
+    focusedAlpha = 0.2f,
+    hoveredAlpha = 0.3f,
+    pressedAlpha = 0.4f
+)
+
+private val RippleBoxBackgroundColor = Color.Blue
+
+private const val Tag = "Ripple"
diff --git a/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt b/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt
index 432839a..6eaccdb 100644
--- a/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt
+++ b/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt
@@ -31,9 +31,14 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
 import androidx.compose.ui.graphics.nativeCanvas
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.node.invalidateDraw
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.isUnspecified
@@ -46,8 +51,32 @@
  * allows the ripple to animate smoothly even while the UI thread is under heavy load, such as
  * when navigating between complex screens.
  *
+ * @see RippleNode
+ */
+internal actual fun createPlatformRippleNode(
+    interactionSource: InteractionSource,
+    bounded: Boolean,
+    radius: Dp,
+    color: ColorProducer,
+    rippleAlpha: () -> RippleAlpha
+): DelegatableNode {
+    return if (IsRunningInPreview) {
+        CommonRippleNode(interactionSource, bounded, radius, color, rippleAlpha)
+    } else {
+        AndroidRippleNode(interactionSource, bounded, radius, color, rippleAlpha)
+    }
+}
+
+/**
+ * Android specific Ripple implementation that uses a [RippleDrawable] under the hood, which allows
+ * rendering the ripple animation on the render thread (away from the main UI thread). This
+ * allows the ripple to animate smoothly even while the UI thread is under heavy load, such as
+ * when navigating between complex screens.
+ *
  * @see Ripple
  */
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
 @Stable
 internal actual class PlatformRipple actual constructor(
     bounded: Boolean,
@@ -62,41 +91,108 @@
         color: State<Color>,
         rippleAlpha: State<RippleAlpha>
     ): RippleIndicationInstance {
-        val view = findNearestViewGroup()
-        // TODO(b/188112048): Remove isInEditMode once RenderThread support is fixed in Layoutlib.
-        if (view.isInEditMode) {
-            return remember(interactionSource, this) {
-                CommonRippleIndicationInstance(bounded, radius, color, rippleAlpha)
-            }
-        }
-
+        val view = findNearestViewGroup(LocalView.current)
         return remember(interactionSource, this, view) {
             AndroidRippleIndicationInstance(bounded, radius, color, rippleAlpha, view)
         }
     }
+}
+
+/**
+ * Android specific [RippleNode]. This uses a [RippleHostView] provided by [rippleContainer] to
+ * draw ripples in the drawing bounds provided within [draw].
+ *
+ * The state layer is still handled by [stateLayer], and drawn inside Compose.
+ */
+internal class AndroidRippleNode(
+    interactionSource: InteractionSource,
+    bounded: Boolean,
+    radius: Dp,
+    color: ColorProducer,
+    rippleAlpha: () -> RippleAlpha
+) : RippleNode(interactionSource, bounded, radius, color, rippleAlpha), RippleHostKey {
+    /**
+     * [RippleContainer] attached to the nearest [ViewGroup]. If it hasn't already been
+     * created by a another ripple, we will create it and attach it to the hierarchy.
+     */
+    private var rippleContainer: RippleContainer? = null
 
     /**
-     * Returns [LocalView] if it is a [ViewGroup], otherwise the nearest parent [ViewGroup] that
-     * we will add a [RippleContainer] to.
-     *
-     * In all normal scenarios this should just be [LocalView], but since [LocalView] is public
-     * API theoretically its value can be overridden with a non-[ViewGroup], so we walk up the
-     * tree to be safe.
+     * Backing [RippleHostView] used to draw ripples for this [RippleIndicationInstance].
      */
-    @Composable
-    private fun findNearestViewGroup(): ViewGroup {
-        var view: View = LocalView.current
-        while (view !is ViewGroup) {
-            val parent = view.parent
-            // We should never get to a ViewParent that isn't a View, without finding a ViewGroup
-            // first - throw an exception if we do.
-            require(parent is View) {
-                "Couldn't find a valid parent for $view. Are you overriding LocalView and " +
-                    "providing a View that is not attached to the view hierarchy?"
-            }
-            view = parent
+    private var rippleHostView: RippleHostView? = null
+        set(value) {
+            field = value
+            invalidateDraw()
         }
-        return view
+
+    /**
+     * Cache the size of the canvas we will draw the ripple into - this is updated each time
+     * [draw] is called. This is needed as before we start animating the ripple, we
+     * need to know its size (changing the bounds mid-animation will cause us to continue the
+     * animation on the UI thread, not the render thread), but the size is only known inside the
+     * draw scope.
+     */
+    private var rippleSize: Size = Size.Zero
+
+    override fun DrawScope.drawRipples() {
+        rippleSize = size
+
+        drawIntoCanvas { canvas ->
+            rippleHostView?.run {
+                // We set these inside addRipple() already, but they may change during the ripple
+                // animation, so update them here too.
+                // Note that changes to color / alpha will not be reflected in any
+                // currently drawn ripples if the ripples are being drawn on the RenderThread,
+                // since only the software paint is updated, not the hardware paint used in
+                // RippleForeground.
+                updateRippleProperties(
+                    size = size,
+                    radius = targetRadius.roundToInt(),
+                    color = rippleColor,
+                    alpha = rippleAlpha().pressedAlpha
+                )
+
+                draw(canvas.nativeCanvas)
+            }
+        }
+    }
+
+    override fun addRipple(interaction: PressInteraction.Press) {
+        rippleHostView = with(getOrCreateRippleContainer()) {
+            getRippleHostView().apply {
+                addRipple(
+                    interaction = interaction,
+                    bounded = bounded,
+                    size = rippleSize,
+                    radius = targetRadius.roundToInt(),
+                    color = rippleColor,
+                    alpha = rippleAlpha().pressedAlpha,
+                    onInvalidateRipple = { invalidateDraw() }
+                )
+            }
+        }
+    }
+
+    override fun removeRipple(interaction: PressInteraction.Press) {
+        rippleHostView?.removeRipple()
+    }
+
+    override fun onDetach() {
+        rippleContainer?.run {
+            disposeRippleIfNeeded()
+        }
+    }
+
+    override fun onResetRippleHostView() {
+        rippleHostView = null
+    }
+
+    private fun getOrCreateRippleContainer(): RippleContainer {
+        if (rippleContainer != null) return rippleContainer!!
+        val view = findNearestViewGroup(currentValueOf(LocalView))
+        rippleContainer = createAndAttachRippleContainerIfNeeded(view)
+        return rippleContainer!!
     }
 }
 
@@ -106,13 +202,15 @@
  *
  * The state layer is still handled by [drawStateLayer], and drawn inside Compose.
  */
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
 internal class AndroidRippleIndicationInstance(
     private val bounded: Boolean,
     private val radius: Dp,
     private val color: State<Color>,
     private val rippleAlpha: State<RippleAlpha>,
     private val view: ViewGroup
-) : RippleIndicationInstance(bounded, rippleAlpha), RememberObserver {
+) : RippleIndicationInstance(bounded, rippleAlpha), RememberObserver, RippleHostKey {
     /**
      * [RippleContainer] attached to the nearest [ViewGroup]: [view]. If it hasn't already been
      * created by a another ripple, we will create it and attach it to the hierarchy.
@@ -230,33 +328,60 @@
         }
     }
 
-    /**
-     * Remove the reference to the existing host view, so we don't incorrectly draw if it is
-     * recycled and used by another [RippleIndicationInstance].
-     */
-    fun resetHostView() {
+    override fun onResetRippleHostView() {
         rippleHostView = null
     }
 
     private fun getOrCreateRippleContainer(): RippleContainer {
         if (rippleContainer != null) return rippleContainer!!
-
-        // Find existing RippleContainer in the view hierarchy
-        for (index in 0 until view.childCount) {
-            val child = view.getChildAt(index)
-            if (child is RippleContainer) {
-                rippleContainer = child
-                break
-            }
-        }
-
-        // Create a new RippleContainer if needed
-        if (rippleContainer == null) {
-            rippleContainer = RippleContainer(view.context).apply {
-                view.addView(this)
-            }
-        }
-
+        rippleContainer = createAndAttachRippleContainerIfNeeded(view)
         return rippleContainer!!
     }
 }
+
+private fun createAndAttachRippleContainerIfNeeded(view: ViewGroup): RippleContainer {
+    // Try to find existing RippleContainer in the view hierarchy
+    for (index in 0 until view.childCount) {
+        val child = view.getChildAt(index)
+        if (child is RippleContainer) {
+            return child
+        }
+    }
+
+    // Create a new RippleContainer if needed and add to the hierarchy
+    return RippleContainer(view.context).apply {
+        view.addView(this)
+    }
+}
+
+/**
+ * Returns [initialView] if it is a [ViewGroup], otherwise the nearest parent [ViewGroup] that
+ * we will add a [RippleContainer] to.
+ *
+ * In all normal scenarios this should just be [LocalView], but since [LocalView] is public
+ * API theoretically its value can be overridden with a non-[ViewGroup], so we walk up the
+ * tree to be safe.
+ */
+private fun findNearestViewGroup(initialView: View): ViewGroup {
+    var view: View = initialView
+    while (view !is ViewGroup) {
+        val parent = view.parent
+        // We should never get to a ViewParent that isn't a View, without finding a ViewGroup
+        // first - throw an exception if we do.
+        require(parent is View) {
+            "Couldn't find a valid parent for $view. Are you overriding LocalView and " +
+                "providing a View that is not attached to the view hierarchy?"
+        }
+        view = parent
+    }
+    return view
+}
+
+/**
+ * Whether we are running in a preview or not, to control using the native vs the common ripple
+ * implementation. We check this way instead of using [View.isInEditMode] or LocalInspectionMode so
+ * this can be called from outside composition.
+ */
+// TODO(b/188112048): Remove in the future when more versions of Studio support previewing native
+//  ripples
+private val IsRunningInPreview = android.os.Build.DEVICE == "layoutlib"
diff --git a/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/RippleContainer.android.kt b/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/RippleContainer.android.kt
index 6571a8c..b69c886 100644
--- a/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/RippleContainer.android.kt
+++ b/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/RippleContainer.android.kt
@@ -20,6 +20,14 @@
 import android.view.ViewGroup
 import androidx.compose.ui.R
 
+internal interface RippleHostKey {
+    /**
+     * Called when the [RippleHostView] associated with this RippleHostKey is reset and no longer
+     * associated to this key. Implementers should remove any references to the [RippleHostView].
+     */
+    fun onResetRippleHostView()
+}
+
 /**
  * A root-level container [ViewGroup] that manages creating and assigning [RippleHostView]s used
  * throughout a Compose hierarchy. Each root Compose View that has components that use ripples
@@ -33,14 +41,14 @@
     private val MaxRippleHosts = 5
 
     /**
-     * [RippleHostView]s that will be assigned to [AndroidRippleIndicationInstance]s when
+     * [RippleHostView]s that will be assigned to [RippleHostKey]s when
      * necessary.
      */
     private val rippleHosts = mutableListOf<RippleHostView>()
 
     /**
      * [RippleHostView]s that are not currently assigned to any
-     * [AndroidRippleIndicationInstance], so they can be reused without needing to allocate new
+     * [RippleHostKey], so they can be reused without needing to allocate new
      * instances.
      */
     private val unusedRippleHosts = mutableListOf<RippleHostView>()
@@ -80,10 +88,10 @@
     }
 
     /**
-     * @return a [RippleHostView] for [this] [AndroidRippleIndicationInstance]. This result will
+     * @return a [RippleHostView] for [this] [RippleHostKey]. This result will
      * be cached if possible, to allow re-using the same [RippleHostView].
      */
-    fun AndroidRippleIndicationInstance.getRippleHostView(): RippleHostView {
+    fun RippleHostKey.getRippleHostView(): RippleHostView {
         val existingRippleHostView = rippleHostMap[this]
         if (existingRippleHostView != null) {
             return existingRippleHostView
@@ -115,7 +123,7 @@
                 //  Consider checking to see if the existing ripple is still drawing, and if so,
                 //  create a new RippleHostView one instead of reassigning
                 if (existingInstance != null) {
-                    existingInstance.resetHostView()
+                    existingInstance.onResetRippleHostView()
                     rippleHostMap.remove(existingInstance)
                     host.disposeRipple()
                 }
@@ -136,11 +144,11 @@
     }
 
     /**
-     * Unassigns the current [RippleHostView] from [this] [AndroidRippleIndicationInstance] and
-     * resets its state, so it can be used by another [AndroidRippleIndicationInstance].
+     * Unassigns the current [RippleHostView] from [this] [RippleHostKey] and
+     * resets its state, so it can be used by another [RippleHostKey].
      */
-    fun AndroidRippleIndicationInstance.disposeRippleIfNeeded() {
-        resetHostView()
+    fun RippleHostKey.disposeRippleIfNeeded() {
+        onResetRippleHostView()
         val rippleHost = rippleHostMap[this]
 
         if (rippleHost != null) {
@@ -153,31 +161,31 @@
 }
 
 /**
- * Simple bidirectional map for [AndroidRippleIndicationInstance] : [RippleHostView].
+ * Simple bidirectional map for [RippleHostKey] : [RippleHostView].
  */
 private class RippleHostMap {
     private val indicationToHostMap =
-        mutableMapOf<AndroidRippleIndicationInstance, RippleHostView>()
+        mutableMapOf<RippleHostKey, RippleHostView>()
     private val hostToIndicationMap =
-        mutableMapOf<RippleHostView, AndroidRippleIndicationInstance>()
+        mutableMapOf<RippleHostView, RippleHostKey>()
 
     operator fun set(
-        indicationInstance: AndroidRippleIndicationInstance,
+        indicationInstance: RippleHostKey,
         rippleHostView: RippleHostView
     ) {
         indicationToHostMap[indicationInstance] = rippleHostView
         hostToIndicationMap[rippleHostView] = indicationInstance
     }
 
-    operator fun get(indicationInstance: AndroidRippleIndicationInstance): RippleHostView? {
+    operator fun get(indicationInstance: RippleHostKey): RippleHostView? {
         return indicationToHostMap[indicationInstance]
     }
 
-    operator fun get(rippleHostView: RippleHostView): AndroidRippleIndicationInstance? {
+    operator fun get(rippleHostView: RippleHostView): RippleHostKey? {
         return hostToIndicationMap[rippleHostView]
     }
 
-    fun remove(indicationInstance: AndroidRippleIndicationInstance) {
+    fun remove(indicationInstance: RippleHostKey) {
         indicationToHostMap[indicationInstance]?.let { hostToIndicationMap.remove(it) }
         indicationToHostMap.remove(indicationInstance)
     }
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/CommonRipple.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/CommonRipple.kt
index 5e2fda1..112c2be 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/CommonRipple.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/CommonRipple.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.material.ripple
 
+import androidx.collection.MutableScatterMap
 import androidx.compose.foundation.interaction.InteractionSource
 import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.runtime.Composable
@@ -25,9 +26,12 @@
 import androidx.compose.runtime.mutableStateMapOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.node.invalidateDraw
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.isUnspecified
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
@@ -37,6 +41,8 @@
  *
  * @see Ripple
  */
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
 @Stable
 internal class CommonRipple(
     bounded: Boolean,
@@ -57,7 +63,59 @@
     }
 }
 
-internal class CommonRippleIndicationInstance constructor(
+internal class CommonRippleNode(
+    interactionSource: InteractionSource,
+    bounded: Boolean,
+    radius: Dp,
+    color: ColorProducer,
+    rippleAlpha: () -> RippleAlpha
+) : RippleNode(interactionSource, bounded, radius, color, rippleAlpha) {
+    private val ripples = MutableScatterMap<PressInteraction.Press, RippleAnimation>()
+
+    override fun addRipple(interaction: PressInteraction.Press) {
+        // Finish existing ripples
+        ripples.forEach { _, ripple -> ripple.finish() }
+        val origin = if (bounded) interaction.pressPosition else null
+        val rippleAnimation = RippleAnimation(
+            origin = origin,
+            radius = targetRadius,
+            bounded = bounded
+        )
+        ripples[interaction] = rippleAnimation
+        coroutineScope.launch {
+            try {
+                rippleAnimation.animate()
+            } finally {
+                ripples.remove(interaction)
+                invalidateDraw()
+            }
+        }
+        invalidateDraw()
+    }
+
+    override fun removeRipple(interaction: PressInteraction.Press) {
+        ripples[interaction]?.finish()
+    }
+
+    override fun DrawScope.drawRipples() {
+        val alpha = rippleAlpha().pressedAlpha
+        if (alpha != 0f) {
+            ripples.forEach { _, ripple ->
+                with(ripple) {
+                    draw(rippleColor.copy(alpha = alpha))
+                }
+            }
+        }
+    }
+
+    override fun onDetach() {
+        ripples.clear()
+    }
+}
+
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
+private class CommonRippleIndicationInstance(
     private val bounded: Boolean,
     private val radius: Dp,
     private val color: State<Color>,
@@ -65,7 +123,14 @@
 ) : RippleIndicationInstance(bounded, rippleAlpha), RememberObserver {
     private val ripples = mutableStateMapOf<PressInteraction.Press, RippleAnimation>()
 
+    private var targetRadius = Float.NaN
+
     override fun ContentDrawScope.drawIndication() {
+        targetRadius = if (radius.isUnspecified) {
+            getRippleEndRadius(bounded, size)
+        } else {
+            radius.toPx()
+        }
         val color = color.value
         drawContent()
         drawStateLayer(radius, color)
@@ -78,7 +143,7 @@
         val origin = if (bounded) interaction.pressPosition else null
         val rippleAnimation = RippleAnimation(
             origin = origin,
-            radius = radius,
+            radius = targetRadius,
             bounded = bounded
         )
         ripples[interaction] = rippleAnimation
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt
index f36c574..a0b60c9 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/Ripple.kt
@@ -21,7 +21,6 @@
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.foundation.Indication
-import androidx.compose.foundation.IndicationInstance
 import androidx.compose.foundation.interaction.DragInteraction
 import androidx.compose.foundation.interaction.FocusInteraction
 import androidx.compose.foundation.interaction.HoverInteraction
@@ -34,17 +33,61 @@
 import androidx.compose.runtime.State
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.graphics.drawscope.clipRect
 import androidx.compose.ui.graphics.isSpecified
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.invalidateDraw
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.isUnspecified
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 
 /**
+ * Creates a Ripple node using the values provided.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new [RippleAnimation], and
+ * responds to other [Interaction]s by showing a fixed [StateLayer] with varying alpha values
+ * depending on the [Interaction].
+ *
+ * This Ripple node is a low level building block for building IndicationNodeFactory implementations
+ * that use a Ripple - higher level design system libraries such as material and material3 provide
+ * [Indication] implementations using this node internally. In most cases you should use those
+ * factories directly: this node exists for design system libraries to delegate their Ripple
+ * implementation to, after querying any required theme values for customizing the Ripple.
+ *
+ * @param interactionSource the [InteractionSource] used to determine the state of the ripple.
+ * @param bounded if true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have [rippleAlpha] applied to calculate the
+ * final color used to draw the ripple.
+ * @param rippleAlpha the [RippleAlpha] that will be applied to the [color] depending on the state
+ * of the ripple.
+ */
+public fun createRippleModifierNode(
+    interactionSource: InteractionSource,
+    bounded: Boolean,
+    radius: Dp,
+    color: ColorProducer,
+    rippleAlpha: () -> RippleAlpha
+): DelegatableNode {
+    return createPlatformRippleNode(interactionSource, bounded, radius, color, rippleAlpha)
+}
+
+/**
  * Creates and [remember]s a Ripple using values provided by [RippleTheme].
  *
  * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
@@ -73,6 +116,17 @@
  * calculate the final color used to draw the ripple. If [Color.Unspecified] is provided the color
  * used will be [RippleTheme.defaultColor] instead.
  */
+@Deprecated(
+    "rememberRipple has been deprecated - it returns an old Indication " +
+        "implementation that is not compatible with the new Indication APIs that provide notable " +
+        "performance improvements. Instead, use the new ripple APIs provided by design system " +
+        "libraries, such as material and material3. If you are implementing your own design " +
+        "system library, use createRippleNode to create your own custom ripple implementation " +
+        "that queries your own theme values. For a migration guide and background " +
+        "information, please visit developer.android.com",
+    level = DeprecationLevel.ERROR
+)
+@Suppress("DEPRECATION", "TYPEALIAS_EXPANSION_DEPRECATION")
 @Composable
 public fun rememberRipple(
     bounded: Boolean = true,
@@ -86,6 +140,17 @@
 }
 
 /**
+ * Creates the platform specific [RippleNode] implementation.
+ */
+internal expect fun createPlatformRippleNode(
+    interactionSource: InteractionSource,
+    bounded: Boolean,
+    radius: Dp,
+    color: ColorProducer,
+    rippleAlpha: () -> RippleAlpha
+): DelegatableNode
+
+/**
  * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
  * by drawing ripple animations and state layers.
  *
@@ -104,24 +169,30 @@
  *
  * Ripple is provided on different platforms using [PlatformRipple].
  */
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
 @Stable
 internal abstract class Ripple(
     private val bounded: Boolean,
     private val radius: Dp,
     private val color: State<Color>
 ) : Indication {
+    @Suppress("DEPRECATION_ERROR")
+    @Deprecated("Super method is deprecated")
     @Composable
     final override fun rememberUpdatedInstance(
         interactionSource: InteractionSource
-    ): IndicationInstance {
+    ): androidx.compose.foundation.IndicationInstance {
         val theme = LocalRippleTheme.current
         val color = rememberUpdatedState(
             if (color.value.isSpecified) {
                 color.value
             } else {
+                @Suppress("DEPRECATION_ERROR")
                 theme.defaultColor()
             }
         )
+        @Suppress("DEPRECATION_ERROR")
         val rippleAlpha = rememberUpdatedState(theme.rippleAlpha())
 
         val instance = rememberUpdatedRippleInstance(
@@ -180,6 +251,8 @@
  * Platform-specific implementation of [Ripple]. This is needed as expect classes cannot
  * (currently) have default implementations, otherwise we would make [Ripple] the expect class.
  */
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
 @Stable
 internal expect class PlatformRipple(
     bounded: Boolean,
@@ -197,15 +270,18 @@
 }
 
 /**
- * Abstract [IndicationInstance] that provides common functionality used by [PlatformRipple]
- * implementations. Implementing classes should call [drawStateLayer] to draw the [StateLayer], so
- * they only need to handle showing the ripple effect when pressed, and not other [Interaction]s.
+ * Abstract [androidx.compose.foundation.IndicationInstance] that provides common functionality
+ * used by [PlatformRipple] implementations. Implementing classes should call [drawStateLayer] to
+ * draw the [StateLayer], so they only need to handle showing the ripple effect when pressed, and
+ * not other [Interaction]s.
  */
+@Suppress("DEPRECATION_ERROR")
+@Deprecated("Replaced by the new RippleNode implementation")
 internal abstract class RippleIndicationInstance(
-    bounded: Boolean,
+    private val bounded: Boolean,
     rippleAlpha: State<RippleAlpha>
-) : IndicationInstance {
-    private val stateLayer = StateLayer(bounded, rippleAlpha)
+) : androidx.compose.foundation.IndicationInstance {
+    private val stateLayer = StateLayer(bounded) { rippleAlpha.value }
 
     abstract fun addRipple(interaction: PressInteraction.Press, scope: CoroutineScope)
 
@@ -217,12 +293,83 @@
 
     fun DrawScope.drawStateLayer(radius: Dp, color: Color) {
         with(stateLayer) {
-            drawStateLayer(radius, color)
+            val targetRadius = if (radius.isUnspecified) {
+                getRippleEndRadius(bounded, size)
+            } else {
+                radius.toPx()
+            }
+            drawStateLayer(targetRadius, color)
         }
     }
 }
 
 /**
+ * Abstract [Modifier.Node] that provides common functionality used by ripple node implementations.
+ * Implementing classes should use [stateLayer] to draw the [StateLayer], so they only need to
+ * handle showing the ripple effect when pressed, and not other [Interaction]s.
+ */
+internal abstract class RippleNode(
+    private val interactionSource: InteractionSource,
+    protected val bounded: Boolean,
+    private val radius: Dp,
+    private val color: ColorProducer,
+    protected val rippleAlpha: () -> RippleAlpha
+) : Modifier.Node(), CompositionLocalConsumerModifierNode, DrawModifierNode {
+    final override val shouldAutoInvalidate: Boolean = false
+
+    private var stateLayer: StateLayer? = null
+
+    // Calculated inside draw(). This won't happen in Robolectric, so default to 0f to avoid crashes
+    var targetRadius: Float = 0f
+        private set
+
+    val rippleColor: Color
+        get() = color()
+
+    final override fun onAttach() {
+        coroutineScope.launch {
+            interactionSource.interactions.collect { interaction ->
+                when (interaction) {
+                    is PressInteraction.Press -> addRipple(interaction)
+                    is PressInteraction.Release -> removeRipple(interaction.press)
+                    is PressInteraction.Cancel -> removeRipple(interaction.press)
+                    else -> updateStateLayer(interaction, this)
+                }
+            }
+        }
+    }
+
+    override fun ContentDrawScope.draw() {
+        targetRadius = if (radius.isUnspecified) {
+            // Explicitly calculate the radius instead of using RippleDrawable.RADIUS_AUTO on
+            // Android since the latest spec does not match with the existing radius calculation in
+            // the framework.
+            getRippleEndRadius(bounded, size)
+        } else {
+            radius.toPx()
+        }
+        drawContent()
+        stateLayer?.run {
+            drawStateLayer(targetRadius, rippleColor)
+        }
+        drawRipples()
+    }
+
+    abstract fun DrawScope.drawRipples()
+
+    abstract fun addRipple(interaction: PressInteraction.Press)
+    abstract fun removeRipple(interaction: PressInteraction.Press)
+    private fun updateStateLayer(interaction: Interaction, scope: CoroutineScope) {
+        val stateLayer = stateLayer ?: StateLayer(bounded, rippleAlpha).also { instance ->
+            // Invalidate when adding the state layer so we can start drawing it
+            invalidateDraw()
+            stateLayer = instance
+        }
+        stateLayer.handleInteraction(interaction, scope)
+    }
+}
+
+/**
  * Represents the layer underneath the press ripple, that displays an overlay for states such as
  * [DragInteraction.Start].
  *
@@ -247,16 +394,14 @@
  */
 private class StateLayer(
     private val bounded: Boolean,
-    // TODO: consider dynamically updating the alpha for existing interactions when rippleAlpha
-    // changes
-    private val rippleAlpha: State<RippleAlpha>
+    private val rippleAlpha: () -> RippleAlpha
 ) {
     private val animatedAlpha = Animatable(0f)
 
     private val interactions: MutableList<Interaction> = mutableListOf()
     private var currentInteraction: Interaction? = null
 
-    fun handleInteraction(interaction: Interaction, scope: CoroutineScope) {
+    internal fun handleInteraction(interaction: Interaction, scope: CoroutineScope) {
         when (interaction) {
             is HoverInteraction.Enter -> {
                 interactions.add(interaction)
@@ -287,10 +432,11 @@
 
         if (currentInteraction != newInteraction) {
             if (newInteraction != null) {
+                val rippleAlpha = rippleAlpha()
                 val targetAlpha = when (interaction) {
-                    is HoverInteraction.Enter -> rippleAlpha.value.hoveredAlpha
-                    is FocusInteraction.Focus -> rippleAlpha.value.focusedAlpha
-                    is DragInteraction.Start -> rippleAlpha.value.draggedAlpha
+                    is HoverInteraction.Enter -> rippleAlpha.hoveredAlpha
+                    is FocusInteraction.Focus -> rippleAlpha.focusedAlpha
+                    is DragInteraction.Start -> rippleAlpha.draggedAlpha
                     else -> 0f
                 }
                 val incomingAnimationSpec = incomingStateLayerAnimationSpecFor(newInteraction)
@@ -309,13 +455,7 @@
         }
     }
 
-    fun DrawScope.drawStateLayer(radius: Dp, color: Color) {
-        val targetRadius = if (radius.isUnspecified) {
-            getRippleEndRadius(bounded, size)
-        } else {
-            radius.toPx()
-        }
-
+    fun DrawScope.drawStateLayer(radius: Float, color: Color) {
         val alpha = animatedAlpha.value
 
         if (alpha > 0f) {
@@ -323,10 +463,10 @@
 
             if (bounded) {
                 clipRect {
-                    drawCircle(modulatedColor, targetRadius)
+                    drawCircle(modulatedColor, radius)
                 }
             } else {
-                drawCircle(modulatedColor, targetRadius)
+                drawCircle(modulatedColor, radius)
             }
         }
     }
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
index b4aa27b..12ec448a 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
@@ -29,9 +29,7 @@
 import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.graphics.drawscope.clipRect
 import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.isUnspecified
 import androidx.compose.ui.util.lerp
 import kotlin.math.max
 import kotlinx.coroutines.CompletableDeferred
@@ -59,11 +57,10 @@
  */
 internal class RippleAnimation(
     private var origin: Offset?,
-    private val radius: Dp,
+    private val radius: Float,
     private val bounded: Boolean
 ) {
     private var startRadius: Float? = null
-    private var targetRadius: Float? = null
 
     private var targetCenter: Offset? = null
 
@@ -126,13 +123,6 @@
         if (startRadius == null) {
             startRadius = getRippleStartRadius(size)
         }
-        if (targetRadius == null) {
-            targetRadius = if (radius.isUnspecified) {
-                getRippleEndRadius(bounded, size)
-            } else {
-                radius.toPx()
-            }
-        }
         if (origin == null) {
             origin = center
         }
@@ -147,7 +137,7 @@
             animatedAlpha.value
         }
 
-        val radius = lerp(startRadius!!, targetRadius!!, animatedRadiusPercent.value)
+        val radius = lerp(startRadius!!, radius, animatedRadiusPercent.value)
         val centerOffset = Offset(
             lerp(origin!!.x, targetCenter!!.x, animatedCenterPercent.value),
             lerp(origin!!.y, targetCenter!!.y, animatedCenterPercent.value),
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt
index daab4e4..66ec98b 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleTheme.kt
@@ -17,8 +17,6 @@
 package androidx.compose.material.ripple
 
 import androidx.compose.foundation.interaction.Interaction
-import androidx.compose.material.ripple.RippleTheme.Companion.defaultRippleAlpha
-import androidx.compose.material.ripple.RippleTheme.Companion.defaultRippleColor
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ProvidableCompositionLocal
@@ -33,12 +31,14 @@
  *
  * @see rememberRipple
  */
+@Deprecated(RippleThemeDeprecationMessage, level = DeprecationLevel.ERROR)
 public interface RippleTheme {
     /**
      * @return the default ripple color at the call site's position in the hierarchy.
      * This color will be used when a color is not explicitly set in the ripple itself.
      * @see defaultRippleColor
      */
+    @Deprecated(RippleThemeDeprecationMessage, level = DeprecationLevel.ERROR)
     @Composable
     public fun defaultColor(): Color
 
@@ -48,6 +48,7 @@
      * [defaultColor] or the color explicitly provided to the ripple.
      * @see defaultRippleAlpha
      */
+    @Deprecated(RippleThemeDeprecationMessage, level = DeprecationLevel.ERROR)
     @Composable
     public fun rippleAlpha(): RippleAlpha
 
@@ -60,6 +61,16 @@
          * contains the ripple.
          * @param lightTheme whether the theme is light or not
          */
+        @Deprecated(
+            "The default ripple color varies between design system versions: this " +
+                "function technically implements the default used by the material library, but " +
+                "is not used by the material3 library. To remove confusion and link the " +
+                "defaults more strongly to the design system library, these default values have " +
+                "been moved to the material and material3 libraries. For material, use " +
+                "MaterialRippleThemeDefaults#rippleColor. For material3, use content color " +
+                "directly.",
+            level = DeprecationLevel.WARNING
+        )
         public fun defaultRippleColor(
             contentColor: Color,
             lightTheme: Boolean
@@ -83,6 +94,16 @@
          * contains the ripple.
          * @param lightTheme whether the theme is light or not
          */
+        @Deprecated(
+            "The default ripple alpha varies between design system versions: this " +
+                "function technically implements the default used by the material library, but " +
+                "is not used by the material3 library. To remove confusion and link the " +
+                "defaults more strongly to the design system library, these default values have " +
+                "been moved to the material and material3 libraries. For material, use " +
+                "MaterialRippleThemeDefaults#rippleAlpha. For material3, use " +
+                "MaterialRippleThemeDefaults#RippleAlpha.",
+            level = DeprecationLevel.WARNING
+        )
         public fun defaultRippleAlpha(contentColor: Color, lightTheme: Boolean): RippleAlpha {
             return when {
                 lightTheme -> {
@@ -159,6 +180,8 @@
  * See [RippleTheme.defaultRippleColor] and [RippleTheme.defaultRippleAlpha] functions for the
  * default implementations for color and alpha.
  */
+@Suppress("DEPRECATION_ERROR")
+@Deprecated(RippleThemeDeprecationMessage, level = DeprecationLevel.ERROR)
 public val LocalRippleTheme: ProvidableCompositionLocal<RippleTheme> =
     staticCompositionLocalOf { DebugRippleTheme }
 
@@ -209,14 +232,22 @@
  * instead provide your own theme with meaningful values - this exists as an alternative to
  * crashing if no theme is provided.
  */
+@Suppress("DEPRECATION_ERROR", "deprecation")
 @Immutable
 private object DebugRippleTheme : RippleTheme {
+    @Deprecated("Super method is deprecated")
     @Composable
-    override fun defaultColor() = defaultRippleColor(Color.Black, lightTheme = true)
+    override fun defaultColor() = RippleTheme.defaultRippleColor(Color.Black, lightTheme = true)
 
+    @Deprecated("Super method is deprecated")
     @Composable
-    override fun rippleAlpha(): RippleAlpha = defaultRippleAlpha(
+    override fun rippleAlpha(): RippleAlpha = RippleTheme.defaultRippleAlpha(
         Color.Black,
         lightTheme = true
     )
 }
+
+private const val RippleThemeDeprecationMessage = "RippleTheme and LocalRippleTheme have been " +
+    "deprecated - they are not compatible with the new ripple implementation using the new " +
+    "Indication APIs that provide notable performance improvements. For a migration guide and " +
+    "background information, please visit developer.android.com"
diff --git a/compose/material/material-ripple/src/desktopMain/kotlin/androidx/compose/material/ripple/Ripple.desktop.kt b/compose/material/material-ripple/src/desktopMain/kotlin/androidx/compose/material/ripple/Ripple.desktop.kt
index 7dce6e6..62fa3d8 100644
--- a/compose/material/material-ripple/src/desktopMain/kotlin/androidx/compose/material/ripple/Ripple.desktop.kt
+++ b/compose/material/material-ripple/src/desktopMain/kotlin/androidx/compose/material/ripple/Ripple.desktop.kt
@@ -17,7 +17,27 @@
 
 package androidx.compose.material.ripple
 
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.unit.Dp
+
+/**
+ * Desktop ripple implementation using the Compose-rendered [CommonRippleNode] implementation.
+ */
+internal actual fun createPlatformRippleNode(
+    interactionSource: InteractionSource,
+    bounded: Boolean,
+    radius: Dp,
+    color: ColorProducer,
+    rippleAlpha: () -> RippleAlpha
+): DelegatableNode {
+    return CommonRippleNode(interactionSource, bounded, radius, color, rippleAlpha)
+}
+
 /**
  * Desktop ripple implementation using the Compose-rendered [CommonRipple] implementation.
  */
+@Suppress("DEPRECATION")
+@Deprecated("Replaced by the new RippleNode implementation")
 internal actual typealias PlatformRipple = CommonRipple
diff --git a/compose/material/material/api/current.txt b/compose/material/material/api/current.txt
index b1fcbf4..0de7448 100644
--- a/compose/material/material/api/current.txt
+++ b/compose/material/material/api/current.txt
@@ -51,24 +51,32 @@
 
   public final class BackdropScaffoldKt {
     method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BackdropScaffold(kotlin.jvm.functions.Function0<kotlin.Unit> appBar, kotlin.jvm.functions.Function0<kotlin.Unit> backLayerContent, kotlin.jvm.functions.Function0<kotlin.Unit> frontLayerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BackdropScaffoldState scaffoldState, optional boolean gesturesEnabled, optional float peekHeight, optional float headerHeight, optional boolean persistentAppBar, optional boolean stickyFrontLayer, optional long backLayerBackgroundColor, optional long backLayerContentColor, optional androidx.compose.ui.graphics.Shape frontLayerShape, optional float frontLayerElevation, optional long frontLayerBackgroundColor, optional long frontLayerContentColor, optional long frontLayerScrimColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost);
+    method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public static androidx.compose.material.BackdropScaffoldState BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmValueChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
     method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BackdropScaffoldState rememberBackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
-  @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
-    ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
+  @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState {
+    ctor @Deprecated public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmValueChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
     method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public kotlin.jvm.functions.Function1<androidx.compose.material.BackdropValue,java.lang.Boolean> getConfirmValueChange();
+    method public androidx.compose.material.BackdropValue getCurrentValue();
     method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
+    method public androidx.compose.material.BackdropValue getTargetValue();
     method public boolean isConcealed();
     method public boolean isRevealed();
+    method public float requireOffset();
     method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final kotlin.jvm.functions.Function1<androidx.compose.material.BackdropValue,java.lang.Boolean> confirmValueChange;
+    property public final androidx.compose.material.BackdropValue currentValue;
     property public final boolean isConcealed;
     property public final boolean isRevealed;
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
+    property public final androidx.compose.material.BackdropValue targetValue;
     field public static final androidx.compose.material.BackdropScaffoldState.Companion Companion;
   }
 
   public static final class BackdropScaffoldState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState, androidx.compose.ui.unit.Density density);
   }
 
   @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public enum BackdropValue {
@@ -652,6 +660,31 @@
     property @Deprecated public final float factorAtMin;
   }
 
+  @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class RippleConfiguration {
+    ctor public RippleConfiguration(optional boolean isEnabled, optional long color, optional androidx.compose.material.ripple.RippleAlpha? rippleAlpha);
+    method public long getColor();
+    method public androidx.compose.material.ripple.RippleAlpha? getRippleAlpha();
+    method public boolean isEnabled();
+    property public final long color;
+    property public final boolean isEnabled;
+    property public final androidx.compose.material.ripple.RippleAlpha? rippleAlpha;
+  }
+
+  public final class RippleDefaults {
+    method public androidx.compose.material.ripple.RippleAlpha rippleAlpha(long contentColor, boolean lightTheme);
+    method public long rippleColor(long contentColor, boolean lightTheme);
+    field public static final androidx.compose.material.RippleDefaults INSTANCE;
+  }
+
+  public final class RippleKt {
+    method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.RippleConfiguration> getLocalRippleConfiguration();
+    method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalUseFallbackRippleImplementation();
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(androidx.compose.ui.graphics.ColorProducer color, optional boolean bounded, optional float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(optional boolean bounded, optional float radius, optional long color);
+    property @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.RippleConfiguration> LocalRippleConfiguration;
+    property @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalUseFallbackRippleImplementation;
+  }
+
   public final class ScaffoldDefaults {
     method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
     property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
diff --git a/compose/material/material/api/restricted_current.txt b/compose/material/material/api/restricted_current.txt
index b1fcbf4..0de7448 100644
--- a/compose/material/material/api/restricted_current.txt
+++ b/compose/material/material/api/restricted_current.txt
@@ -51,24 +51,32 @@
 
   public final class BackdropScaffoldKt {
     method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BackdropScaffold(kotlin.jvm.functions.Function0<kotlin.Unit> appBar, kotlin.jvm.functions.Function0<kotlin.Unit> backLayerContent, kotlin.jvm.functions.Function0<kotlin.Unit> frontLayerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BackdropScaffoldState scaffoldState, optional boolean gesturesEnabled, optional float peekHeight, optional float headerHeight, optional boolean persistentAppBar, optional boolean stickyFrontLayer, optional long backLayerBackgroundColor, optional long backLayerContentColor, optional androidx.compose.ui.graphics.Shape frontLayerShape, optional float frontLayerElevation, optional long frontLayerBackgroundColor, optional long frontLayerContentColor, optional long frontLayerScrimColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost);
+    method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public static androidx.compose.material.BackdropScaffoldState BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmValueChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
     method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BackdropScaffoldState rememberBackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
   }
 
-  @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
-    ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
+  @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState {
+    ctor @Deprecated public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmValueChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
     method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public kotlin.jvm.functions.Function1<androidx.compose.material.BackdropValue,java.lang.Boolean> getConfirmValueChange();
+    method public androidx.compose.material.BackdropValue getCurrentValue();
     method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
+    method public androidx.compose.material.BackdropValue getTargetValue();
     method public boolean isConcealed();
     method public boolean isRevealed();
+    method public float requireOffset();
     method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final kotlin.jvm.functions.Function1<androidx.compose.material.BackdropValue,java.lang.Boolean> confirmValueChange;
+    property public final androidx.compose.material.BackdropValue currentValue;
     property public final boolean isConcealed;
     property public final boolean isRevealed;
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
+    property public final androidx.compose.material.BackdropValue targetValue;
     field public static final androidx.compose.material.BackdropScaffoldState.Companion Companion;
   }
 
   public static final class BackdropScaffoldState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState, androidx.compose.ui.unit.Density density);
   }
 
   @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public enum BackdropValue {
@@ -652,6 +660,31 @@
     property @Deprecated public final float factorAtMin;
   }
 
+  @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class RippleConfiguration {
+    ctor public RippleConfiguration(optional boolean isEnabled, optional long color, optional androidx.compose.material.ripple.RippleAlpha? rippleAlpha);
+    method public long getColor();
+    method public androidx.compose.material.ripple.RippleAlpha? getRippleAlpha();
+    method public boolean isEnabled();
+    property public final long color;
+    property public final boolean isEnabled;
+    property public final androidx.compose.material.ripple.RippleAlpha? rippleAlpha;
+  }
+
+  public final class RippleDefaults {
+    method public androidx.compose.material.ripple.RippleAlpha rippleAlpha(long contentColor, boolean lightTheme);
+    method public long rippleColor(long contentColor, boolean lightTheme);
+    field public static final androidx.compose.material.RippleDefaults INSTANCE;
+  }
+
+  public final class RippleKt {
+    method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.RippleConfiguration> getLocalRippleConfiguration();
+    method @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalUseFallbackRippleImplementation();
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(androidx.compose.ui.graphics.ColorProducer color, optional boolean bounded, optional float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(optional boolean bounded, optional float radius, optional long color);
+    property @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.RippleConfiguration> LocalRippleConfiguration;
+    property @SuppressCompatibility @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalUseFallbackRippleImplementation;
+  }
+
   public final class ScaffoldDefaults {
     method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
     property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
diff --git a/compose/material/material/integration-tests/material-catalog/build.gradle b/compose/material/material/integration-tests/material-catalog/build.gradle
index 15bc9f9..49c18e2 100644
--- a/compose/material/material/integration-tests/material-catalog/build.gradle
+++ b/compose/material/material/integration-tests/material-catalog/build.gradle
@@ -30,8 +30,8 @@
     implementation project(":compose:runtime:runtime")
     implementation project(":compose:foundation:foundation-layout")
     implementation project(":compose:ui:ui")
-    implementation project(":compose:material:material")
-    implementation project(":compose:material:material:material-samples")
+    implementation("androidx.compose.material:material:1.6.0-beta01")
+    implementation("androidx.compose.material:material-samples:1.6.0-beta01")
     implementation project(":navigation:navigation-compose")
 }
 
diff --git a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
index f8b99e2..d7f1dd7 100644
--- a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
+++ b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
@@ -344,16 +344,43 @@
         }
     }
 
+    @Suppress("DEPRECATION")
+    @Test
+    fun backdropScaffold_deprecateScaffoldState_doesNotCrash() {
+        lateinit var scaffoldState: BackdropScaffoldState
+        rule.setContent {
+            scaffoldState = BackdropScaffoldState(
+                initialValue = Revealed
+            )
+            BackdropScaffold(
+                scaffoldState = scaffoldState,
+                peekHeight = peekHeight,
+                headerHeight = headerHeight,
+                appBar = { Box(Modifier.height(peekHeight)) },
+                backLayerContent = { Box(Modifier.height(contentHeight)) },
+                frontLayerContent = { Box(
+                    Modifier
+                        .fillMaxSize()
+                        .testTag(frontLayer)) }
+            )
+        }
+
+        rule.runOnIdle {
+            assertThat(scaffoldState.currentValue).isEqualTo(Revealed)
+        }
+    }
+
     /**
      * Tests that the state and offset of [swipeable] are updated when swiping.
      */
     @Test
     fun backdropScaffold_syncThresholdUpdate() {
         val increasedAnchor = mutableStateOf(false)
-        val scaffoldState = BackdropScaffoldState(Revealed)
+        var scaffoldState: BackdropScaffoldState? = null
         rule.setContent {
+            scaffoldState = rememberBackdropScaffoldState(initialValue = Revealed)
             BackdropScaffold(
-                scaffoldState = scaffoldState,
+                scaffoldState = scaffoldState!!,
                 frontLayerScrimColor = Color.Red,
                 appBar = { },
                 backLayerContent = {
@@ -374,21 +401,21 @@
         }
 
         val revealedOffset = rule.runOnIdle {
-            assertThat(scaffoldState.currentValue).isEqualTo(BackdropValue.Revealed)
+            assertThat(scaffoldState?.currentValue).isEqualTo(BackdropValue.Revealed)
             // state change changes the anchors, causing the recalculation
             increasedAnchor.value = true
-            scaffoldState.offset.value
+            scaffoldState?.requireOffset()
         }
 
         rule.runOnIdle {
-            assertThat(scaffoldState.offset.value).isNotEqualTo(revealedOffset)
+            assertThat(scaffoldState?.requireOffset()).isNotEqualTo(revealedOffset)
             // swap back, causing threshold update during update-caused settle
             increasedAnchor.value = false
         }
 
         rule.runOnIdle {
             // no crash and assert passes
-            assertThat(scaffoldState.offset.value).isEqualTo(revealedOffset)
+            assertThat(scaffoldState?.requireOffset()).isEqualTo(revealedOffset)
         }
     }
 
diff --git a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/RippleTest.kt
similarity index 78%
rename from compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt
rename to compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/RippleTest.kt
index be665d3..15c1d55 100644
--- a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt
+++ b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/RippleTest.kt
@@ -34,10 +34,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.ripple.LocalRippleTheme
 import androidx.compose.material.ripple.RippleAlpha
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -69,8 +66,7 @@
 import org.junit.runner.RunWith
 
 /**
- * Test for the [RippleTheme] provided by [MaterialTheme], to verify colors and opacity in
- * different configurations.
+ * Test for [ripple], to verify colors and opacity in different configurations.
  */
 @LargeTest
 @RunWith(AndroidJUnit4::class)
@@ -85,7 +81,7 @@
     // color.
     maxSdkVersion = Build.VERSION_CODES.R
 )
-class MaterialRippleThemeTest {
+class RippleTest {
 
     @get:Rule
     val rule = createComposeRule()
@@ -770,239 +766,103 @@
         )
     }
 
-    @Test
-    fun customRippleTheme_pressed() {
-        val interactionSource = MutableInteractionSource()
-
-        val contentColor = Color.Black
-
-        val rippleColor = Color.Red
-        val expectedAlpha = 0.5f
-        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
-
-        val rippleTheme = object : RippleTheme {
-            @Composable
-            override fun defaultColor() = rippleColor
-
-            @Composable
-            override fun rippleAlpha() = rippleAlpha
-        }
-
-        var scope: CoroutineScope? = null
-
-        rule.setContent {
-            scope = rememberCoroutineScope()
-            MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
-                    Surface(contentColor = contentColor) {
-                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBoxWithBackground(
-                                interactionSource,
-                                rememberRipple(),
-                                bounded = true
-                            )
-                        }
-                    }
-                }
-            }
-        }
-
-        val expectedColor = calculateResultingRippleColor(
-            rippleColor,
-            rippleOpacity = expectedAlpha
-        )
-
-        assertRippleMatches(
-            scope!!,
-            interactionSource,
-            PressInteraction.Press(Offset(10f, 10f)),
-            expectedColor
-        )
-    }
-
-    @Test
-    fun customRippleTheme_hovered() {
-        val interactionSource = MutableInteractionSource()
-
-        val contentColor = Color.Black
-
-        val rippleColor = Color.Red
-        val expectedAlpha = 0.5f
-        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
-
-        val rippleTheme = object : RippleTheme {
-            @Composable
-            override fun defaultColor() = rippleColor
-
-            @Composable
-            override fun rippleAlpha() = rippleAlpha
-        }
-
-        var scope: CoroutineScope? = null
-
-        rule.setContent {
-            scope = rememberCoroutineScope()
-            MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
-                    Surface(contentColor = contentColor) {
-                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBoxWithBackground(
-                                interactionSource,
-                                rememberRipple(),
-                                bounded = true
-                            )
-                        }
-                    }
-                }
-            }
-        }
-
-        val expectedColor = calculateResultingRippleColor(
-            rippleColor,
-            rippleOpacity = expectedAlpha
-        )
-
-        assertRippleMatches(
-            scope!!,
-            interactionSource,
-            HoverInteraction.Enter(),
-            expectedColor
-        )
-    }
-
-    @Test
-    fun customRippleTheme_focused() {
-        val interactionSource = MutableInteractionSource()
-
-        val contentColor = Color.Black
-
-        val rippleColor = Color.Red
-        val expectedAlpha = 0.5f
-        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
-
-        val rippleTheme = object : RippleTheme {
-            @Composable
-            override fun defaultColor() = rippleColor
-
-            @Composable
-            override fun rippleAlpha() = rippleAlpha
-        }
-
-        var scope: CoroutineScope? = null
-
-        rule.setContent {
-            scope = rememberCoroutineScope()
-            MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
-                    Surface(contentColor = contentColor) {
-                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBoxWithBackground(
-                                interactionSource,
-                                rememberRipple(),
-                                bounded = true
-                            )
-                        }
-                    }
-                }
-            }
-        }
-
-        val expectedColor = calculateResultingRippleColor(
-            rippleColor,
-            rippleOpacity = expectedAlpha
-        )
-
-        assertRippleMatches(
-            scope!!,
-            interactionSource,
-            FocusInteraction.Focus(),
-            expectedColor
-        )
-    }
-
-    @Test
-    fun customRippleTheme_dragged() {
-        val interactionSource = MutableInteractionSource()
-
-        val contentColor = Color.Black
-
-        val rippleColor = Color.Red
-        val expectedAlpha = 0.5f
-        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
-
-        val rippleTheme = object : RippleTheme {
-            @Composable
-            override fun defaultColor() = rippleColor
-            @Composable
-            override fun rippleAlpha() = rippleAlpha
-        }
-
-        var scope: CoroutineScope? = null
-
-        rule.setContent {
-            scope = rememberCoroutineScope()
-            MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
-                    Surface(contentColor = contentColor) {
-                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            RippleBoxWithBackground(
-                                interactionSource,
-                                rememberRipple(),
-                                bounded = true
-                            )
-                        }
-                    }
-                }
-            }
-        }
-
-        val expectedColor = calculateResultingRippleColor(
-            rippleColor,
-            rippleOpacity = expectedAlpha
-        )
-
-        assertRippleMatches(
-            scope!!,
-            interactionSource,
-            DragInteraction.Start(),
-            expectedColor
-        )
-    }
-
     /**
+     * Test case for changing content color during an existing ripple effect
+     *
      * Note: no corresponding test for pressed ripples since RippleForeground does not update the
      * color of currently active ripples unless they are being drawn on the UI thread
      * (which should only happen if the target radius also changes).
      */
     @Test
-    fun themeChangeDuringRipple_dragged() {
+    fun contentColorChangeDuringRipple_dragged() {
         val interactionSource = MutableInteractionSource()
 
-        fun createRippleTheme(color: Color, alpha: Float) = object : RippleTheme {
-            val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
-            @Composable
-            override fun defaultColor() = color
-
-            @Composable
-            override fun rippleAlpha() = rippleAlpha
-        }
-
         val initialColor = Color.Red
-        val initialAlpha = 0.5f
-
-        var rippleTheme by mutableStateOf(createRippleTheme(initialColor, initialAlpha))
+        var contentColor by mutableStateOf(initialColor)
 
         var scope: CoroutineScope? = null
 
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
-                    Surface(contentColor = Color.Black) {
+                Surface(contentColor = contentColor) {
+                    Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                        RippleBoxWithBackground(
+                            interactionSource,
+                            ripple(),
+                            bounded = true
+                        )
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    initialColor,
+                    rippleOpacity = 0.08f
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newColor = Color.Green
+
+        rule.runOnUiThread {
+            contentColor = newColor
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    newColor,
+                    rippleOpacity = 0.08f
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    @OptIn(ExperimentalMaterialApi::class)
+    @Test
+    fun rippleConfiguration_color_dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        val rippleConfiguration = RippleConfiguration(
+            color = Color.Red
+        )
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            MaterialTheme {
+                Surface {
+                    CompositionLocalProvider(
+                        LocalRippleConfiguration provides rippleConfiguration
+                    ) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             RippleBoxWithBackground(
                                 interactionSource,
-                                rememberRipple(),
+                                ripple(),
                                 bounded = true
                             )
                         }
@@ -1025,19 +885,56 @@
                 }
 
             val expectedColor =
-                calculateResultingRippleColor(initialColor, rippleOpacity = initialAlpha)
+                calculateResultingRippleColor(
+                    // Color from the ripple configuration should be used
+                    rippleConfiguration.color,
+                    // Default alpha should be used
+                    rippleOpacity = 0.08f
+                )
 
             Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
         }
+    }
 
-        val newColor = Color.Green
-        // TODO: changing alpha for existing state layers is not currently supported
-        val newAlpha = 0.5f
+    @OptIn(ExperimentalMaterialApi::class)
+    @Test
+    fun rippleConfiguration_color_explicitColorSet_dragged() {
+        val interactionSource = MutableInteractionSource()
 
-        rule.runOnUiThread {
-            rippleTheme = createRippleTheme(newColor, newAlpha)
+        val rippleConfiguration = RippleConfiguration(
+            color = Color.Red
+        )
+
+        val explicitColor = Color.Green
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            MaterialTheme {
+                Surface {
+                    CompositionLocalProvider(
+                        LocalRippleConfiguration provides rippleConfiguration
+                    ) {
+                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                            RippleBoxWithBackground(
+                                interactionSource,
+                                ripple(color = explicitColor),
+                                bounded = true
+                            )
+                        }
+                    }
+                }
+            }
         }
 
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
         with(rule.onNodeWithTag(Tag)) {
             val centerPixel = captureToImage().asAndroidBitmap()
                 .run {
@@ -1045,24 +942,243 @@
                 }
 
             val expectedColor =
-                calculateResultingRippleColor(newColor, rippleOpacity = newAlpha)
+                calculateResultingRippleColor(
+                    // Color explicitly set on the ripple should 'win' over the configuration color
+                    explicitColor,
+                    // Default alpha should be used
+                    rippleOpacity = 0.08f
+                )
 
             Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
         }
     }
 
+    @OptIn(ExperimentalMaterialApi::class)
     @Test
-    fun contentColorProvidedAfterRememberRipple() {
+    fun rippleConfiguration_alpha_dragged() {
         val interactionSource = MutableInteractionSource()
 
-        val alpha = 0.5f
-        val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
-        val expectedRippleColor = Color.Red
+        val contentColor = Color.Black
 
-        val theme = object : RippleTheme {
+        val rippleConfiguration = RippleConfiguration(
+            rippleAlpha = RippleAlpha(0.5f, 0.5f, 0.5f, 0.5f)
+        )
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            MaterialTheme {
+                Surface(contentColor = contentColor) {
+                    CompositionLocalProvider(
+                        LocalRippleConfiguration provides rippleConfiguration
+                    ) {
+                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                            RippleBoxWithBackground(
+                                interactionSource,
+                                ripple(),
+                                bounded = true
+                            )
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            val expectedColor =
+                calculateResultingRippleColor(
+                    // Default color should be used
+                    contentColor,
+                    // Alpha from the ripple configuration should be used
+                    rippleOpacity = rippleConfiguration.rippleAlpha!!.draggedAlpha
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+    }
+
+    @OptIn(ExperimentalMaterialApi::class)
+    @Test
+    fun rippleConfiguration_disabled_dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        val rippleConfiguration = RippleConfiguration(
+            isEnabled = false
+        )
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            MaterialTheme {
+                Surface {
+                    CompositionLocalProvider(
+                        LocalRippleConfiguration provides rippleConfiguration
+                    ) {
+                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                            RippleBoxWithBackground(
+                                interactionSource,
+                                ripple(),
+                                bounded = true
+                            )
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            // No ripple should be showing
+            Truth.assertThat(Color(centerPixel)).isEqualTo(RippleBoxBackgroundColor)
+        }
+    }
+
+    /**
+     * Test case for changing RippleConfiguration during an existing ripple effect
+     *
+     * Note: no corresponding test for pressed ripples since RippleForeground does not update the
+     * color of currently active ripples unless they are being drawn on the UI thread
+     * (which should only happen if the target radius also changes).
+     */
+    @OptIn(ExperimentalMaterialApi::class)
+    @Test
+    fun rippleConfigurationChangeDuringRipple_dragged() {
+        val interactionSource = MutableInteractionSource()
+
+        val contentColor = Color.Black
+
+        var rippleConfiguration by mutableStateOf(RippleConfiguration())
+
+        var scope: CoroutineScope? = null
+
+        rule.setContent {
+            scope = rememberCoroutineScope()
+            MaterialTheme {
+                Surface(contentColor = contentColor) {
+                    CompositionLocalProvider(
+                        LocalRippleConfiguration provides rippleConfiguration
+                    ) {
+                        Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                            RippleBoxWithBackground(
+                                interactionSource,
+                                ripple(),
+                                bounded = true
+                            )
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle {
+            scope!!.launch {
+                interactionSource.emit(DragInteraction.Start())
+            }
+        }
+        rule.waitForIdle()
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            // Ripple should use default values
+            val expectedColor =
+                calculateResultingRippleColor(
+                    contentColor,
+                    rippleOpacity = 0.08f
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        val newConfiguration = RippleConfiguration(
+            isEnabled = true,
+            color = Color.Red,
+            rippleAlpha = RippleAlpha(0.5f, 0.5f, 0.5f, 0.5f)
+        )
+
+        rule.runOnUiThread {
+            rippleConfiguration = newConfiguration
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            // The ripple should now use the new configuration value for color. Ripple alpha
+            // is not currently updated during an existing effect, so it should still use the old
+            // value.
+            val expectedColor =
+                calculateResultingRippleColor(
+                    newConfiguration.color,
+                    rippleOpacity = 0.08f
+                )
+
+            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
+        }
+
+        rule.runOnUiThread {
+            rippleConfiguration = RippleConfiguration(isEnabled = false)
+        }
+
+        with(rule.onNodeWithTag(Tag)) {
+            val centerPixel = captureToImage().asAndroidBitmap()
+                .run {
+                    getPixel(width / 2, height / 2)
+                }
+
+            // The ripple should now be removed
+            Truth.assertThat(Color(centerPixel)).isEqualTo(RippleBoxBackgroundColor)
+        }
+    }
+
+    @OptIn(ExperimentalMaterialApi::class)
+    @Suppress("DEPRECATION_ERROR")
+    @Test
+    fun fallback_customRippleTheme() {
+        val interactionSource = MutableInteractionSource()
+
+        val contentColor = Color.Black
+
+        val rippleColor = Color.Red
+        val expectedAlpha = 0.5f
+        val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
+
+        val rippleTheme = object : androidx.compose.material.ripple.RippleTheme {
+            @Deprecated("Super method is deprecated")
             @Composable
-            override fun defaultColor() = LocalContentColor.current
+            override fun defaultColor() = rippleColor
 
+            @Deprecated("Super method is deprecated")
             @Composable
             override fun rippleAlpha() = rippleAlpha
         }
@@ -1072,44 +1188,34 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides theme) {
-                    Surface(contentColor = Color.Black) {
-                        // Create ripple where contentColor is black
-                        val ripple = rememberRipple()
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides rippleTheme,
+                    LocalUseFallbackRippleImplementation provides true
+                ) {
+                    Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                            Surface(contentColor = expectedRippleColor) {
-                                // Ripple is used where contentColor is red, so the instance
-                                // should get the red color when it is created
-                                RippleBoxWithBackground(interactionSource, ripple, bounded = true)
-                            }
+                            RippleBoxWithBackground(
+                                interactionSource,
+                                rippleOrFallbackImplementation(),
+                                bounded = true
+                            )
                         }
                     }
                 }
             }
         }
 
-        rule.runOnIdle {
-            scope!!.launch {
-                interactionSource.emit(PressInteraction.Press(Offset(10f, 10f)))
-            }
-        }
+        val expectedColor = calculateResultingRippleColor(
+            rippleColor,
+            rippleOpacity = expectedAlpha
+        )
 
-        rule.waitForIdle()
-        // Ripples are drawn on the RenderThread, not the main (UI) thread, so we can't wait for
-        // synchronization. Instead just wait until after the ripples are finished animating.
-        Thread.sleep(300)
-
-        with(rule.onNodeWithTag(Tag)) {
-            val centerPixel = captureToImage().asAndroidBitmap()
-                .run {
-                    getPixel(width / 2, height / 2)
-                }
-
-            val expectedColor =
-                calculateResultingRippleColor(expectedRippleColor, rippleOpacity = alpha)
-
-            Truth.assertThat(Color(centerPixel)).isEqualTo(expectedColor)
-        }
+        assertRippleMatches(
+            scope!!,
+            interactionSource,
+            PressInteraction.Press(Offset(10f, 10f)),
+            expectedColor
+        )
     }
 
     /**
@@ -1140,6 +1246,7 @@
 
         // Advance to the end of the ripple / state layer animation
         rule.waitForIdle()
+        @Suppress("BanThreadSleep")
         if (interaction is PressInteraction) {
             // Ripples are drawn on the RenderThread, not the main (UI) thread, so we can't wait for
             // synchronization. Instead just wait until after the ripples are finished animating.
@@ -1222,7 +1329,7 @@
         MaterialTheme(colors) {
             Surface(contentColor = contentColor) {
                 Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                    RippleBoxWithBackground(interactionSource, rememberRipple(bounded), bounded)
+                    RippleBoxWithBackground(interactionSource, ripple(bounded), bounded)
                 }
             }
         }
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
index 2caf16b..e833b1e 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
@@ -33,6 +33,7 @@
 import androidx.compose.material.BackdropValue.Concealed
 import androidx.compose.material.BackdropValue.Revealed
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
@@ -42,22 +43,30 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.UiComposable
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.graphics.isSpecified
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.SubcomposeLayout
+import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.semantics.collapse
 import androidx.compose.ui.semantics.expand
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.offset
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.zIndex
@@ -84,73 +93,154 @@
 }
 
 /**
+ * State of the persistent bottom sheet in [BackdropScaffold].
+ *
+ * @param initialValue The initial value of the state.
+ * @param density The density that this state can use to convert values to and from dp.
+ * @param animationSpec The default animation that will be used to animate to a new state.
+ * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
+ * @param snackbarHostState The [SnackbarHostState] used to show snackbars inside the scaffold.
+ */
+@Suppress("Deprecation")
+@ExperimentalMaterialApi
+@Stable
+fun BackdropScaffoldState(
+    initialValue: BackdropValue,
+    density: Density,
+    animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
+    confirmValueChange: (BackdropValue) -> Boolean = { true },
+    snackbarHostState: SnackbarHostState = SnackbarHostState(),
+) = BackdropScaffoldState(
+    initialValue,
+    animationSpec,
+    confirmValueChange,
+    snackbarHostState
+).also {
+    it.density = density
+}
+
+/**
  * State of the [BackdropScaffold] composable.
  *
  * @param initialValue The initial value of the state.
  * @param animationSpec The default animation that will be used to animate to a new state.
- * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
+ * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
  * @param snackbarHostState The [SnackbarHostState] used to show snackbars inside the scaffold.
  */
 @ExperimentalMaterialApi
 @Stable
-class BackdropScaffoldState(
+class BackdropScaffoldState @Deprecated(
+    "This constructor is deprecated. Density must be provided by the component. " +
+        "Please use the constructor that provides a [Density].",
+    ReplaceWith(
+        """
+            BackdropScaffoldState(
+                initialValue = initialValue,
+                density = LocalDensity.current,
+                animationSpec = animationSpec,
+                confirmValueChange = confirmValueChange
+            )
+            """
+    )
+) constructor(
     initialValue: BackdropValue,
     animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
-    confirmStateChange: (BackdropValue) -> Boolean = { true },
-    val snackbarHostState: SnackbarHostState = SnackbarHostState()
-) : SwipeableState<BackdropValue>(
-    initialValue = initialValue,
-    animationSpec = animationSpec,
-    confirmStateChange = confirmStateChange
+    val confirmValueChange: (BackdropValue) -> Boolean = { true },
+    val snackbarHostState: SnackbarHostState = SnackbarHostState(),
 ) {
     /**
+     * The current value of the [BottomSheetState].
+     */
+    val currentValue: BackdropValue
+        get() = anchoredDraggableState.currentValue
+
+    /**
+     * The target value the state will settle at once the current interaction ends, or the
+     * [currentValue] if there is no interaction in progress.
+     */
+    val targetValue: BackdropValue
+        get() = anchoredDraggableState.targetValue
+
+    /**
+     * Require the current offset.
+     *
+     * @throws IllegalStateException If the offset has not been initialized yet
+     */
+    fun requireOffset() = anchoredDraggableState.requireOffset()
+
+    /**
      * Whether the back layer is revealed.
      */
     val isRevealed: Boolean
-        get() = currentValue == Revealed
+        get() = anchoredDraggableState.currentValue == Revealed
 
     /**
      * Whether the back layer is concealed.
      */
     val isConcealed: Boolean
-        get() = currentValue == Concealed
+        get() = anchoredDraggableState.currentValue == Concealed
 
     /**
      * Reveal the back layer with animation and suspend until it if fully revealed or animation
      * has been cancelled.  This method will throw [CancellationException] if the animation is
      * interrupted
-     *
-     * @return the reason the reveal animation ended
      */
-    suspend fun reveal() = animateTo(targetValue = Revealed)
+    suspend fun reveal() = anchoredDraggableState.animateTo(targetValue = Revealed)
 
     /**
      * Conceal the back layer with animation and suspend until it if fully concealed or animation
      * has been cancelled. This method will throw [CancellationException] if the animation is
      * interrupted
-     *
-     * @return the reason the conceal animation ended
      */
-    suspend fun conceal() = animateTo(targetValue = Concealed)
+    suspend fun conceal() = anchoredDraggableState.animateTo(targetValue = Concealed)
 
-    internal val nestedScrollConnection = this.PreUpPostDownNestedScrollConnection
+    internal val anchoredDraggableState = AnchoredDraggableState(
+        initialValue = initialValue,
+        animationSpec = animationSpec,
+        confirmValueChange = confirmValueChange,
+        positionalThreshold = {
+            with(requireDensity()) {
+                PositionalThreshold.toPx()
+            }
+        },
+        velocityThreshold = {
+            with(requireDensity()) {
+                VelocityThreshold.toPx()
+            }
+        }
+    )
+
+    internal var density: Density? = null
+    private fun requireDensity() = requireNotNull(density) {
+        "The density on BackdropScaffoldState ($this) was not set." +
+            " Did you use BackdropScaffoldState with " +
+            "the BackdropScaffold composable?"
+    }
+
+    internal val nestedScrollConnection = ConsumeSwipeNestedScrollConnection(
+        anchoredDraggableState,
+        Orientation.Vertical
+    )
 
     companion object {
+
         /**
          * The default [Saver] implementation for [BackdropScaffoldState].
          */
         fun Saver(
             animationSpec: AnimationSpec<Float>,
             confirmStateChange: (BackdropValue) -> Boolean,
-            snackbarHostState: SnackbarHostState
+            snackbarHostState: SnackbarHostState,
+            density: Density
         ): Saver<BackdropScaffoldState, *> = Saver(
-            save = { it.currentValue },
+            save = { it.anchoredDraggableState.currentValue },
             restore = {
                 BackdropScaffoldState(
                     initialValue = it,
                     animationSpec = animationSpec,
-                    confirmStateChange = confirmStateChange,
-                    snackbarHostState = snackbarHostState
+                    confirmValueChange = confirmStateChange,
+                    snackbarHostState = snackbarHostState,
+                    density = density
                 )
             }
         )
@@ -171,8 +261,9 @@
     initialValue: BackdropValue,
     animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
     confirmStateChange: (BackdropValue) -> Boolean = { true },
-    snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }
+    snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
 ): BackdropScaffoldState {
+    val density = LocalDensity.current
     return rememberSaveable(
         animationSpec,
         confirmStateChange,
@@ -180,14 +271,16 @@
         saver = BackdropScaffoldState.Saver(
             animationSpec = animationSpec,
             confirmStateChange = confirmStateChange,
-            snackbarHostState = snackbarHostState
+            snackbarHostState = snackbarHostState,
+            density = density
         )
     ) {
         BackdropScaffoldState(
             initialValue = initialValue,
             animationSpec = animationSpec,
-            confirmStateChange = confirmStateChange,
-            snackbarHostState = snackbarHostState
+            confirmValueChange = confirmStateChange,
+            snackbarHostState = snackbarHostState,
+            density = density
         )
     }
 }
@@ -275,6 +368,12 @@
     frontLayerScrimColor: Color = BackdropScaffoldDefaults.frontLayerScrimColor,
     snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }
 ) {
+    // b/278692145 Remove this once deprecated methods without density are removed
+    val density = LocalDensity.current
+    SideEffect {
+        scaffoldState.density = density
+    }
+
     val peekHeightPx = with(LocalDensity.current) { peekHeight.toPx() }
     val headerHeightPx = with(LocalDensity.current) { headerHeight.toPx() }
 
@@ -285,13 +384,16 @@
                 backLayerContent()
             }
         } else {
-            BackLayerTransition(scaffoldState.targetValue, appBar, backLayerContent)
+            BackLayerTransition(scaffoldState.anchoredDraggableState.targetValue,
+                appBar, backLayerContent)
         }
     }
     val calculateBackLayerConstraints: (Constraints) -> Constraints = {
         it.copy(minWidth = 0, minHeight = 0).offset(vertical = -headerHeightPx.roundToInt())
     }
 
+    val state = scaffoldState.anchoredDraggableState
+
     // Back layer
     Surface(
         color = backLayerBackgroundColor,
@@ -314,27 +416,46 @@
                 Modifier
             }
 
+            val calculateAnchors = { layoutSize: IntSize ->
+                val sheetHeight = layoutSize.height.toFloat()
+                val collapsedHeight = layoutSize.height - peekHeightPx
+                DraggableAnchors {
+                    if (sheetHeight == 0f || sheetHeight == peekHeightPx) {
+                        Concealed at collapsedHeight
+                    } else {
+                        Concealed at peekHeightPx
+                        Revealed at revealedHeight
+                    }
+                }
+            }
             val swipeable = Modifier
                 .then(nestedScroll)
-                .swipeable(
-                    state = scaffoldState,
-                    anchors = mapOf(
-                        peekHeightPx to Concealed,
-                        revealedHeight to Revealed
-                    ),
+                .anchoredDraggable(
+                    state = state,
                     orientation = Orientation.Vertical,
-                    enabled = gesturesEnabled
+                    enabled = gesturesEnabled,
                 )
+                .onSizeChanged { layoutSize ->
+                    val newAnchors = calculateAnchors(layoutSize)
+                    val newTarget = when (scaffoldState.targetValue) {
+                        Concealed -> Concealed
+                        Revealed -> if (newAnchors.hasAnchorFor(Revealed)) Revealed else Concealed
+                    }
+                    state.updateAnchors(
+                        newAnchors = newAnchors,
+                        newTarget = newTarget
+                    )
+                }
                 .semantics {
                     if (scaffoldState.isConcealed) {
                         collapse {
-                            if (scaffoldState.confirmStateChange(Revealed)) {
+                            if (scaffoldState.confirmValueChange(Revealed)) {
                                 scope.launch { scaffoldState.reveal() }
                             }; true
                         }
                     } else {
                         expand {
-                            if (scaffoldState.confirmStateChange(Concealed)) {
+                            if (scaffoldState.confirmValueChange(Concealed)) {
                                 scope.launch { scaffoldState.conceal() }
                             }; true
                         }
@@ -344,7 +465,7 @@
             // Front layer
             Surface(
                 Modifier
-                    .offset { IntOffset(0, scaffoldState.offset.value.roundToInt()) }
+                    .offset { IntOffset(0, state.requireOffset().toInt()) }
                     .then(swipeable),
                 shape = frontLayerShape,
                 elevation = frontLayerElevation,
@@ -356,11 +477,11 @@
                     Scrim(
                         color = frontLayerScrimColor,
                         onDismiss = {
-                            if (gesturesEnabled && scaffoldState.confirmStateChange(Concealed)) {
+                            if (gesturesEnabled && scaffoldState.confirmValueChange(Concealed)) {
                                 scope.launch { scaffoldState.conceal() }
                             }
                         },
-                        visible = scaffoldState.targetValue == Revealed
+                        visible = scaffoldState.anchoredDraggableState.targetValue == Revealed
                     )
                 }
             }
@@ -426,23 +547,27 @@
     )
     val animationSlideOffset = with(LocalDensity.current) { AnimationSlideOffset.toPx() }
 
-    val appBarFloat = (animationProgress - 1).coerceIn(0f, 1f)
-    val contentFloat = (1 - animationProgress).coerceIn(0f, 1f)
+    val appBarFloat = (animationProgress - 1).fastCoerceIn(0f, 1f)
+    val contentFloat = (1 - animationProgress).fastCoerceIn(0f, 1f)
 
     Box {
         Box(
-            Modifier.zIndex(appBarFloat).graphicsLayer(
-                alpha = appBarFloat,
-                translationY = (1 - appBarFloat) * animationSlideOffset
-            )
+            Modifier
+                .zIndex(appBarFloat)
+                .graphicsLayer(
+                    alpha = appBarFloat,
+                    translationY = (1 - appBarFloat) * animationSlideOffset
+                )
         ) {
             appBar()
         }
         Box(
-            Modifier.zIndex(contentFloat).graphicsLayer(
-                alpha = contentFloat,
-                translationY = (1 - contentFloat) * -animationSlideOffset
-            )
+            Modifier
+                .zIndex(contentFloat)
+                .graphicsLayer(
+                    alpha = contentFloat,
+                    translationY = (1 - contentFloat) * -animationSlideOffset
+                )
         ) {
             content()
         }
@@ -521,3 +646,60 @@
 }
 
 private val AnimationSlideOffset = 20.dp
+private val VelocityThreshold = 125.dp
+private val PositionalThreshold = 56.dp
+
+@OptIn(ExperimentalMaterialApi::class)
+internal fun ConsumeSwipeNestedScrollConnection(
+    state: AnchoredDraggableState<*>,
+    orientation: Orientation
+): NestedScrollConnection = object : NestedScrollConnection {
+    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+        val delta = available.toFloat()
+        return if (delta < 0 && source == NestedScrollSource.Drag) {
+            state.dispatchRawDelta(delta).toOffset()
+        } else {
+            Offset.Zero
+        }
+    }
+
+    override fun onPostScroll(
+        consumed: Offset,
+        available: Offset,
+        source: NestedScrollSource
+    ): Offset {
+        return if (source == NestedScrollSource.Drag) {
+            state.dispatchRawDelta(available.toFloat()).toOffset()
+        } else {
+            Offset.Zero
+        }
+    }
+
+    override suspend fun onPreFling(available: Velocity): Velocity {
+        val toFling = available.toFloat()
+        val currentOffset = state.requireOffset()
+        return if (toFling < 0 && currentOffset > state.anchors.minAnchor()) {
+            state.settle(velocity = toFling)
+            // since we go to the anchor with tween settling, consume all for the best UX
+            available
+        } else {
+            Velocity.Zero
+        }
+    }
+
+    override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
+        state.settle(velocity = available.toFloat())
+        return available
+    }
+
+    private fun Float.toOffset(): Offset = Offset(
+        x = if (orientation == Orientation.Horizontal) this else 0f,
+        y = if (orientation == Orientation.Vertical) this else 0f
+    )
+
+    @JvmName("velocityToFloat")
+    private fun Velocity.toFloat() = if (orientation == Orientation.Horizontal) x else y
+
+    @JvmName("offsetToFloat")
+    private fun Offset.toFloat(): Float = if (orientation == Orientation.Horizontal) x else y
+}
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
index a216b26..5e7b8dc 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
@@ -36,7 +36,6 @@
 import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.selectableGroup
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -218,7 +217,7 @@
     // The color of the Ripple should always the selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
     // provided by BottomNavigationTransition.
-    val ripple = rememberRipple(bounded = false, color = selectedContentColor)
+    val ripple = rippleOrFallbackImplementation(bounded = false, color = selectedContentColor)
 
     Box(
         modifier
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt
index a894c83..2a9e24b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Checkbox.kt
@@ -29,7 +29,6 @@
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.triStateToggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
@@ -145,7 +144,7 @@
                 enabled = enabled,
                 role = Role.Checkbox,
                 interactionSource = interactionSource,
-                indication = rememberRipple(
+                indication = rippleOrFallbackImplementation(
                     bounded = false,
                     radius = CheckboxRippleRadius
                 )
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index bd51ba9..d9d7236 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -65,6 +65,7 @@
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import kotlin.math.max
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CancellationException
@@ -782,7 +783,7 @@
 }
 
 private fun calculateFraction(a: Float, b: Float, pos: Float) =
-    ((pos - a) / (b - a)).coerceIn(0f, 1f)
+    ((pos - a) / (b - a)).fastCoerceIn(0f, 1f)
 
 @Composable
 private fun BottomDrawerScrim(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
index fc5182e..ee51276 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
@@ -21,7 +21,6 @@
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.remember
@@ -71,7 +70,7 @@
                 enabled = enabled,
                 role = Role.Button,
                 interactionSource = interactionSource,
-                indication = rememberRipple(bounded = false, radius = RippleRadius)
+                indication = rippleOrFallbackImplementation(bounded = false, radius = RippleRadius)
             ),
         contentAlignment = Alignment.Center
     ) {
@@ -116,7 +115,7 @@
             enabled = enabled,
             role = Role.Checkbox,
             interactionSource = interactionSource,
-            indication = rememberRipple(bounded = false, radius = RippleRadius)
+            indication = rippleOrFallbackImplementation(bounded = false, radius = RippleRadius)
         ),
         contentAlignment = Alignment.Center
     ) {
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
index eaf511a..b8fa051 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
@@ -18,12 +18,8 @@
 
 import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.text.selection.LocalTextSelectionColors
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.runtime.remember
 
@@ -67,13 +63,15 @@
         // provided, and overwrite the values set in it.
         colors.copy()
     }.apply { updateColorsFrom(colors) }
-    val rippleIndication = rememberRipple()
+    val rippleIndication = rippleOrFallbackImplementation()
     val selectionColors = rememberTextSelectionColors(rememberedColors)
+    @Suppress("DEPRECATION_ERROR")
     CompositionLocalProvider(
         LocalColors provides rememberedColors,
         LocalContentAlpha provides ContentAlpha.high,
         LocalIndication provides rippleIndication,
-        LocalRippleTheme provides MaterialRippleTheme,
+        // TODO: b/304985887 - remove after one stable release
+        androidx.compose.material.ripple.LocalRippleTheme provides CompatRippleTheme,
         LocalShapes provides shapes,
         LocalTextSelectionColors provides selectionColors,
         LocalTypography provides typography
@@ -120,19 +118,3 @@
         @ReadOnlyComposable
         get() = LocalShapes.current
 }
-
-@Immutable
-private object MaterialRippleTheme : RippleTheme {
-
-    @Composable
-    override fun defaultColor() = RippleTheme.defaultRippleColor(
-            contentColor = LocalContentColor.current,
-            lightTheme = MaterialTheme.colors.isLight
-        )
-
-    @Composable
-    override fun rippleAlpha() = RippleTheme.defaultRippleAlpha(
-        contentColor = LocalContentColor.current,
-        lightTheme = MaterialTheme.colors.isLight
-    )
-}
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
index f3dd3808..2cb6d22 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
@@ -35,7 +35,6 @@
 import androidx.compose.foundation.layout.sizeIn
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Immutable
@@ -148,7 +147,7 @@
                 enabled = enabled,
                 onClick = onClick,
                 interactionSource = interactionSource,
-                indication = rememberRipple(true)
+                indication = rippleOrFallbackImplementation(true)
             )
             .fillMaxWidth()
             // Preferred min and max width used during the intrinsic measurement.
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt
index bf876d0..44b01378 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt
@@ -37,7 +37,6 @@
 import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.selectableGroup
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -226,7 +225,7 @@
     // The color of the Ripple should always the selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
     // provided by NavigationRailTransition.
-    val ripple = rememberRipple(
+    val ripple = rippleOrFallbackImplementation(
         bounded = false,
         color = selectedContentColor
     )
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ProgressIndicator.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ProgressIndicator.kt
index 9be72a8..ff76abf 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ProgressIndicator.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ProgressIndicator.kt
@@ -49,6 +49,7 @@
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.offset
+import androidx.compose.ui.util.fastCoerceIn
 import kotlin.math.PI
 import kotlin.math.abs
 import kotlin.math.max
@@ -108,7 +109,7 @@
     backgroundColor: Color = color.copy(alpha = IndicatorBackgroundOpacity),
     strokeCap: StrokeCap = StrokeCap.Butt,
 ) {
-    val coercedProgress = progress.coerceIn(0f, 1f)
+    val coercedProgress = progress.fastCoerceIn(0f, 1f)
     Canvas(
         modifier
             .increaseSemanticsBounds()
@@ -324,7 +325,7 @@
     backgroundColor: Color = Color.Transparent,
     strokeCap: StrokeCap = StrokeCap.Butt,
 ) {
-    val coercedProgress = progress.coerceIn(0f, 1f)
+    val coercedProgress = progress.fastCoerceIn(0f, 1f)
     val stroke = with(LocalDensity.current) {
         Stroke(width = strokeWidth.toPx(), cap = strokeCap)
     }
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt
index cf73687..9798b22 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/RadioButton.kt
@@ -28,7 +28,6 @@
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.selectable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
@@ -92,7 +91,7 @@
                 enabled = enabled,
                 role = Role.RadioButton,
                 interactionSource = interactionSource,
-                indication = rememberRipple(
+                indication = rippleOrFallbackImplementation(
                     bounded = false,
                     radius = RadioButtonRippleRadius
                 )
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Ripple.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Ripple.kt
new file mode 100644
index 0000000..4d7f703
--- /dev/null
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Ripple.kt
@@ -0,0 +1,461 @@
+/*
+ * 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.compose.material
+
+import androidx.compose.foundation.Indication
+import androidx.compose.foundation.IndicationNodeFactory
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.material.ripple.RippleAlpha
+import androidx.compose.material.ripple.createRippleModifierNode
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.compositionLocalOf
+import androidx.compose.runtime.staticCompositionLocalOf
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.graphics.isSpecified
+import androidx.compose.ui.graphics.luminance
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DelegatingNode
+import androidx.compose.ui.node.ObserverModifierNode
+import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.node.observeReads
+import androidx.compose.ui.unit.Dp
+
+/**
+ * Creates a Ripple using the provided values and values inferred from the theme.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new animation, and
+ * responds to other [Interaction]s by showing a fixed state layer with varying alpha values
+ * depending on the [Interaction].
+ *
+ * [MaterialTheme] provides Ripples using [androidx.compose.foundation.LocalIndication], so a Ripple
+ * will be used as the default [Indication] inside components such as
+ * [androidx.compose.foundation.clickable] and [androidx.compose.foundation.indication], in
+ * addition to Material provided components that use a Ripple as well.
+ *
+ * You can also explicitly create a Ripple and provide it to custom components in order to change
+ * the parameters from the default, such as to create an unbounded ripple with a fixed size.
+ *
+ * To create a Ripple with a manually defined color that can change over time, see the other
+ * [ripple] overload with a [ColorProducer] parameter. This will avoid unnecessary recompositions
+ * when changing the color, and preserve existing ripple state when the color changes.
+ *
+ * @param bounded If true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have [RippleDefaults.rippleAlpha]
+ * applied to calculate the final color used to draw the ripple. If [Color.Unspecified] is
+ * provided the color used will be [RippleDefaults.rippleColor] instead.
+ */
+@Stable
+fun ripple(
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified,
+    color: Color = Color.Unspecified
+): IndicationNodeFactory {
+    return if (radius == Dp.Unspecified && color == Color.Unspecified) {
+        if (bounded) return DefaultBoundedRipple else DefaultUnboundedRipple
+    } else {
+        RippleNodeFactory(bounded, radius, color)
+    }
+}
+
+/**
+ * Creates a Ripple using the provided values and values inferred from the theme.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new ripple animation, and
+ * responds to other [Interaction]s by showing a fixed state layer with varying alpha values
+ * depending on the [Interaction].
+ *
+ * [MaterialTheme] provides Ripples using [androidx.compose.foundation.LocalIndication], so a Ripple
+ * will be used as the default [Indication] inside components such as
+ * [androidx.compose.foundation.clickable] and [androidx.compose.foundation.indication], in
+ * addition to Material provided components that use a Ripple as well.
+ *
+ * You can also explicitly create a Ripple and provide it to custom components in order to change
+ * the parameters from the default, such as to create an unbounded ripple with a fixed size.
+ *
+ * To create a Ripple with a static color, see the [ripple] overload with a [Color] parameter. This
+ * overload is optimized for Ripples that have dynamic colors that change over time, to reduce
+ * unnecessary recompositions.
+ *
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have [RippleDefaults.rippleAlpha]
+ * applied to calculate the final color used to draw the ripple. If you are creating this
+ * [ColorProducer] outside of composition (where it will be automatically remembered), make sure
+ * that its instance is stable (such as by remembering the object that holds it), or remember the
+ * returned [ripple] object to make sure that ripple nodes are not being created each recomposition.
+ * @param bounded If true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ */
+@Stable
+fun ripple(
+    color: ColorProducer,
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified
+): IndicationNodeFactory {
+    return RippleNodeFactory(bounded, radius, color)
+}
+
+/**
+ * Default values used by [ripple].
+ */
+object RippleDefaults {
+    /**
+     * Represents the default color that will be used for a ripple if a color has not been
+     * explicitly set on the ripple instance.
+     *
+     * @param contentColor the color of content (text or iconography) in the component that
+     * contains the ripple.
+     * @param lightTheme whether the theme is light or not
+     */
+    fun rippleColor(
+        contentColor: Color,
+        lightTheme: Boolean
+    ): Color {
+        val contentLuminance = contentColor.luminance()
+        // If we are on a colored surface (typically indicated by low luminance content), the
+        // ripple color should be white.
+        return if (!lightTheme && contentLuminance < 0.5) {
+            Color.White
+            // Otherwise use contentColor
+        } else {
+            contentColor
+        }
+    }
+
+    /**
+     * Represents the default [RippleAlpha] that will be used for a ripple to indicate different
+     * states.
+     *
+     * @param contentColor the color of content (text or iconography) in the component that
+     * contains the ripple.
+     * @param lightTheme whether the theme is light or not
+     */
+    fun rippleAlpha(contentColor: Color, lightTheme: Boolean): RippleAlpha {
+        return when {
+            lightTheme -> {
+                if (contentColor.luminance() > 0.5) {
+                    LightThemeHighContrastRippleAlpha
+                } else {
+                    LightThemeLowContrastRippleAlpha
+                }
+            }
+            else -> {
+                DarkThemeRippleAlpha
+            }
+        }
+    }
+}
+
+/**
+ * Temporary CompositionLocal to allow configuring whether the old ripple implementation that uses
+ * the deprecated [androidx.compose.material.ripple.RippleTheme] API should be used in Material
+ * components and LocalIndication, instead of the new [ripple] API. This flag defaults to false,
+ * and will be removed after one stable release: it should only be used to temporarily unblock
+ * upgrading.
+ *
+ * Provide this CompositionLocal before you provide [MaterialTheme] to make sure it is correctly
+ * provided through LocalIndication.
+ */
+// TODO: b/304985887 - remove after one stable release
+@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+@get:ExperimentalMaterialApi
+@ExperimentalMaterialApi
+val LocalUseFallbackRippleImplementation: ProvidableCompositionLocal<Boolean> =
+    staticCompositionLocalOf { false }
+
+/**
+ * CompositionLocal used for providing [RippleConfiguration] down the tree. This acts as a
+ * tree-local 'override' for ripples used inside components that you cannot directly control, such
+ * as to change the color of a specific component's ripple, or disable it entirely.
+ *
+ * In most cases you should rely on the default theme behavior for consistency with other components
+ * - this exists as an escape hatch for individual components and is not intended to be used for
+ * full theme customization across an application. For this use case you should instead build your
+ * own custom ripple that queries your design system theme values directly using
+ * [createRippleModifierNode].
+ */
+@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+@get:ExperimentalMaterialApi
+@ExperimentalMaterialApi
+val LocalRippleConfiguration: ProvidableCompositionLocal<RippleConfiguration> =
+    compositionLocalOf { RippleConfiguration() }
+
+/**
+ * Configuration for [ripple] appearance, provided using [LocalRippleConfiguration]. In most cases
+ * the default values should be used, for custom design system use cases you should instead
+ * build your own custom ripple using [createRippleModifierNode].
+ *
+ * @param isEnabled whether the ripple is enabled. If false, no ripple will be rendered
+ * @param color the color override for the ripple. If [Color.Unspecified], then the default color
+ * from the theme will be used instead. Note that if the ripple has a color explicitly set with
+ * the parameter on [ripple], that will always be used instead of this value.
+ * @param rippleAlpha the [RippleAlpha] override for this ripple. If null, then the default alpha
+ * will be used instead.
+ */
+@Immutable
+@ExperimentalMaterialApi
+class RippleConfiguration(
+    val isEnabled: Boolean = true,
+    val color: Color = Color.Unspecified,
+    val rippleAlpha: RippleAlpha? = null
+) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is RippleConfiguration) return false
+
+        if (isEnabled != other.isEnabled) return false
+        if (color != other.color) return false
+        if (rippleAlpha != other.rippleAlpha) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = isEnabled.hashCode()
+        result = 31 * result + color.hashCode()
+        result = 31 * result + (rippleAlpha?.hashCode() ?: 0)
+        return result
+    }
+
+    override fun toString(): String {
+        return "RippleConfiguration(enabled=$isEnabled, color=$color, rippleAlpha=$rippleAlpha)"
+    }
+}
+
+// TODO: b/304985887 - remove after one stable release
+@Suppress("DEPRECATION_ERROR")
+@OptIn(ExperimentalMaterialApi::class)
+@Composable
+internal fun rippleOrFallbackImplementation(
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified,
+    color: Color = Color.Unspecified
+): Indication {
+    return if (LocalUseFallbackRippleImplementation.current) {
+        androidx.compose.material.ripple.rememberRipple(bounded, radius, color)
+    } else {
+        ripple(bounded, radius, color)
+    }
+}
+
+// TODO: b/304985887 - remove after one stable release
+@Suppress("DEPRECATION_ERROR")
+@Immutable
+internal object CompatRippleTheme : androidx.compose.material.ripple.RippleTheme {
+
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun defaultColor() = RippleDefaults.rippleColor(
+        contentColor = LocalContentColor.current,
+        lightTheme = MaterialTheme.colors.isLight
+    )
+
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun rippleAlpha() = RippleDefaults.rippleAlpha(
+        contentColor = LocalContentColor.current,
+        lightTheme = MaterialTheme.colors.isLight
+    )
+}
+
+@Stable
+private class RippleNodeFactory private constructor(
+    private val bounded: Boolean,
+    private val radius: Dp,
+    private val colorProducer: ColorProducer?,
+    private val color: Color
+) : IndicationNodeFactory {
+    constructor(
+        bounded: Boolean,
+        radius: Dp,
+        colorProducer: ColorProducer
+    ) : this(bounded, radius, colorProducer, Color.Unspecified)
+
+    constructor(
+        bounded: Boolean,
+        radius: Dp,
+        color: Color
+    ) : this(bounded, radius, null, color)
+
+    override fun create(interactionSource: InteractionSource): DelegatableNode {
+        val colorProducer = colorProducer ?: ColorProducer { color }
+        return DelegatingThemeAwareRippleNode(interactionSource, bounded, radius, colorProducer)
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is RippleNodeFactory) return false
+
+        if (bounded != other.bounded) return false
+        if (radius != other.radius) return false
+        if (colorProducer != other.colorProducer) return false
+        return color == other.color
+    }
+
+    override fun hashCode(): Int {
+        var result = bounded.hashCode()
+        result = 31 * result + radius.hashCode()
+        result = 31 * result + colorProducer.hashCode()
+        result = 31 * result + color.hashCode()
+        return result
+    }
+}
+
+@OptIn(ExperimentalMaterialApi::class)
+private class DelegatingThemeAwareRippleNode(
+    private val interactionSource: InteractionSource,
+    private val bounded: Boolean,
+    private val radius: Dp,
+    private val color: ColorProducer,
+) : DelegatingNode(), CompositionLocalConsumerModifierNode, ObserverModifierNode {
+    private var rippleNode: DelegatableNode? = null
+
+    override fun onAttach() {
+        observeReads {
+            updateConfiguration()
+        }
+    }
+
+    override fun onObservedReadsChanged() {
+        updateConfiguration()
+    }
+
+    /**
+     * Handles changes to [RippleConfiguration.isEnabled]. Changes to [RippleConfiguration.color] and
+     * [RippleConfiguration.rippleAlpha] are handled as part of the ripple definition.
+     */
+    private fun updateConfiguration() {
+        val configuration = currentValueOf(LocalRippleConfiguration)
+        if (!configuration.isEnabled) {
+            removeRipple()
+        } else {
+            if (rippleNode == null) attachNewRipple()
+        }
+    }
+
+    private fun attachNewRipple() {
+        val calculateColor = ColorProducer {
+            val userDefinedColor = color()
+            if (userDefinedColor.isSpecified) {
+                userDefinedColor
+            } else {
+                val rippleConfiguration = currentValueOf(LocalRippleConfiguration)
+                if (rippleConfiguration.color.isSpecified) {
+                    rippleConfiguration.color
+                } else {
+                    RippleDefaults.rippleColor(
+                        contentColor = currentValueOf(LocalContentColor),
+                        lightTheme = currentValueOf(LocalColors).isLight
+                    )
+                }
+            }
+        }
+        val calculateRippleAlpha = {
+            val rippleConfiguration = currentValueOf(LocalRippleConfiguration)
+            rippleConfiguration.rippleAlpha ?: RippleDefaults.rippleAlpha(
+                contentColor = currentValueOf(LocalContentColor),
+                lightTheme = currentValueOf(LocalColors).isLight
+            )
+        }
+
+        rippleNode = delegate(createRippleModifierNode(
+            interactionSource,
+            bounded,
+            radius,
+            calculateColor,
+            calculateRippleAlpha
+        ))
+    }
+
+    private fun removeRipple() {
+        rippleNode?.let { undelegate(it) }
+    }
+}
+
+private val DefaultBoundedRipple = RippleNodeFactory(
+    bounded = true,
+    radius = Dp.Unspecified,
+    color = Color.Unspecified
+)
+
+private val DefaultUnboundedRipple = RippleNodeFactory(
+    bounded = false,
+    radius = Dp.Unspecified,
+    color = Color.Unspecified
+)
+
+/**
+ * Alpha values for high luminance content in a light theme.
+ *
+ * This content will typically be placed on colored surfaces, so it is important that the
+ * contrast here is higher to meet accessibility standards, and increase legibility.
+ *
+ * These levels are typically used for text / iconography in primary colored tabs /
+ * bottom navigation / etc.
+ */
+private val LightThemeHighContrastRippleAlpha = RippleAlpha(
+    pressedAlpha = 0.24f,
+    focusedAlpha = 0.24f,
+    draggedAlpha = 0.16f,
+    hoveredAlpha = 0.08f
+)
+
+/**
+ * Alpha levels for low luminance content in a light theme.
+ *
+ * This content will typically be placed on grayscale surfaces, so the contrast here can be lower
+ * without sacrificing accessibility and legibility.
+ *
+ * These levels are typically used for body text on the main surface (white in light theme, grey
+ * in dark theme) and text / iconography in surface colored tabs / bottom navigation / etc.
+ */
+private val LightThemeLowContrastRippleAlpha = RippleAlpha(
+    pressedAlpha = 0.12f,
+    focusedAlpha = 0.12f,
+    draggedAlpha = 0.08f,
+    hoveredAlpha = 0.04f
+)
+
+/**
+ * Alpha levels for all content in a dark theme.
+ */
+private val DarkThemeRippleAlpha = RippleAlpha(
+    pressedAlpha = 0.10f,
+    focusedAlpha = 0.12f,
+    draggedAlpha = 0.08f,
+    hoveredAlpha = 0.04f
+)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
index 31e5a89..bfb70a7 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
@@ -51,7 +51,6 @@
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.progressSemantics
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.LaunchedEffect
@@ -93,6 +92,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.util.fastMinByOrNull
 import androidx.compose.ui.util.lerp
@@ -721,7 +721,10 @@
                 .size(thumbSize, thumbSize)
                 .indication(
                     interactionSource = interactionSource,
-                    indication = rememberRipple(bounded = false, radius = ThumbRippleRadius)
+                    indication = rippleOrFallbackImplementation(
+                        bounded = false,
+                        radius = ThumbRippleRadius
+                    )
                 )
                 .hoverable(interactionSource = interactionSource)
                 .shadow(if (enabled) elevation else 0.dp, CircleShape, clip = false)
@@ -831,7 +834,7 @@
 
 // Calculate the 0..1 fraction that `pos` value represents between `a` and `b`
 private fun calcFraction(a: Float, b: Float, pos: Float) =
-    (if (b - a == 0f) 0f else (pos - a) / (b - a)).coerceIn(0f, 1f)
+    (if (b - a == 0f) 0f else (pos - a) / (b - a)).fastCoerceIn(0f, 1f)
 
 @Composable
 private fun CorrectValueSideEffect(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Surface.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Surface.kt
index a10749c..3b3e069 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Surface.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Surface.kt
@@ -28,7 +28,6 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.remember
@@ -241,7 +240,7 @@
                 )
                 .clickable(
                     interactionSource = interactionSource,
-                    indication = rememberRipple(),
+                    indication = rippleOrFallbackImplementation(),
                     enabled = enabled,
                     onClick = onClick
                 ),
@@ -356,7 +355,7 @@
                 .selectable(
                     selected = selected,
                     interactionSource = interactionSource,
-                    indication = rememberRipple(),
+                    indication = rippleOrFallbackImplementation(),
                     enabled = enabled,
                     onClick = onClick
                 ),
@@ -471,7 +470,7 @@
                 .toggleable(
                     value = checked,
                     interactionSource = interactionSource,
-                    indication = rememberRipple(),
+                    indication = rippleOrFallbackImplementation(),
                     enabled = enabled,
                     onValueChange = onCheckedChange
                 ),
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
index afacdfd..fc39fae 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
@@ -54,6 +54,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.fastMaxBy
 import androidx.compose.ui.util.fastMinByOrNull
 import androidx.compose.ui.util.lerp
@@ -708,7 +709,7 @@
     fun computeResistance(overflow: Float): Float {
         val factor = if (overflow < 0) factorAtMin else factorAtMax
         if (factor == 0f) return 0f
-        val progress = (overflow / basis).coerceIn(-1f, 1f)
+        val progress = (overflow / basis).fastCoerceIn(-1f, 1f)
         return basis / factor * sin(progress * PI.toFloat() / 2)
     }
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
index c3e25c4..49c7733 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
@@ -37,7 +37,6 @@
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.toggleable
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.LaunchedEffect
@@ -262,7 +261,10 @@
             .offset { IntOffset(thumbValue().roundToInt(), 0) }
             .indication(
                 interactionSource = interactionSource,
-                indication = rememberRipple(bounded = false, radius = ThumbRippleRadius)
+                indication = rippleOrFallbackImplementation(
+                    bounded = false,
+                    radius = ThumbRippleRadius
+                )
             )
             .requiredSize(ThumbDiameter)
             .shadow(elevation, CircleShape, clip = false)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt
index c41b10f..bd48fc3 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Tab.kt
@@ -33,7 +33,6 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.selection.selectable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -164,7 +163,7 @@
     // The color of the Ripple should always the be selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
     // provided by TabTransition.
-    val ripple = rememberRipple(bounded = true, color = selectedContentColor)
+    val ripple = rippleOrFallbackImplementation(bounded = true, color = selectedContentColor)
 
     TabTransition(selectedContentColor, unselectedContentColor, selected) {
         Row(
@@ -234,7 +233,7 @@
     // The color of the Ripple should always the selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
     // provided by TabTransition.
-    val ripple = rememberRipple(bounded = true, color = selectedContentColor)
+    val ripple = rippleOrFallbackImplementation(bounded = true, color = selectedContentColor)
 
     TabTransition(selectedContentColor, unselectedContentColor, selected) {
         Column(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
index 197f1a41..37904b7 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldDefaults.kt
@@ -208,13 +208,13 @@
 @Immutable
 object TextFieldDefaults {
     /**
-     * The default min width applied for a [TextField] and [OutlinedTextField].
+     * The default min height applied to a [TextField] and [OutlinedTextField].
      * Note that you can override it by applying Modifier.heightIn directly on a text field.
      */
     val MinHeight = 56.dp
 
     /**
-     * The default min width applied for a [TextField] and [OutlinedTextField].
+     * The default min width applied to a [TextField] and [OutlinedTextField].
      * Note that you can override it by applying Modifier.widthIn directly on a text field.
      */
     val MinWidth = 280.dp
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicator.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicator.kt
index e8c1323..414cbd9 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicator.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicator.kt
@@ -51,6 +51,7 @@
 import androidx.compose.ui.graphics.drawscope.rotate
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import kotlin.math.abs
 import kotlin.math.max
 import kotlin.math.min
@@ -187,7 +188,7 @@
     // How far beyond the threshold pull has gone, as a percentage of the threshold.
     val overshootPercent = abs(progress) - 1.0f
     // Limit the overshoot to 200%. Linear between 0 and 200.
-    val linearTension = overshootPercent.coerceIn(0f, 2f)
+    val linearTension = overshootPercent.fastCoerceIn(0f, 2f)
     // Non-linear tension. Increases with linearTension, but at a decreasing rate.
     val tensionPercent = linearTension - linearTension.pow(2) / 4
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicatorTransform.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicatorTransform.kt
index f398c5a..d780486 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicatorTransform.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshIndicatorTransform.kt
@@ -24,6 +24,7 @@
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.platform.inspectable
+import androidx.compose.ui.util.fastCoerceIn
 
 /**
  * A modifier for translating the position and scaling the size of a pull-to-refresh indicator
@@ -67,7 +68,7 @@
             if (scale && !state.refreshing) {
                 val scaleFraction = LinearOutSlowInEasing
                     .transform(state.position / state.threshold)
-                    .coerceIn(0f, 1f)
+                    .fastCoerceIn(0f, 1f)
                 scaleX = scaleFraction
                 scaleY = scaleFraction
             }
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt
index 746c057..5cc559f 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt
@@ -33,6 +33,7 @@
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
 import kotlin.math.abs
 import kotlin.math.pow
 import kotlinx.coroutines.CoroutineScope
@@ -197,7 +198,7 @@
             // How far beyond the threshold pull has gone, as a percentage of the threshold.
             val overshootPercent = abs(progress) - 1.0f
             // Limit the overshoot to 200%. Linear between 0 and 200.
-            val linearTension = overshootPercent.coerceIn(0f, 2f)
+            val linearTension = overshootPercent.fastCoerceIn(0f, 2f)
             // Non-linear tension. Increases with linearTension, but at a decreasing rate.
             val tensionPercent = linearTension - linearTension.pow(2) / 4
             // The additional offset beyond the threshold.
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/TabRowBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/TabRowBenchmark.kt
index e892880..d69b104 100644
--- a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/TabRowBenchmark.kt
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/TabRowBenchmark.kt
@@ -28,6 +28,7 @@
 import androidx.compose.testutils.LayeredComposeTestCase
 import androidx.compose.testutils.ToggleableTestCase
 import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkToFirstPixel
 import androidx.compose.testutils.benchmark.toggleStateBenchmarkComposeMeasureLayout
 import org.junit.Rule
 import org.junit.Test
@@ -40,7 +41,7 @@
 
     @Test
     fun firstPixel() {
-        benchmarkRule.benchmarkFirstRenderUntilStable(tabRowTestCaseFactory)
+        benchmarkRule.benchmarkToFirstPixel(tabRowTestCaseFactory)
     }
 
     @Test
diff --git a/compose/material3/material3-adaptive/build.gradle b/compose/material3/material3-adaptive/build.gradle
index 340ee40..476b13f 100644
--- a/compose/material3/material3-adaptive/build.gradle
+++ b/compose/material3/material3-adaptive/build.gradle
@@ -58,7 +58,7 @@
             dependsOn(jvmMain)
             dependencies {
                 api("androidx.annotation:annotation:1.1.0")
-                implementation(project(":window:window"))
+                implementation("androidx.window:window:1.2.0")
             }
         }
 
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt
index 77310445..a25f6b9 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt
@@ -85,6 +85,44 @@
         }
 }
 
+internal fun Modifier.animatedPane(): Modifier {
+    return this.then(AnimatedPaneElement)
+}
+
+private object AnimatedPaneElement : ModifierNodeElement<AnimatedPaneNode>() {
+    private val inspectorInfo = debugInspectorInfo {
+        name = "isPaneComposable"
+        value = true
+    }
+
+    override fun create(): AnimatedPaneNode {
+        return AnimatedPaneNode()
+    }
+
+    override fun update(node: AnimatedPaneNode) {
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        inspectorInfo()
+    }
+
+    override fun hashCode(): Int {
+        return 0
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return (other is AnimatedPaneElement)
+    }
+}
+
+private class AnimatedPaneNode : ParentDataModifierNode, Modifier.Node() {
+    override fun Density.modifyParentData(parentData: Any?) =
+        ((parentData as? PaneScaffoldParentData) ?: PaneScaffoldParentData()).also {
+            it.isAnimatedPane = true
+        }
+}
+
 internal data class PaneScaffoldParentData(
     var preferredWidth: Float? = null,
+    var isAnimatedPane: Boolean = false
 )
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt
index aae4e8f..a31ec41 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt
@@ -28,7 +28,10 @@
 import androidx.compose.animation.slideOutHorizontally
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.geometry.Offset
@@ -149,11 +152,13 @@
         },
     )
 
-    val measurePolicy =
-        remember { ThreePaneContentMeasurePolicy(scaffoldDirective, scaffoldValue, ltrPaneOrder) }
-    measurePolicy.scaffoldDirective = scaffoldDirective
-    measurePolicy.scaffoldValue = scaffoldValue
-    measurePolicy.paneOrder = ltrPaneOrder
+    val measurePolicy = remember {
+        ThreePaneContentMeasurePolicy(scaffoldDirective, scaffoldValue, ltrPaneOrder)
+    }.apply {
+        this.scaffoldDirective = scaffoldDirective
+        this.scaffoldValue = scaffoldValue
+        this.paneOrder = ltrPaneOrder
+    }
 
     LookaheadScope {
         Layout(
@@ -328,10 +333,13 @@
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 private class ThreePaneContentMeasurePolicy(
-    var scaffoldDirective: PaneScaffoldDirective,
-    var scaffoldValue: ThreePaneScaffoldValue,
-    var paneOrder: ThreePaneScaffoldHorizontalOrder
+    scaffoldDirective: PaneScaffoldDirective,
+    scaffoldValue: ThreePaneScaffoldValue,
+    paneOrder: ThreePaneScaffoldHorizontalOrder
 ) : MultiContentMeasurePolicy {
+    var scaffoldDirective by mutableStateOf(scaffoldDirective)
+    var scaffoldValue by mutableStateOf(scaffoldValue)
+    var paneOrder by mutableStateOf(paneOrder)
 
     /**
      * Data class that is used to store the position and width of an expanded pane to be reused when
@@ -642,6 +650,10 @@
         // When panes are being hidden, apply each pane's width and position from the cache to
         // maintain the those before it's hidden by the AnimatedVisibility.
         measurables.fastForEach {
+            if (!it.isAnimatedPane) {
+                // When panes are not animated, we don't need to measure and place them.
+                return
+            }
             val cachedPanePlacement = placementsCache[it.role]!!
             it.measure(
                 Constraints.fixed(
@@ -684,6 +696,7 @@
     AnimatedVisibility(
         visible = paneAdaptedValue == PaneAdaptedValue.Expanded,
         modifier = modifier
+            .animatedPane()
             .clipToBounds(paneAdaptedValue)
             .then(
                 if (paneAdaptedValue == PaneAdaptedValue.Expanded) {
@@ -722,6 +735,8 @@
     } else {
         data.preferredWidth!!.toInt()
     }
+
+    val isAnimatedPane = data.isAnimatedPane
 }
 
 /**
diff --git a/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/MaterialImportDetectorTest.kt b/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/MaterialImportDetectorTest.kt
index 5bdd89c..32e0cb6 100644
--- a/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/MaterialImportDetectorTest.kt
+++ b/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/MaterialImportDetectorTest.kt
@@ -41,7 +41,7 @@
     private val MaterialButtonStub = bytecodeStub(
         filename = "Button.kt",
         filepath = "androidx/compose/material",
-        checksum = 0x94880e7a,
+        checksum = 0x3ab9ae7,
         """
             package androidx.compose.material
 
@@ -49,26 +49,27 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
         TSxJLcpMzBHicCotKcnP8y7hMuNSxalMr6A0J6coNa0otThDiDcAyAmCcID6
-        dLgUcOsryiwoyEkV4ggC00DVvFzMafn5QmwhqcUl3iVKDFoMAB7yTT20AAAA
+        dLgUcOsryiwoyEkV4ggC00DValxSOFUbI7mGl4s5LT9fiC0ktbjEu0SJQYsB
+        AAY211PcAAAA
         """,
         """
         androidx/compose/material/ButtonKt.class:
-        H4sIAAAAAAAA/yVOu07DQBCcPSdOYh5xCC+npIIGJ4iOCpCQLAJIgNKkusQn
-        dMS+Q/Y5SplfoqVAqfkoxB3eYnZ2Zla7P79f3wAuERFOuEoLLdNVPNf5hy5F
-        nHMjCsmz+KYyRqt70wIRwne+5HHG1Vv8NHsXc6t6BL/OELzTswmhN15ok0kV
-        PwjDU274FYHlS88eIwdtByDQwhFmzZV0bGhZOiL0N2s/2KwDFrKBH27WAzYk
-        Z12Q2+rUx84XhtC41akgdMdSiccqn4nilc8yqwQvuirm4k66IXqulJG5mMhS
-        WvdaKW24kVqVGIGhgfqdCE34th/YKUJd9PlvHVp0FmyY4ch9jX0c2z6yassu
-        tqfwEnQSBAm2sJ1gB7sJuginoBI97E3BSjRL9P8AKS93K3cBAAA=
+        H4sIAAAAAAAA/yVOu07DQBCcPScOMY84hJdTUkGDE0RHBUhIFgEkQGlSXeIT
+        usS+Q/Y5SplfoqVAqfkoxB3eYnZ2Zla7P79f3wCuEBFOuUoLLdNVPNP5hy5F
+        nHMjCsmz+LYyRqsH0wIRwjlf8jjj6j1+ns7FzKoewa8zBO/sfEzojhbaZFLF
+        j8LwlBt+TWD50rPHyEHbAQi0cIRZcyUdG1iWDgm9zdoPNuuAhazvh5t1nw3I
+        WZfkttr1sYuFITTudCoInZFU4qnKp6J449PMKsGrroqZuJduiF4qZWQuxrKU
+        1r1RShtupFYlhmBooH4nQhO+7Yd2ilAXff5bRxadBRtmOHZf4wAntg+t2rKL
+        WxN4CdoJggTb2Emwi70EHYQTUIku9idgJZolen+absHWdwEAAA==
         """
     )
 
     private val ExperimentalMaterialApiStub = bytecodeStub(
         filename = "ExperimentalMaterialApi.kt",
         filepath = "androidx/compose/material",
-        checksum = 0x6caaf88f,
+        checksum = 0x4808c29,
         """
             package androidx.compose.material
 
@@ -81,31 +82,31 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
         TSxJLcpMzBHicCotKcnP8y7hMuNSxalMr6A0J6coNa0otThDiDcAyAmCcID6
         dLgUcOsryiwoyEkV4ggC00DValxSOFUbI7mGl4s5LT9fiC0ktbjEu0SJQYsB
-        ANpB3LXcAAAA
+        AAY211PcAAAA
         """,
         """
         androidx/compose/material/ExperimentalMaterialApi.class:
-        H4sIAAAAAAAA/5VSwW4TMRB93pAmpEDTAiVpKDUcyq3bFm6ctgjQSimtEoRU
-        5eQkQ+Nmd52uvVF6y41/4oAijnwUYlY0JBJFiMv4zbxnzxvb3398+QrgJZ4J
-        HKiknxrdn/g9E4+MJT9WjlKtIv/NZMQgpsSp6Pi6GIx0CUKgeqHGyo9Ucu6f
-        dC+o50ooCOwsqipJjFNOm8QPfsMSigKbzaFxkU78Fl1mOiV7MnJh8kqgFJO1
-        6pwEzj4MtJVzIzI4DSXntORHsu28FukhRVfSGdkbcFuSJs2TLsmUYjMmFiXS
-        DUh+ylyW0p7A9rz9ksMWOT6VEbsojlWUsYfnN+gWkyzvWDkK3wetMwHZvHH+
-        Ze3uPySnJtK9q9zG62bQbgusz20ck1N95RRzXjwu8PuJPJTzAAEx5PpE59k+
-        o/6BQH02LVe8mlfxqo3yt89ebTY99PbF0WyaCw4FXjT/+/G5Ozfb+gu7N3QC
-        lbbJ0h691RHfYr2V8VwxfdRWdyNaXKAVaFxzYTL+g91li7jFrVby8VDADkcP
-        TyB5fcd5hblVwh3cxb1fcA1VrKOIjQ4KIe6HeBDiITYZ4lGIGuodCIstNDrw
-        LB5bbOMpH7bKu/lLo2xx+yc4GLrsGQMAAA==
+        H4sIAAAAAAAA/5VSTW8TMRB93pAmTflIC5SkodRwaG/dtnDjtEWAVkpplSCk
+        KicnGRo3u+uw9kbpLTf+EwcUceRHIWZFQyJRhLiM38x79ryx/f3Hl68AXuCZ
+        wKFK+qnR/YnfM/HIWPJj5SjVKvJfT0YMYkqcik6ui8FIlyAEqpdqrPxIJRf+
+        afeSeq6EgsDOoqqSxDjltEn84DcsoSiw2RwaF+nEb9GnTKdkT0cuTF4KlGKy
+        Vl2QwPn7gbZybkQGZ6HknJb8SLad1yI9pOhKOiN7A25L0qR50iWZUmzGxKJE
+        ugHJj5nLUtoX2J63X3LYIsenMmIXxbGKMvawd4NuMcnyjpXj8F3QOheQzRvn
+        X9bu/kNyZiLdu8ptvGoG7bbA+tzGCTnVV04x58XjAr+fyMNqHiAghlyf6Dw7
+        YNQ/FKjPpuWKV/MqXrVR/vbZq82mR96BOJ5Nc8GRwPPmfz8+d+dmW39h94dO
+        oNI2WdqjNzriW6y3Mp4rpg/a6m5Eiwu0Ao1rLkzGf7C7bBG3uNVKPh4K2OHo
+        4Qkkr285rzC3RriNO7j7C95DFesoYqODQoj7IR6EeIhNhngUooZ6B8JiC40O
+        PIvHFtt4yoet8W7+0ihbrP4EIBEHSxkDAAA=
         """
     )
 
     private val Material3ButtonStub = bytecodeStub(
         filename = "Button.kt",
         filepath = "androidx/compose/material3",
-        checksum = 0x8bce80e4,
+        checksum = 0x314468f6,
         """
             package androidx.compose.material3
 
@@ -113,27 +114,27 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
         TSxJLcpMzBHicCotKcnP8y7hMuNSxalMr6A0J6coNa0otThDiDcAyAmCcID6
         dLgUcOsryiwoyEkV4ggC00DValxSOFUbI7mGl4s5LT9fiC0ktbjEu0SJQYsB
-        ANpB3LXcAAAA
+        AAY211PcAAAA
         """,
         """
         androidx/compose/material3/ButtonKt.class:
-        H4sIAAAAAAAA/yVOTU/CQBB9s4UC9YMifpWrF71YUG+e1MSkETVRw4XTQjdm
-        ge6adks48pe8ejCc/VHGXTuHN2/ee5OZn9+vbwBXiAgnXKW5lukqnursQxci
-        zrgRueSLy/i2NEarB9MAEcIZX/J4wdV7/DyZialVPYJfZQje6dmI0BnOtVlI
-        FT8Kw1Nu+DWBZUvPXiMHTQcg0NwRZs2VdKxvWTogdDdrP9isAxaynh9u1j3W
-        J2ddkNtqVcfO54ZQu9OpILSHUomnMpuI/I1PFlYJXnWZT8W9dEP0UiojMzGS
-        hbTujVLacCO1KjAAQw3VOxHq8G0/sFOEqujz3zq06CzYMMOR+xr7OLZ9YNWG
-        XWyO4SVoJQgSbGE7wQ52E7QRjkEFOtgbgxWoF+j+AX2HBh54AQAA
+        H4sIAAAAAAAA/yVOu07DQBCcPScOMY84hJfT0kCDE6CjAiQkiwASoDSpLvEJ
+        HbHvkH2OUuaXaClQaj4KcYe3mJ2dmdXuz+/XN4BLRIRjrtJCy3QZz3T+oUsR
+        59yIQvLsIr6pjNHq3rRAhPCdL3iccfUWP03fxcyqHsGvMwTv5HRM6I7m2mRS
+        xQ/C8JQbfkVg+cKz18hB2wEINHeEWXMpHRtYlg4JvfXKD9argIWs74frVZ8N
+        yFnn5Lba9bGzuSE0bnUqCJ2RVOKxyqeieOXTzCrBi66KmbiTboieK2VkLsay
+        lNa9VkobbqRWJYZgaKB+J0ITvu37dopQF33+WwcWnQUbZjh0X2MPR7YPrdqy
+        ixsTeAnaCYIEm9hKsI2dBB2EE1CJLnYnYCWaJXp/zsaw43gBAAA=
         """
     )
 
     private val RippleStub = bytecodeStub(
         filename = "Ripple.kt",
         filepath = "androidx/compose/material/ripple",
-        checksum = 0x2f218395,
+        checksum = 0x691c7742,
         """
             package androidx.compose.material.ripple
 
@@ -141,26 +142,27 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
         TSxJLcpMzBHicCotKcnP8y7hMuNSxalMr6A0J6coNa0otThDiDcAyAmCcID6
-        dLgUcOsryiwoyEkV4ggC00DVvFzMafn5QmwhqcUl3iVKDFoMAB7yTT20AAAA
+        dLgUcOsryiwoyEkV4ggC00DValxSOFUbI7mGl4s5LT9fiC0ktbjEu0SJQYsB
+        AAY211PcAAAA
         """,
         """
         androidx/compose/material/ripple/RippleKt.class:
-        H4sIAAAAAAAA/yVOTU/CQBB9s+WzKhTxq/wCuVgw3jwZE5NG1AQNF04L3ZiF
-        dpe0C+HIX/LqwXD2Rxl36Rzem5k3k/d+/75/ANwhJPS5SnItk20019lKFyLK
-        uBG55GmUy9UqFdH4QM+mDiIEC77hUcrVZ/Q2W4i53XqEVi4ykc1EXt4SvOv+
-        hNAZLbVJpYpehOEJN/yewLKNZ73JQcMBCLR0DbPiVrpuYLtkSOjudzV/v/NZ
-        wHq1YL/rsQE56ZbcV7M0u1kaQuVRJ9a2PZJKvK5dkg8+c0H8d73O5+JJuiEc
-        r5WRmZjIQlr1QSltuJFaFRiCoYIyTogqapbP7RSiLPo6SBcWnQR7zHDpUuMM
-        V5aHdlu3j40pvBjNGH6MIxzHOEErRhvBFFSgg9MpWIFqge4/mpQXSIYBAAA=
+        H4sIAAAAAAAA/yVOTU/CQBB9s+VDqkIRv8ovkIsF4s2TMTFpRE3QcOG00I1Z
+        aHdJuxCO/CWvHgxnf5Rxl87hvZl5M3nv9+/7B8AdQkKPqyTXMtlGc52tdCGi
+        jBuRS55GuVytUhGND/Rs6iBCsOAbHqVcfUZvs4WY261HaOYiE9lM5OUtwbvp
+        TQjt0VKbVKroRRiecMPvCSzbeNabHDQcgEBL1zArbqXr+rZLBoTOflfz9zuf
+        BaxbC/a7LuuTk4bkvhql2e3SECqPOrG2rZFU4nXtknzwmQviv+t1PhdP0g3h
+        eK2MzMREFtKqD0ppw43UqsAADBWUcUJUUbN8YacQZdHXQbq06CTYY4Yrlxrn
+        uLY8sNu6fTyawovRiOHHOMZJjFM0Y7QQTEEF2jibghWoFuj8AynVobWGAQAA
         """
         )
 
     private val IconsStub = bytecodeStub(
         filename = "Icons.kt",
         filepath = "androidx/compose/material/icons",
-        checksum = 0x1643e419,
+        checksum = 0xe246828f,
         """
             package androidx.compose.material.icons
 
@@ -168,51 +170,53 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
         TSxJLcpMzBHicCotKcnP8y7hMuNSxalMr6A0J6coNa0otThDiDcAyAmCcID6
-        dLgUcOsryiwoyEkV4ggC00DVvFzMafn5QmwhqcUl3iVKDFoMAB7yTT20AAAA
+        dLgUcOsryiwoyEkV4ggC00DValxSOFUbI7mGl4s5LT9fiC0ktbjEu0SJQYsB
+        AAY211PcAAAA
         """,
         """
         androidx/compose/material/icons/Icons.class:
-        H4sIAAAAAAAA/42SzW7TQBSFz0wSx3UDDeWnCQUKtIifBW4rdlRIpQLJkjES
-        rSKhrib2qExizyB7EnWZFQ/CG1QsKoGEItjxUIg7JoIFG2zp3nvu3Pk8c+Qf
-        Pz9/BfAEWwz3hM5Ko7LTMDXFe1PJsBBWlkrkoUqNrsLIxTYYQ3ckpiLMhT4J
-        Xw9HMrVtNBi8PaWVfcbQePBw0EELXoAm2gxN+05VDPfj//rCUwZ/L81rVgDu
-        AH6UHB7tJwcvOriAYImaFxk2Y1OehCNph6VQtFlobaywyoESY5NJnhPqUjw2
-        lmDhK2lFJqygHi+mDbo1c8F3AQxsTP1T5dQ2VdkOw9Z8FgS8xwPepWo+879/
-        4L35bJdvs+dtn3/76PEud7O7zBH8+vSPx5Zh/c1EW1XISE9VpYa53P97NrLj
-        wGSSYSVWWiaTYijLI0EzDKuxSUU+EOQI6UUzODSTMpUvlRP9BXjwDxY75Eqz
-        vkrfmUT5FimPcpcyp7dVqw1Sobsw5dajc/hn9fLtxTAIcodi5/cAlghFLmH5
-        z+Y1mnbP8hfwt+fofMLKWd3guFvHm9is/ykynwCrx2hEuBzhSoSruEYl1iL0
-        0D8Gq3Ad67ReIahwo4L3C+qkwQ6QAgAA
+        H4sIAAAAAAAA/42Sz27TQBDGv90kjuMGmhZoEwq00CL+HHBbcaNCKhVIloyR
+        aBWp6mljr9pNbC+yN1GPOfEgvEHFoRKVUAQ3HgoxayI4cGEtzcw3O/vbnZF/
+        /PzyFcBzbDE8FHlSaJWc+7HOPuhS+pkwslAi9VWs89IPrG2CMXSGYiL8VOSn
+        /rvBUMamiRqDs6dyZV4y1B4/6bfRgOOhjiZD3ZypkuFR+F83vGBw9+K0Ynng
+        FuAG0eHRfnTwuo1r8FqUvM6wGeri1B9KMyiEosMiz7URRllQpE00TlNCLYUj
+        bQjmv5VGJMIIyvFsUqOumTUta8DARpQ/V1ZtU5TsMGzNpp7Hu9zjHYpmU/f7
+        R96dTXf5NnvVdPm3Tw7vcFu7yyzBrV7/bGQY1t6Pc6MyGeQTVapBKvf/vo3G
+        caATybAYqlxG42wgiyNBNQzLoY5F2hc0EdLzpHeox0Us3ygrenNw/x8sdmgq
+        9aqVnh0S+XukHPId8py+RqXWSfm2YfKNp5dwL6rtjXkxCHKfbPt3AVqEAlws
+        /Dm8StV2LVyBH1+i/RmLF1WC40Fl72Kz+qdo+ARYPkEtwI0ANwPcwgqFWA3Q
+        Re8ErMRtrNF+Ca/EnRLOL4cbczOQAgAA
         """
         )
 
     private val PullRefreshStub = bytecodeStub(
         filename = "PullRefresh.kt",
         filepath = "androidx/compose/material/pullrefresh",
-        checksum = 0x20bedb6d,
+        checksum = 0xfa59248b,
         """
             package androidx.compose.material.pullrefresh
 
             fun pullRefresh() {}
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuWSTMxLKcrPTKnQS87PLcgvTtXL
         TSxJLcpMzBHicCotKcnP8y7hMuNSxalMr6A0J6coNa0otThDiDcAyAmCcID6
-        dLgUcOsryiwoyEkV4ggC00DVvFzMafn5QmwhqcUl3iVKDFoMAB7yTT20AAAA
+        dLgUcOsryiwoyEkV4ggC00DValxSOFUbI7mGl4s5LT9fiC0ktbjEu0SJQYsB
+        AAY211PcAAAA
         """,
         """
         androidx/compose/material/pullrefresh/PullRefreshKt.class:
-        H4sIAAAAAAAA/01OTU/CQBSct+XLolDEr/IL9GJBvXkyJiaN+BE0XDgtdNWF
-        tkvaLeHIX/LqwXD2Rxl35aDvMG/ezLxkvr4/PgFcwCec8zTKlIyWwUQlc5WL
-        IOFaZJLHwbyI40y8ZCJ/Cx4NH2z4ra6CCN6UL3gQ8/Q1eBhPxcSoDqE+/wsS
-        nOOTIaHVnykdyzS4E5pHXPNLAksWjqlAFmoWQKCZJcyYS2lZ17CoR2ivVxV3
-        vXKZxzoVb73qsC5Z64zsV+NftdOZJpSuVSQIzb5MxX2RjEX2zMexUdwnVWQT
-        cSPt4Q+KVMtEDGUujXuVpkpzLVWaoweGEjadfJRRMXvfXD42Q++/1oFBa8GE
-        GQ5tdezhyOyeUavmsTaCE2IrhBuiju0QO2iEaMIbgXK0sDsCy1HO0f4B7wOm
-        OJIBAAA=
+        H4sIAAAAAAAA/01OTU/CQBSct+VDikIRv8ov0IsF9ebJmJg04kfQcOG00FUX
+        2i5pt4Qjf8mrB8PZH2XclYO+w7x5M/OS+fr++ARwAZ9wztMoUzJaBhOVzFUu
+        goRrkUkeB/MijjPxkon8LXg0fLDht7oKInhTvuBBzNPX4GE8FROjOoT6/C9I
+        cI5PhoRWf6Z0LNPgTmgecc0vCSxZOKYCWahZAIFmljBjLqVlXcOiHqG9XlXc
+        9cplHutUvPWqw7pkrTOyX41/1U5nmlC6VpEgNPsyFfdFMhbZMx/HRnGfVJFN
+        xI20hz8oUi0TMZS5NO5VmirNtVRpjh4YSth08lFGxex9c/nYDL3/WgcGrQUT
+        Zji01bGHI7N7Rq2ax60RnBC1EG6IOrZD7KARoglvBMrRwu4ILEc5R/sHIVOo
+        LJIBAAA=
         """
         )
 
diff --git a/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/ScaffoldPaddingDetectorTest.kt b/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/ScaffoldPaddingDetectorTest.kt
index 014f0ab..303273a 100644
--- a/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/ScaffoldPaddingDetectorTest.kt
+++ b/compose/material3/material3-lint/src/test/java/androidx/compose/material3/lint/ScaffoldPaddingDetectorTest.kt
@@ -43,7 +43,7 @@
     private val ScaffoldStub = bytecodeStub(
         filename = "Scaffold.kt",
         filepath = "androidx/compose/material3",
-        checksum = 0xfee46355,
+        checksum = 0xc74cb7f7,
         """
             package androidx.compose.material3
 
@@ -60,74 +60,75 @@
             ) {}
 
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGI2Bijg0uCSSsxLKcrPTKnQS87PLcgvTtXL
-        TSxJLcpMzDEW4gpOTkxLy89J8S7h4uViTsvPF2ILSS0u8S5RYtBiAACpks1u
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uCSSsxLKcrPTKnQS87PLcgvTtXL
+        TSxJLcpMzDEW4gpOTkxLy89J8S7h4uViTsvPF2ILSS0u8S5RYtBiAABi9Cyd
         UQAAAA==
         """,
         """
         androidx/compose/material3/ScaffoldKt$Scaffold$1.class:
-        H4sIAAAAAAAAAKVU604TQRT+Zlt62RZbEOUi3kFbULYt3ktICIG4oWBisYnh
+        H4sIAAAAAAAA/6VU604TQRT+Zlt62RZbEOUi3kFbULYt3ktICIG4oWBisYnh
         17S7haG7s6a7bfAfD+ET+ASiiSSaGOJPH8p4ZmkNhogaN9mzJ+d835lzm/32
         /dMXAPfwhKHApdX2hLVnNDz3lefbhssDuy24M29UG7zZ9BxrLZjqq1PFOBjD
         WqXlBY6Qxm7XNYQkguSOUeFu3eLlk75mRzYC4UnfWO1phYW+/4UUQXmxzDDx
         +2BxRBmunB0wjhhDbEFQuEWGSC5fY4jmzHwtjQR0HQNIkSHYET5DqfKv9VJ+
         MSG7XstmGMnlK7u8yw2Hy23jWX3XbgTlNDJI6tAwxJA6UVoc5xkS5kZ1c2lj
         eYVh8Je607iAi0mMYJRACw0nzF4lHIaaUO5zSdImGYb6xHU74BYPOKWkud0I
-        jZApEVMCDKyllAg594TSCqRZRYbJo/2EfrSva1mNPtmj/QmtwJ7qX9/GtISm
+        jZApkVQCDKyllAg594TSCqRZRYbJo/2EfrSva1mNPtmj/QmtwJ7qX9/GtISm
         MCVKfIFLT752vY5PPaRg03/VpzjuMGR/Nsuym7zjBAxvcqf73BHGumeJprDb
         f1qR//QXy+bpMal1mINBpfbTnWtRptFlz6LJDle8BndqnAqsO/amEgyZipD2
         Rset2+2eJW1KabeXHe77Nm1TZkU2HM8XcptGs+NZDMmq2JY86LQJrFe9Trth
-        rwrFHH/ekYFw7ZrwBYVaktILeJg2CjTmAWo53SyMq7nT7KL00i6QpUTaFCGY
-        mvRM5BDpg3Da8yTTx1YMhpwhtYg9xmyIoVeBNbrqCqYMqRNEdkzMLhEx2yOW
-        1CKpw2c+Yvg9xt6dwU/0Dk5Q2v2DRwmtntRnaC8PcekDLh+EhgHcJ6kT7Bgw
-        hgdhnXep/ofhIRE8Cr9FPA7/TnTxiXV1CxET10xcN3EDN01qxrSJW7i9BeYj
-        hzz5fcz4mPWR+QHL6C/y2gQAAA==
+        rwrFHH/ekYFw7ZrwBYVaktILeJg2CjTmAWo53SyMq7nT7KL00i6QpUTaFCFo
+        KojNRA6RPginPU8yfWzFYMgZUovYY8yGGHoVWKOrrmDKkDpBZMfE7BIRsz1i
+        SS2SOnzmI4bfY+zdGfxE7+AEpd0/eJTQ6kl9hvbyEJc+4PJBaBjAfZI6wY4B
+        Y3gQ1nmX6n8YHhLBo/BbxOPw70QXn1hXtxAxcc3EdRM3cNOkZkybuIXbW2A+
+        csiT38eMj1kfmR/t8cYr2gQAAA==
         """,
         """
         androidx/compose/material3/ScaffoldKt$Scaffold$2.class:
-        H4sIAAAAAAAAAKVUbU/TUBR+bjf2xnADUV7Ed9ANlI7h+wgJIRAbBiYOlxg+
+        H4sIAAAAAAAA/6VUbU/TUBR+bjf2xnADUV7Ed9ANlI7h+wgJIRAbBiYOlxg+
         3bUdXNbemrVd8Bs/wl/gLxBNNNHEED/6o4znlk0xRNTYpKcn5zzPueft9uu3
         j58B3MEjhhKXVtsT1p5ueu4Lz7d1lwd2W3BnXq+ZvNn0HGstmOypk+UkGMNa
         teUFjpD6bsfVhSSC5I5e5W7D4pXjvmYozUB40tdXu1ppoed/JkVQWawwjP8+
         WBJxhkunB0wiwZBYEBRukSFWKNYZ4gWjWM8ihUwGfegnQ7AjfIZy9V/rpfwS
         Qna8ls0wXChWd3mH6w6X2/qTxq5tBpUsckhnoGGQof9YaUmcZUgZG7XNpY3l
         FYaBX+rO4hzOpzGMEQItmE6UvUo4CjWu3GfSpE0wDPaI63bALR5wSklzOzEa
-        IVMioQQYWEspMXLuCaWVSLPmGCYO91OZw/2Mltfokz/cH9dK7HHmy+uEltIU
+        IVMirQQYWEspMXLuCaWVSLPmGCYO91OZw/2Mltfokz/cH9dK7HHmy+uEltIU
         pkyJL3DpyZeuF/rUQwo29Vd9SuIWQ/5Hsyy7yUMnYHhVONnnUOjrniWawm7/
         aUX+0z9XMU6OSa3DLHQqtZfubIsyjS97Fk12qOqZ3KlzKrDh2JtKMOSqQtob
         oduw211L1pDSbi873Pdt2qbcijQdzxdym0az41kM6ZrYljwI2wTO1Lywbdqr
-        QjHHnoYyEK5dF76gUEtSegGP0kaJxtxHLaebhTE1d5pdnF7aBbKUSZskBFOT
-        no59QPYgmvY8yeyRFQMRZ1AtYpcxE2HoVWCNrrqCsYjyk8iOiPklIua7xLJa
-        JHX49HsMvcXom1P4qe7BKUq7d/AIodXT/wna8w+48A4XDyJDH+6SzBDsCDCK
-        e1Gdt6n++9EhMTyIvnN4GP2d6OIT6/IWYgauGLhq4BquG9SMKQM3cHMLzEcB
-        RfL7mPYx4yP3HfQNQiHaBAAA
+        QjHHnoYyEK5dF76gUEtSegGP0kaJxtxHLaebhTE1d5pdnF7aBbKUSZskBE0F
+        ienYB2QPomnPk8weWTEQcQbVInYZMxGGXgXW6KorGIsoP4nsiJhfImK+Syyr
+        RVKHT7/H0FuMvjmFn+oenKK0ewePEFo9/Z+gPf+AC+9w8SAy9OEuyQzBjgCj
+        uBfVeZvqvx8dEsOD6DuHh9HfiS4+sS5vIWbgioGrBq7hukHNmDJwAze3wHwU
+        UCS/j2kfMz5y3wHSFKv42gQAAA==
         """,
         """
         androidx/compose/material3/ScaffoldKt.class:
-        H4sIAAAAAAAAAMVUS3PbVBT+ru1YkmOnrhKniVtCaRya5lHZbnk6FFLTtCK2
-        6eA2m6yuZdkolq8yemTKhgnDX2DDln8Aqw4LxsOSf8EfYXok2yGNOwm0zLDQ
-        Pc97zneOzj1//PXrbwDuos6wwkXbdaz2M81w+oeOZ2p97puuxe07WtPgnY5j
-        t3d9CYwhe8CPuGZz0dW+bB2YBmnjDPLYi+G71dpEtMDS6k7b6limW6n1HN+2
-        hHZw1Nc6gTB8yxGetjPiim9oL1Vu7TH8+WYYtsb2p8LyK/f+W/fS1uYkuI4T
-        iDYPzdTab5zA1x7zdtsS3T1uB6ZXOZMhrHFlMoobCN/qm1o1knnLNisMyzXH
-        7WoHpt9yuUU4uBCOz4eYGo7fCGybvOT+qDcyUgxLpyqwBE2C4LamC9+lAJbh
-        SUgz5IyvTaM3ivCYu7xvkiPDzdXa2RGpnNI0wyBdqiCNGVxKIYMsQ9J3Du9z
-        yq0yKC3H951+JM4xSIZDAIQvY55wnf9bGa5fND0XupTIJTue5kLb7PDA9hl+
-        +J+nWp9sajgE184DJeEtamc4DFxQEIbzayiceFbSeBvXFSzhHYbiP9oNhZOW
-        lSQs0zzpjeaT7Ub1AUN5MusFESj/Ct5VUMDNl2fxFZ2TcOvfYyxLWH8NYOUI
-        2KaCDdxOYwrJFGIoMlwe/7266XN6xpxmKNY/itN6ZeGRDA8wsF7IxMj4zAo5
-        uhprlxi+HxzfSA2OU7FsLCILJyT65NiYzz/NDo7zsSIryzI5ExcvzxKXyGfU
-        hEr64tTvPyVjcjLSShPaK1k5PxvpUiOLMrQ8kkIoZRaiVMfVnH41E8rwnbyi
-        gRctMobpcTtv9+hdJapO22S4VLOE2Qj6LdN9Eu6tMKFjcHuP098geaRUmlZX
-        cD9wib/61XDb6eLI8iwyb/+92BgKZ60nG+olt0zT50avzg9HCdK6EKZbtbnn
-        mWRONZ3ANcwdK7QtjkLuTaRDieYgEf5joovhYJBUJYmP9Itr6vRzXF5XZ+nc
-        UHN0bqpX6Pw5uvJ5OCPU+QVaiQ+IXxteQoo0iDiVPhZxc/TFIm4eecSxE0WQ
-        8HAUQyb6KLQnSFCisTtzZhVcxTXiQ4R9SpUkWs4lEt/+iNQvuDHA0m4uMTWU
-        VgdYq+US0lDSSKqvrW9sPkdpCF2ncwrxmUwmqmKJkICSSIR9hmgO05RKwTLS
-        VJVCeL8gu0oXC1FlC/SUhnQ3CncfNaI1AlemsHf2EddxV8d7Ot7HBzo+xEc6
-        PkZlH8zDFj7Zx7SHKQ/3PKQ8LHhQPXzqQfYw52Hew2cetl8ABZTb8egIAAA=
+        H4sIAAAAAAAA/8VUy3IbVRA9V695WEoU2XJsJTghlhPHj4ykhKdMwBExGSwp
+        KZR449XVaCTGHt1xzcMVNpQpfoENW/4AVikWlIolf8GPUOkZScaxUnYgVLGY
+        vv263ad7+vYff/36G4B7eMywxEXHdazOc81w+geOZ2p97puuxe27Wsvg3a5j
+        d7Z9CYwhu8cPuWZz0dMet/dMg7RxBnnsxfDdcn0iWmBpDadjdS3Trdb3Hd+2
+        hLZ32Ne6gTB8yxGetjXiSm9pL1dv7zD8+XYYNsb2Z8Lyq/f/W/fyxvokuK4T
+        iA4PzdTab5zA157wTscSvR1uB6ZXPZUhrHFpMoobCN/qm1otknnbNqsMi3XH
+        7Wl7pt92uUU4uBCOz4eYmo7fDGybvOT+qDcyVIaFExVYgiZBcFvThe9SAMvw
+        JKQZ8sbXprE/ivCEu7xvkiPDreX66RGpntC0wiA9qiCNC7ioIoMsQ8p3Dh5w
+        yp1jUNqO7zv9SJxhkAyHAAhfxizhOvu3Mlw/b3rOdSmTS3Y8zcWO2eWB7TP8
+        8D9PtT7Z1HAIrp4FSsI71M5wGLigIAxn11A89qymcQ3XFSzgXYbSG+2G4nHL
+        yhIWaZ70ZuvpZrP2kKEymfWcCJR/CTcVFHHr1Vl8Teck3P7nGCsSVv8FsEoE
+        bF3BGu6kkURKRQwlhkvjv9cwfU7PmNMMxfqHcVqvLCRKSMDA9kMmRsbnVsjR
+        1VinzPD94OiGOjhSY9lYdMwdH9Enx8Z84Vl2cFSIlVhFlsmZuHhlmrhEIZNL
+        5EhfSv7+UyompyKtNKG9nJUL05FOHVmUoeWRFEKpsBBlblzNyVczoQzfyWsa
+        eN4iY7j5ZjMo4QHD1Lj1d/bpDSZqTsdkuFi3hNkM+m3TfRruuBCcY3B7h9Of
+        I3mkVFpWT3A/cIm/8tVwM+ri0PIsMm/+vQQZiqetx9vsFbdMy+fGfoMfjBKk
+        dSFMt2ZzzzPJrLacwDXMLSu0zY9C7kykQ5lmJhHOA53z4RCR9JAkPtLPr+Sm
+        XuDSam6a6FouT3Q9d5noz9GVLaIp+ktztD6/IH5leAkqaRBxOfpYxM3QF4u4
+        WRQQx6MoggR9FEOm88vQniBBiUb0FM0quIKrxIcI+5QqRWcln0h8+yPUX3Bj
+        gIXtfCI5lJYHWKnnE9JQ0khqrKyurb9AeQh9m2gS8QuZTFTFAiGht0FUpVoU
+        5DFFqRQsIk1VKYS3TvYQdzGqbI6e3fCs0d1rVFUjCvs5mnTWCWSFwt/dRVzH
+        PR3v6XgfH+j4EB/p+BjVXTAPG/hkF1Mekh7ue1A9zHnIefjUg+xhxsOsh888
+        bL4EoWeehRwJAAA=
         """
     )
 
diff --git a/compose/material3/material3-window-size-class/api/1.2.0-beta01.txt b/compose/material3/material3-window-size-class/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..7da9b6a
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/1.2.0-beta01.txt
@@ -0,0 +1,60 @@
+// Signature format: 4.0
+package androidx.compose.material3.windowsizeclass {
+
+  public final class AndroidWindowSizeClass_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi @androidx.compose.runtime.Composable public static androidx.compose.material3.windowsizeclass.WindowSizeClass calculateWindowSizeClass(android.app.Activity activity);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This material3-window-size-class API is experimental and is likely to change or to " + "be removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3WindowSizeClassApi {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowHeightSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowHeightSizeClass.Companion Companion;
+  }
+
+  public static final class WindowHeightSizeClass.Companion {
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> getAllSizeClasses();
+    method public int getCompact();
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> getDefaultSizeClasses();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> AllSizeClasses;
+    property public final int Compact;
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> DefaultSizeClasses;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+  @androidx.compose.runtime.Immutable public final class WindowSizeClass {
+    method public int getHeightSizeClass();
+    method public int getWidthSizeClass();
+    property public final int heightSizeClass;
+    property public final int widthSizeClass;
+    field public static final androidx.compose.material3.windowsizeclass.WindowSizeClass.Companion Companion;
+  }
+
+  public static final class WindowSizeClass.Companion {
+    method @SuppressCompatibility @androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi public androidx.compose.material3.windowsizeclass.WindowSizeClass calculateFromSize(long size, optional java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> supportedWidthSizeClasses, optional java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> supportedHeightSizeClasses);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowWidthSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowWidthSizeClass.Companion Companion;
+  }
+
+  public static final class WindowWidthSizeClass.Companion {
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> getAllSizeClasses();
+    method public int getCompact();
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> getDefaultSizeClasses();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> AllSizeClasses;
+    property public final int Compact;
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> DefaultSizeClasses;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+}
+
diff --git a/compose/material3/material3-window-size-class/api/res-1.2.0-beta01.txt b/compose/material3/material3-window-size-class/api/res-1.2.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/res-1.2.0-beta01.txt
diff --git a/compose/material3/material3-window-size-class/api/restricted_1.2.0-beta01.txt b/compose/material3/material3-window-size-class/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..7da9b6a
--- /dev/null
+++ b/compose/material3/material3-window-size-class/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,60 @@
+// Signature format: 4.0
+package androidx.compose.material3.windowsizeclass {
+
+  public final class AndroidWindowSizeClass_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi @androidx.compose.runtime.Composable public static androidx.compose.material3.windowsizeclass.WindowSizeClass calculateWindowSizeClass(android.app.Activity activity);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This material3-window-size-class API is experimental and is likely to change or to " + "be removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3WindowSizeClassApi {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowHeightSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowHeightSizeClass.Companion Companion;
+  }
+
+  public static final class WindowHeightSizeClass.Companion {
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> getAllSizeClasses();
+    method public int getCompact();
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> getDefaultSizeClasses();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> AllSizeClasses;
+    property public final int Compact;
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> DefaultSizeClasses;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+  @androidx.compose.runtime.Immutable public final class WindowSizeClass {
+    method public int getHeightSizeClass();
+    method public int getWidthSizeClass();
+    property public final int heightSizeClass;
+    property public final int widthSizeClass;
+    field public static final androidx.compose.material3.windowsizeclass.WindowSizeClass.Companion Companion;
+  }
+
+  public static final class WindowSizeClass.Companion {
+    method @SuppressCompatibility @androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi public androidx.compose.material3.windowsizeclass.WindowSizeClass calculateFromSize(long size, optional java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> supportedWidthSizeClasses, optional java.util.Set<androidx.compose.material3.windowsizeclass.WindowHeightSizeClass> supportedHeightSizeClasses);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class WindowWidthSizeClass implements java.lang.Comparable<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> {
+    method public operator int compareTo(int other);
+    field public static final androidx.compose.material3.windowsizeclass.WindowWidthSizeClass.Companion Companion;
+  }
+
+  public static final class WindowWidthSizeClass.Companion {
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> getAllSizeClasses();
+    method public int getCompact();
+    method public java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> getDefaultSizeClasses();
+    method public int getExpanded();
+    method public int getMedium();
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> AllSizeClasses;
+    property public final int Compact;
+    property public final java.util.Set<androidx.compose.material3.windowsizeclass.WindowWidthSizeClass> DefaultSizeClasses;
+    property public final int Expanded;
+    property public final int Medium;
+  }
+
+}
+
diff --git a/compose/material3/material3/api/1.2.0-beta01.txt b/compose/material3/material3/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..7ca2ade
--- /dev/null
+++ b/compose/material3/material3/api/1.2.0-beta01.txt
@@ -0,0 +1,2073 @@
+// Signature format: 4.0
+package androidx.compose.material3 {
+
+  public final class AlertDialogDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getIconContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public long getTextContentColor();
+    method @androidx.compose.runtime.Composable public long getTitleContentColor();
+    method public float getTonalElevation();
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long iconContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final long textContentColor;
+    property @androidx.compose.runtime.Composable public final long titleContentColor;
+    field public static final androidx.compose.material3.AlertDialogDefaults INSTANCE;
+  }
+
+  public final class AndroidAlertDialog_androidKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long iconContentColor, optional long titleContentColor, optional long textContentColor, optional float tonalElevation, optional androidx.compose.ui.window.DialogProperties properties);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BasicAlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class AndroidMenu_androidKt {
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class AppBarKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.BottomAppBarScrollBehavior? scrollBehavior, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.BottomAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.BottomAppBarState BottomAppBarState(float initialHeightOffsetLimit, float initialHeightOffset, float initialContentOffset);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void CenterAlignedTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void LargeTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MediumTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SmallTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.BottomAppBarState rememberBottomAppBarState(optional float initialHeightOffsetLimit, optional float initialHeightOffset, optional float initialContentOffset);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TopAppBarState rememberTopAppBarState(optional float initialHeightOffsetLimit, optional float initialHeightOffset, optional float initialContentOffset);
+  }
+
+  public final class AssistChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke assistChipBorder(boolean enabled, optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder assistChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors assistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation assistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedAssistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedAssistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.AssistChipDefaults INSTANCE;
+  }
+
+  public final class BadgeDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    field public static final androidx.compose.material3.BadgeDefaults INSTANCE;
+  }
+
+  public final class BadgeKt {
+    method @androidx.compose.runtime.Composable public static void Badge(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? content);
+    method @androidx.compose.runtime.Composable public static void BadgedBox(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> badge, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface BasicTooltipState {
+    method public void dismiss();
+    method public boolean isPersistent();
+    method public boolean isVisible();
+    method public void onDispose();
+    method public suspend Object? show(optional androidx.compose.foundation.MutatePriority mutatePriority, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract boolean isPersistent;
+    property public abstract boolean isVisible;
+  }
+
+  public final class BottomAppBarDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.BottomAppBarScrollBehavior exitAlwaysScrollBehavior(optional androidx.compose.material3.BottomAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @androidx.compose.runtime.Composable public long getBottomAppBarFabColor();
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getContainerElevation();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float ContainerElevation;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property @androidx.compose.runtime.Composable public final long bottomAppBarFabColor;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface BottomAppBarScrollBehavior {
+    method public androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? getFlingAnimationSpec();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float>? getSnapAnimationSpec();
+    method public androidx.compose.material3.BottomAppBarState getState();
+    method public boolean isPinned();
+    property public abstract androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec;
+    property public abstract boolean isPinned;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec;
+    property public abstract androidx.compose.material3.BottomAppBarState state;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface BottomAppBarState {
+    method public float getCollapsedFraction();
+    method public float getContentOffset();
+    method public float getHeightOffset();
+    method public float getHeightOffsetLimit();
+    method public void setContentOffset(float);
+    method public void setHeightOffset(float);
+    method public void setHeightOffsetLimit(float);
+    property public abstract float collapsedFraction;
+    property public abstract float contentOffset;
+    property public abstract float heightOffset;
+    property public abstract float heightOffsetLimit;
+    field public static final androidx.compose.material3.BottomAppBarState.Companion Companion;
+  }
+
+  public static final class BottomAppBarState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,?> Saver;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
+    method @androidx.compose.runtime.Composable public void DragHandle(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional androidx.compose.ui.graphics.Shape shape, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExpandedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getHiddenShape();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method public float getSheetMaxWidth();
+    method public float getSheetPeekHeight();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape ExpandedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape HiddenShape;
+    property @androidx.compose.runtime.Composable public final long ScrimColor;
+    property public final float SheetMaxWidth;
+    property public final float SheetPeekHeight;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomSheetDefaults INSTANCE;
+  }
+
+  public final class BottomSheetScaffoldKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BottomSheetScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.BottomSheetScaffoldState scaffoldState, optional float sheetPeekHeight, optional float sheetMaxWidth, optional androidx.compose.ui.graphics.Shape sheetShape, optional long sheetContainerColor, optional long sheetContentColor, optional float sheetTonalElevation, optional float sheetShadowElevation, optional kotlin.jvm.functions.Function0<kotlin.Unit>? sheetDragHandle, optional boolean sheetSwipeEnabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarHostState,kotlin.Unit> snackbarHost, optional long containerColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material3.SheetState bottomSheetState, optional androidx.compose.material3.SnackbarHostState snackbarHostState);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SheetState rememberStandardBottomSheetState(optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetScaffoldState {
+    ctor public BottomSheetScaffoldState(androidx.compose.material3.SheetState bottomSheetState, androidx.compose.material3.SnackbarHostState snackbarHostState);
+    method public androidx.compose.material3.SheetState getBottomSheetState();
+    method public androidx.compose.material3.SnackbarHostState getSnackbarHostState();
+    property public final androidx.compose.material3.SheetState bottomSheetState;
+    property public final androidx.compose.material3.SnackbarHostState snackbarHostState;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ButtonColors {
+    ctor public ButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors buttonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation buttonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors elevatedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation elevatedButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors filledTonalButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation filledTonalButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method public androidx.compose.foundation.layout.PaddingValues getButtonWithIconContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledTonalShape();
+    method public float getIconSize();
+    method public float getIconSpacing();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedButtonBorder();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonWithIconContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getTextShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors outlinedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors textButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ButtonWithIconContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float IconSize;
+    property public final float IconSpacing;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonWithIconContentPadding;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledTonalShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedButtonBorder;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape textShape;
+    field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class ButtonElevation {
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public final class CalendarModelKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static String formatWithSkeleton(long utcTimeMillis, String skeleton, java.util.Locale locale, java.util.Map<java.lang.String,java.lang.Object> cache);
+  }
+
+  public final class CalendarModel_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static String formatWithSkeleton(long utcTimeMillis, String skeleton, java.util.Locale locale, java.util.Map<java.lang.String,java.lang.Object> cache);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardColors {
+    ctor public CardColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class CardDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation cardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors elevatedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation elevatedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors outlinedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation outlinedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.CardDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardElevation {
+  }
+
+  public final class CardKt {
+    method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CheckboxColors {
+    ctor public CheckboxColors(long checkedCheckmarkColor, long uncheckedCheckmarkColor, long checkedBoxColor, long uncheckedBoxColor, long disabledCheckedBoxColor, long disabledUncheckedBoxColor, long disabledIndeterminateBoxColor, long checkedBorderColor, long uncheckedBorderColor, long disabledBorderColor, long disabledUncheckedBorderColor, long disabledIndeterminateBorderColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedBoxColor();
+    method public long getCheckedCheckmarkColor();
+    method public long getDisabledBorderColor();
+    method public long getDisabledCheckedBoxColor();
+    method public long getDisabledIndeterminateBorderColor();
+    method public long getDisabledIndeterminateBoxColor();
+    method public long getDisabledUncheckedBorderColor();
+    method public long getDisabledUncheckedBoxColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedBoxColor();
+    method public long getUncheckedCheckmarkColor();
+    property public final long checkedBorderColor;
+    property public final long checkedBoxColor;
+    property public final long checkedCheckmarkColor;
+    property public final long disabledBorderColor;
+    property public final long disabledCheckedBoxColor;
+    property public final long disabledIndeterminateBorderColor;
+    property public final long disabledIndeterminateBoxColor;
+    property public final long disabledUncheckedBorderColor;
+    property public final long disabledUncheckedBoxColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedBoxColor;
+    property public final long uncheckedCheckmarkColor;
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CheckboxColors colors(optional long checkedColor, optional long uncheckedColor, optional long checkmarkColor, optional long disabledCheckedColor, optional long disabledUncheckedColor, optional long disabledIndeterminateColor);
+    field public static final androidx.compose.material3.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CheckboxKt {
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @Deprecated @androidx.compose.runtime.Immutable public final class ChipBorder {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipColors {
+    ctor public ChipColors(long containerColor, long labelColor, long leadingIconContentColor, long trailingIconContentColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconContentColor, long disabledTrailingIconContentColor);
+    method public long getContainerColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconContentColor();
+    method public long getDisabledTrailingIconContentColor();
+    method public long getLabelColor();
+    method public long getLeadingIconContentColor();
+    method public long getTrailingIconContentColor();
+    property public final long containerColor;
+    property public final long disabledContainerColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconContentColor;
+    property public final long disabledTrailingIconContentColor;
+    property public final long labelColor;
+    property public final long leadingIconContentColor;
+    property public final long trailingIconContentColor;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipElevation {
+    ctor public ChipElevation(float elevation, float pressedElevation, float focusedElevation, float hoveredElevation, float draggedElevation, float disabledElevation);
+    method public float getDisabledElevation();
+    method public float getDraggedElevation();
+    method public float getElevation();
+    method public float getFocusedElevation();
+    method public float getHoveredElevation();
+    method public float getPressedElevation();
+    property public final float disabledElevation;
+    property public final float draggedElevation;
+    property public final float elevation;
+    property public final float focusedElevation;
+    property public final float hoveredElevation;
+    property public final float pressedElevation;
+  }
+
+  public final class ChipKt {
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ColorScheme {
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim);
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim, long surfaceBright, long surfaceDim, long surfaceContainer, long surfaceContainerHigh, long surfaceContainerHighest, long surfaceContainerLow, long surfaceContainerLowest);
+    method @Deprecated public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim, optional long surfaceBright, optional long surfaceDim, optional long surfaceContainer, optional long surfaceContainerHigh, optional long surfaceContainerHighest, optional long surfaceContainerLow, optional long surfaceContainerLowest);
+    method public long getBackground();
+    method public long getError();
+    method public long getErrorContainer();
+    method public long getInverseOnSurface();
+    method public long getInversePrimary();
+    method public long getInverseSurface();
+    method public long getOnBackground();
+    method public long getOnError();
+    method public long getOnErrorContainer();
+    method public long getOnPrimary();
+    method public long getOnPrimaryContainer();
+    method public long getOnSecondary();
+    method public long getOnSecondaryContainer();
+    method public long getOnSurface();
+    method public long getOnSurfaceVariant();
+    method public long getOnTertiary();
+    method public long getOnTertiaryContainer();
+    method public long getOutline();
+    method public long getOutlineVariant();
+    method public long getPrimary();
+    method public long getPrimaryContainer();
+    method public long getScrim();
+    method public long getSecondary();
+    method public long getSecondaryContainer();
+    method public long getSurface();
+    method public long getSurfaceBright();
+    method public long getSurfaceContainer();
+    method public long getSurfaceContainerHigh();
+    method public long getSurfaceContainerHighest();
+    method public long getSurfaceContainerLow();
+    method public long getSurfaceContainerLowest();
+    method public long getSurfaceDim();
+    method public long getSurfaceTint();
+    method public long getSurfaceVariant();
+    method public long getTertiary();
+    method public long getTertiaryContainer();
+    property public final long background;
+    property public final long error;
+    property public final long errorContainer;
+    property public final long inverseOnSurface;
+    property public final long inversePrimary;
+    property public final long inverseSurface;
+    property public final long onBackground;
+    property public final long onError;
+    property public final long onErrorContainer;
+    property public final long onPrimary;
+    property public final long onPrimaryContainer;
+    property public final long onSecondary;
+    property public final long onSecondaryContainer;
+    property public final long onSurface;
+    property public final long onSurfaceVariant;
+    property public final long onTertiary;
+    property public final long onTertiaryContainer;
+    property public final long outline;
+    property public final long outlineVariant;
+    property public final long primary;
+    property public final long primaryContainer;
+    property public final long scrim;
+    property public final long secondary;
+    property public final long secondaryContainer;
+    property public final long surface;
+    property public final long surfaceBright;
+    property public final long surfaceContainer;
+    property public final long surfaceContainerHigh;
+    property public final long surfaceContainerHighest;
+    property public final long surfaceContainerLow;
+    property public final long surfaceContainerLowest;
+    property public final long surfaceDim;
+    property public final long surfaceTint;
+    property public final long surfaceVariant;
+    property public final long tertiary;
+    property public final long tertiaryContainer;
+  }
+
+  public final class ColorSchemeKt {
+    method @androidx.compose.runtime.Stable public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
+    method @Deprecated public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim, optional long surfaceBright, optional long surfaceContainer, optional long surfaceContainerHigh, optional long surfaceContainerHighest, optional long surfaceContainerLow, optional long surfaceContainerLowest, optional long surfaceDim);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalTonalElevationEnabled();
+    method @Deprecated public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim, optional long surfaceBright, optional long surfaceContainer, optional long surfaceContainerHigh, optional long surfaceContainerHighest, optional long surfaceContainerLow, optional long surfaceContainerLowest, optional long surfaceDim);
+    method @androidx.compose.runtime.Stable public static long surfaceColorAtElevation(androidx.compose.material3.ColorScheme, float elevation);
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalTonalElevationEnabled;
+  }
+
+  public final class ContentColorKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> getLocalContentColor();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> LocalContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class DatePickerColors {
+    ctor public DatePickerColors(long containerColor, long titleContentColor, long headlineContentColor, long weekdayContentColor, long subheadContentColor, long navigationContentColor, long yearContentColor, long disabledYearContentColor, long currentYearContentColor, long selectedYearContentColor, long disabledSelectedYearContentColor, long selectedYearContainerColor, long disabledSelectedYearContainerColor, long dayContentColor, long disabledDayContentColor, long selectedDayContentColor, long disabledSelectedDayContentColor, long selectedDayContainerColor, long disabledSelectedDayContainerColor, long todayContentColor, long todayDateBorderColor, long dayInSelectionRangeContainerColor, long dayInSelectionRangeContentColor, long dividerColor, androidx.compose.material3.TextFieldColors dateTextFieldColors);
+    method public long getContainerColor();
+    method public long getCurrentYearContentColor();
+    method public androidx.compose.material3.TextFieldColors getDateTextFieldColors();
+    method public long getDayContentColor();
+    method public long getDayInSelectionRangeContainerColor();
+    method public long getDayInSelectionRangeContentColor();
+    method public long getDisabledDayContentColor();
+    method public long getDisabledSelectedDayContainerColor();
+    method public long getDisabledSelectedDayContentColor();
+    method public long getDisabledSelectedYearContainerColor();
+    method public long getDisabledSelectedYearContentColor();
+    method public long getDisabledYearContentColor();
+    method public long getDividerColor();
+    method public long getHeadlineContentColor();
+    method public long getNavigationContentColor();
+    method public long getSelectedDayContainerColor();
+    method public long getSelectedDayContentColor();
+    method public long getSelectedYearContainerColor();
+    method public long getSelectedYearContentColor();
+    method public long getSubheadContentColor();
+    method public long getTitleContentColor();
+    method public long getTodayContentColor();
+    method public long getTodayDateBorderColor();
+    method public long getWeekdayContentColor();
+    method public long getYearContentColor();
+    property public final long containerColor;
+    property public final long currentYearContentColor;
+    property public final androidx.compose.material3.TextFieldColors dateTextFieldColors;
+    property public final long dayContentColor;
+    property public final long dayInSelectionRangeContainerColor;
+    property public final long dayInSelectionRangeContentColor;
+    property public final long disabledDayContentColor;
+    property public final long disabledSelectedDayContainerColor;
+    property public final long disabledSelectedDayContentColor;
+    property public final long disabledSelectedYearContainerColor;
+    property public final long disabledSelectedYearContentColor;
+    property public final long disabledYearContentColor;
+    property public final long dividerColor;
+    property public final long headlineContentColor;
+    property public final long navigationContentColor;
+    property public final long selectedDayContainerColor;
+    property public final long selectedDayContentColor;
+    property public final long selectedYearContainerColor;
+    property public final long selectedYearContentColor;
+    property public final long subheadContentColor;
+    property public final long titleContentColor;
+    property public final long todayContentColor;
+    property public final long todayDateBorderColor;
+    property public final long weekdayContentColor;
+    property public final long yearContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DatePickerDefaults {
+    method @androidx.compose.runtime.Composable public void DatePickerHeadline(Long? selectedDateMillis, int displayMode, androidx.compose.material3.DatePickerFormatter dateFormatter, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public void DatePickerTitle(int displayMode, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.DatePickerColors colors(optional long containerColor, optional long titleContentColor, optional long headlineContentColor, optional long weekdayContentColor, optional long subheadContentColor, optional long navigationContentColor, optional long yearContentColor, optional long disabledYearContentColor, optional long currentYearContentColor, optional long selectedYearContentColor, optional long disabledSelectedYearContentColor, optional long selectedYearContainerColor, optional long disabledSelectedYearContainerColor, optional long dayContentColor, optional long disabledDayContentColor, optional long selectedDayContentColor, optional long disabledSelectedDayContentColor, optional long selectedDayContainerColor, optional long disabledSelectedDayContainerColor, optional long todayContentColor, optional long todayDateBorderColor, optional long dayInSelectionRangeContentColor, optional long dayInSelectionRangeContainerColor, optional long dividerColor, optional androidx.compose.material3.TextFieldColors dateTextFieldColors);
+    method public androidx.compose.material3.DatePickerFormatter dateFormatter(optional String yearSelectionSkeleton, optional String selectedDateSkeleton, optional String selectedDateDescriptionSkeleton);
+    method public androidx.compose.material3.SelectableDates getAllDates();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getTonalElevation();
+    method public kotlin.ranges.IntRange getYearRange();
+    property public final androidx.compose.material3.SelectableDates AllDates;
+    property public final float TonalElevation;
+    property public final kotlin.ranges.IntRange YearRange;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.DatePickerDefaults INSTANCE;
+    field public static final String YearAbbrMonthDaySkeleton = "yMMMd";
+    field public static final String YearMonthSkeleton = "yMMMM";
+    field public static final String YearMonthWeekdayDaySkeleton = "yMMMMEEEEd";
+  }
+
+  public final class DatePickerDialog_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DatePickerDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional androidx.compose.ui.graphics.Shape shape, optional float tonalElevation, optional androidx.compose.material3.DatePickerColors colors, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface DatePickerFormatter {
+    method public String? formatDate(Long? dateMillis, java.util.Locale locale, optional boolean forContentDescription);
+    method public String? formatMonthYear(Long? monthMillis, java.util.Locale locale);
+  }
+
+  public final class DatePickerKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DatePicker(androidx.compose.material3.DatePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.DatePickerState DatePickerState(java.util.Locale locale, optional Long? initialSelectedDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DatePickerState rememberDatePickerState(optional Long? initialSelectedDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface DatePickerState {
+    method public int getDisplayMode();
+    method public long getDisplayedMonthMillis();
+    method public androidx.compose.material3.SelectableDates getSelectableDates();
+    method public Long? getSelectedDateMillis();
+    method public kotlin.ranges.IntRange getYearRange();
+    method public void setDisplayMode(int);
+    method public void setDisplayedMonthMillis(long);
+    method public void setSelectedDateMillis(Long?);
+    property public abstract int displayMode;
+    property public abstract long displayedMonthMillis;
+    property public abstract androidx.compose.material3.SelectableDates selectableDates;
+    property public abstract Long? selectedDateMillis;
+    property public abstract kotlin.ranges.IntRange yearRange;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DateRangePickerDefaults {
+    method @androidx.compose.runtime.Composable public void DateRangePickerHeadline(Long? selectedStartDateMillis, Long? selectedEndDateMillis, int displayMode, androidx.compose.material3.DatePickerFormatter dateFormatter, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public void DateRangePickerTitle(int displayMode, optional androidx.compose.ui.Modifier modifier);
+    field public static final androidx.compose.material3.DateRangePickerDefaults INSTANCE;
+  }
+
+  public final class DateRangePickerKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DateRangePicker(androidx.compose.material3.DateRangePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.DateRangePickerState DateRangePickerState(java.util.Locale locale, optional Long? initialSelectedStartDateMillis, optional Long? initialSelectedEndDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DateRangePickerState rememberDateRangePickerState(optional Long? initialSelectedStartDateMillis, optional Long? initialSelectedEndDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface DateRangePickerState {
+    method public int getDisplayMode();
+    method public long getDisplayedMonthMillis();
+    method public androidx.compose.material3.SelectableDates getSelectableDates();
+    method public Long? getSelectedEndDateMillis();
+    method public Long? getSelectedStartDateMillis();
+    method public kotlin.ranges.IntRange getYearRange();
+    method public void setDisplayMode(int);
+    method public void setDisplayedMonthMillis(long);
+    method public void setSelection(Long? startDateMillis, Long? endDateMillis);
+    property public abstract int displayMode;
+    property public abstract long displayedMonthMillis;
+    property public abstract androidx.compose.material3.SelectableDates selectableDates;
+    property public abstract Long? selectedEndDateMillis;
+    property public abstract Long? selectedStartDateMillis;
+    property public abstract kotlin.ranges.IntRange yearRange;
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
+    method @Deprecated public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissDirection[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection EndToStart;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection StartToEnd;
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
+    method @Deprecated public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissValue[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue Default;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToEnd;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToStart;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
+    field public static final androidx.compose.material3.DisplayMode.Companion Companion;
+  }
+
+  public static final class DisplayMode.Companion {
+    method public int getInput();
+    method public int getPicker();
+    property public final int Input;
+    property public final int Picker;
+  }
+
+  public final class DividerDefaults {
+    method @androidx.compose.runtime.Composable public long getColor();
+    method public float getThickness();
+    property public final float Thickness;
+    property @androidx.compose.runtime.Composable public final long color;
+    field public static final androidx.compose.material3.DividerDefaults INSTANCE;
+  }
+
+  public final class DividerKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void Divider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+    method @androidx.compose.runtime.Composable public static void HorizontalDivider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+    method @androidx.compose.runtime.Composable public static void VerticalDivider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+  }
+
+  public final class DrawerDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getDismissibleDrawerElevation();
+    method public float getMaximumDrawerWidth();
+    method public float getModalDrawerElevation();
+    method public float getPermanentDrawerElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float DismissibleDrawerElevation;
+    property public final float MaximumDrawerWidth;
+    property public final float ModalDrawerElevation;
+    property public final float PermanentDrawerElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.DrawerDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class DrawerState {
+    ctor public DrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+    method @Deprecated public suspend Object? animateTo(androidx.compose.material3.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float getCurrentOffset();
+    method public androidx.compose.material3.DrawerValue getCurrentValue();
+    method @Deprecated public androidx.compose.runtime.State<java.lang.Float> getOffset();
+    method public androidx.compose.material3.DrawerValue getTargetValue();
+    method public boolean isAnimationRunning();
+    method public boolean isClosed();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.DrawerValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final float currentOffset;
+    property public final androidx.compose.material3.DrawerValue currentValue;
+    property public final boolean isAnimationRunning;
+    property public final boolean isClosed;
+    property public final boolean isOpen;
+    property @Deprecated public final androidx.compose.runtime.State<java.lang.Float> offset;
+    property public final androidx.compose.material3.DrawerValue targetValue;
+    field public static final androidx.compose.material3.DrawerState.Companion Companion;
+  }
+
+  public static final class DrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DrawerState,androidx.compose.material3.DrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DrawerValue {
+    method public static androidx.compose.material3.DrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DrawerValue[] values();
+    enum_constant public static final androidx.compose.material3.DrawerValue Closed;
+    enum_constant public static final androidx.compose.material3.DrawerValue Open;
+  }
+
+  public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3Api {
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface ExposedDropdownMenuBoxScope {
+    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
+    method public androidx.compose.ui.Modifier menuAnchor(androidx.compose.ui.Modifier);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class ExposedDropdownMenuDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded);
+    method public androidx.compose.foundation.layout.PaddingValues getItemContentPadding();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ItemContentPadding;
+    field public static final androidx.compose.material3.ExposedDropdownMenuDefaults INSTANCE;
+  }
+
+  public final class ExposedDropdownMenu_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FabPosition {
+    field public static final androidx.compose.material3.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    method public int getEndOverlay();
+    method public int getStart();
+    property public final int Center;
+    property public final int End;
+    property public final int EndOverlay;
+    property public final int Start;
+  }
+
+  public final class FilterChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors elevatedFilterChipColors(optional long containerColor, optional long labelColor, optional long iconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation elevatedFilterChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke filterChipBorder(boolean enabled, boolean selected, optional long borderColor, optional long selectedBorderColor, optional long disabledBorderColor, optional long disabledSelectedBorderColor, optional float borderWidth, optional float selectedBorderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors filterChipColors(optional long containerColor, optional long labelColor, optional long iconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation filterChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.FilterChipDefaults INSTANCE;
+  }
+
+  public final class FloatingActionButtonDefaults {
+    method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
+    method public float getLargeIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getLargeShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getSmallShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation loweredElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    property public final float LargeIconSize;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape extendedFabShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape largeShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape smallShape;
+    field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
+  }
+
+  public final class FloatingActionButtonKt {
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconButtonColors {
+    ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class IconButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledTonalIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledTonalIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors iconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors iconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedIconButtonBorder(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors outlinedIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke? outlinedIconToggleButtonBorder(boolean enabled, boolean checked);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors outlinedIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.IconButtonDefaults INSTANCE;
+  }
+
+  public final class IconButtonKt {
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class IconKt {
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+    ctor public IconToggleButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor, long checkedContainerColor, long checkedContentColor);
+    method public long getCheckedContainerColor();
+    method public long getCheckedContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long checkedContainerColor;
+    property public final long checkedContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class InputChipDefaults {
+    method public float getAvatarSize();
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke inputChipBorder(boolean enabled, boolean selected, optional long borderColor, optional long selectedBorderColor, optional long disabledBorderColor, optional long disabledSelectedBorderColor, optional float borderWidth, optional float selectedBorderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors inputChipColors(optional long containerColor, optional long labelColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation inputChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float AvatarSize;
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.InputChipDefaults INSTANCE;
+  }
+
+  public final class InteractiveComponentSizeKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
+    property @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
+    property @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+  }
+
+  public final class LabelKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Label(kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean isPersistent, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ListItemColors {
+    ctor public ListItemColors(long containerColor, long headlineColor, long leadingIconColor, long overlineColor, long supportingTextColor, long trailingIconColor, long disabledHeadlineColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getContainerColor();
+    method public long getDisabledHeadlineColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getHeadlineColor();
+    method public long getLeadingIconColor();
+    method public long getOverlineColor();
+    method public long getSupportingTextColor();
+    method public long getTrailingIconColor();
+    property public final long containerColor;
+    property public final long disabledHeadlineColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTrailingIconColor;
+    property public final long headlineColor;
+    property public final long leadingIconColor;
+    property public final long overlineColor;
+    property public final long supportingTextColor;
+    property public final long trailingIconColor;
+  }
+
+  public final class ListItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ListItemColors colors(optional long containerColor, optional long headlineColor, optional long leadingIconColor, optional long overlineColor, optional long supportingColor, optional long trailingIconColor, optional long disabledHeadlineColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContainerColor();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContentColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long containerColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long contentColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.ListItemDefaults INSTANCE;
+  }
+
+  public final class ListItemKt {
+    method @androidx.compose.runtime.Composable public static void ListItem(kotlin.jvm.functions.Function0<kotlin.Unit> headlineContent, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingContent, optional androidx.compose.material3.ListItemColors colors, optional float tonalElevation, optional float shadowElevation);
+  }
+
+  public final class MaterialTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
+    field public static final androidx.compose.material3.MaterialTheme INSTANCE;
+  }
+
+  public final class MaterialThemeKt {
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Shapes shapes, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class MenuDefaults {
+    method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    field public static final androidx.compose.material3.MenuDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class MenuItemColors {
+    ctor public MenuItemColors(long textColor, long leadingIconColor, long trailingIconColor, long disabledTextColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getLeadingIconColor();
+    method public long getTextColor();
+    method public long getTrailingIconColor();
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long leadingIconColor;
+    property public final long textColor;
+    property public final long trailingIconColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class ModalBottomSheetDefaults {
+    method public androidx.compose.material3.ModalBottomSheetProperties properties(optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean isFocusable, optional boolean shouldDismissOnBackPress);
+    field public static final androidx.compose.material3.ModalBottomSheetDefaults INSTANCE;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class ModalBottomSheetProperties {
+    ctor public ModalBottomSheetProperties(androidx.compose.ui.window.SecureFlagPolicy securePolicy, boolean isFocusable, boolean shouldDismissOnBackPress);
+    method public androidx.compose.ui.window.SecureFlagPolicy getSecurePolicy();
+    method public boolean getShouldDismissOnBackPress();
+    method public boolean isFocusable();
+    property public final boolean isFocusable;
+    property public final androidx.compose.ui.window.SecureFlagPolicy securePolicy;
+    property public final boolean shouldDismissOnBackPress;
+  }
+
+  public final class ModalBottomSheet_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ModalBottomSheet(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SheetState sheetState, optional float sheetMaxWidth, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional float tonalElevation, optional long scrimColor, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dragHandle, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.ModalBottomSheetProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SheetState rememberModalBottomSheetState(optional boolean skipPartiallyExpanded, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface MultiChoiceSegmentedButtonRowScope extends androidx.compose.foundation.layout.RowScope {
+  }
+
+  public final class NavigationBarDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+    ctor public NavigationBarItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
+  }
+
+  public final class NavigationBarItemDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    field public static final androidx.compose.material3.NavigationBarItemDefaults INSTANCE;
+  }
+
+  public final class NavigationBarKt {
+    method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> badgeColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
+  }
+
+  public final class NavigationDrawerItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationDrawerItemColors colors(optional long selectedContainerColor, optional long unselectedContainerColor, optional long selectedIconColor, optional long unselectedIconColor, optional long selectedTextColor, optional long unselectedTextColor, optional long selectedBadgeColor, optional long unselectedBadgeColor);
+    method public androidx.compose.foundation.layout.PaddingValues getItemPadding();
+    property public final androidx.compose.foundation.layout.PaddingValues ItemPadding;
+    field public static final androidx.compose.material3.NavigationDrawerItemDefaults INSTANCE;
+  }
+
+  public final class NavigationDrawerKt {
+    method @androidx.compose.runtime.Composable public static void DismissibleDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public final class NavigationRailDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+    ctor public NavigationRailItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
+  }
+
+  public final class NavigationRailItemDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    field public static final androidx.compose.material3.NavigationRailItemDefaults INSTANCE;
+  }
+
+  public final class NavigationRailKt {
+    method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class OutlinedTextFieldDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void ContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void DecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors colors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method public androidx.compose.foundation.layout.PaddingValues contentPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method public float getFocusedBorderThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getUnfocusedBorderThickness();
+    property public final float FocusedBorderThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final float UnfocusedBorderThickness;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.OutlinedTextFieldDefaults INSTANCE;
+  }
+
+  public final class OutlinedTextFieldKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface PlainTooltipState extends androidx.compose.material3.BasicTooltipState {
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method @androidx.compose.runtime.Composable public long getCircularColor();
+    method public int getCircularDeterminateStrokeCap();
+    method public int getCircularIndeterminateStrokeCap();
+    method public float getCircularStrokeWidth();
+    method @androidx.compose.runtime.Composable public long getCircularTrackColor();
+    method @androidx.compose.runtime.Composable public long getLinearColor();
+    method public int getLinearStrokeCap();
+    method @androidx.compose.runtime.Composable public long getLinearTrackColor();
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getProgressAnimationSpec();
+    property public final int CircularDeterminateStrokeCap;
+    property public final int CircularIndeterminateStrokeCap;
+    property public final float CircularStrokeWidth;
+    property public final int LinearStrokeCap;
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> ProgressAnimationSpec;
+    property @androidx.compose.runtime.Composable public final long circularColor;
+    property @androidx.compose.runtime.Composable public final long circularTrackColor;
+    property @androidx.compose.runtime.Composable public final long linearColor;
+    property @androidx.compose.runtime.Composable public final long linearTrackColor;
+    field public static final androidx.compose.material3.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class ProgressIndicatorKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(kotlin.jvm.functions.Function0<java.lang.Float> progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(kotlin.jvm.functions.Function0<java.lang.Float> progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+  }
+
+  @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+    ctor public RadioButtonColors(long selectedColor, long unselectedColor, long disabledSelectedColor, long disabledUnselectedColor);
+    method public long getDisabledSelectedColor();
+    method public long getDisabledUnselectedColor();
+    method public long getSelectedColor();
+    method public long getUnselectedColor();
+    property public final long disabledSelectedColor;
+    property public final long disabledUnselectedColor;
+    property public final long selectedColor;
+    property public final long unselectedColor;
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RadioButtonColors colors(optional long selectedColor, optional long unselectedColor, optional long disabledSelectedColor, optional long disabledUnselectedColor);
+    field public static final androidx.compose.material3.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RangeSliderState {
+    ctor public RangeSliderState(optional float activeRangeStart, optional float activeRangeEnd, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
+    method public float getActiveRangeEnd();
+    method public float getActiveRangeStart();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnValueChangeFinished();
+    method public int getSteps();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getValueRange();
+    method public void setActiveRangeEnd(float);
+    method public void setActiveRangeStart(float);
+    property public final float activeRangeEnd;
+    property public final float activeRangeStart;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished;
+    property public final int steps;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @androidx.compose.runtime.Stable public final class RichTooltipColors {
+    ctor public RichTooltipColors(long containerColor, long contentColor, long titleContentColor, long actionContentColor);
+    method public long getActionContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getTitleContentColor();
+    property public final long actionContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long titleContentColor;
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface RichTooltipState extends androidx.compose.material3.BasicTooltipState {
+  }
+
+  public final class ScaffoldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
+    field public static final androidx.compose.material3.ScaffoldDefaults INSTANCE;
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, optional androidx.compose.foundation.layout.WindowInsets contentWindowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static boolean getScaffoldSubcomposeInMeasureFix();
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static void setScaffoldSubcomposeInMeasureFix(boolean);
+    property @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final boolean ScaffoldSubcomposeInMeasureFix;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SearchBarColors {
+    method public long getContainerColor();
+    method public long getDividerColor();
+    method public androidx.compose.material3.TextFieldColors getInputFieldColors();
+    property public final long containerColor;
+    property public final long dividerColor;
+    property public final androidx.compose.material3.TextFieldColors inputFieldColors;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SearchBarDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SearchBarColors colors(optional long containerColor, optional long dividerColor, optional androidx.compose.material3.TextFieldColors inputFieldColors);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getDockedShape();
+    method @Deprecated public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFullScreenShape();
+    method public float getInputFieldHeight();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getInputFieldShape();
+    method public float getShadowElevation();
+    method public float getTonalElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors inputFieldColors(optional long textColor, optional long disabledTextColor, optional long cursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors inputFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long cursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor);
+    property @Deprecated public final float Elevation;
+    property public final float InputFieldHeight;
+    property public final float ShadowElevation;
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape dockedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape fullScreenShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape inputFieldShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.SearchBarDefaults INSTANCE;
+  }
+
+  public final class SearchBar_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SegmentedButtonColors {
+    ctor public SegmentedButtonColors(long activeContainerColor, long activeContentColor, long activeBorderColor, long inactiveContainerColor, long inactiveContentColor, long inactiveBorderColor, long disabledActiveContainerColor, long disabledActiveContentColor, long disabledActiveBorderColor, long disabledInactiveContainerColor, long disabledInactiveContentColor, long disabledInactiveBorderColor);
+    method public long getActiveBorderColor();
+    method public long getActiveContainerColor();
+    method public long getActiveContentColor();
+    method public long getDisabledActiveBorderColor();
+    method public long getDisabledActiveContainerColor();
+    method public long getDisabledActiveContentColor();
+    method public long getDisabledInactiveBorderColor();
+    method public long getDisabledInactiveContainerColor();
+    method public long getDisabledInactiveContentColor();
+    method public long getInactiveBorderColor();
+    method public long getInactiveContainerColor();
+    method public long getInactiveContentColor();
+    property public final long activeBorderColor;
+    property public final long activeContainerColor;
+    property public final long activeContentColor;
+    property public final long disabledActiveBorderColor;
+    property public final long disabledActiveContainerColor;
+    property public final long disabledActiveContentColor;
+    property public final long disabledInactiveBorderColor;
+    property public final long disabledInactiveContainerColor;
+    property public final long disabledInactiveContentColor;
+    property public final long inactiveBorderColor;
+    property public final long inactiveContainerColor;
+    property public final long inactiveContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SegmentedButtonDefaults {
+    method @androidx.compose.runtime.Composable public void ActiveIcon();
+    method @androidx.compose.runtime.Composable public void Icon(boolean active, optional kotlin.jvm.functions.Function0<kotlin.Unit> activeContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? inactiveContent);
+    method public androidx.compose.foundation.BorderStroke borderStroke(long color, optional float width);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SegmentedButtonColors colors(optional long activeContainerColor, optional long activeContentColor, optional long activeBorderColor, optional long inactiveContainerColor, optional long inactiveContentColor, optional long inactiveBorderColor, optional long disabledActiveContainerColor, optional long disabledActiveContentColor, optional long disabledActiveBorderColor, optional long disabledInactiveContainerColor, optional long disabledInactiveContentColor, optional long disabledInactiveBorderColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.foundation.shape.CornerBasedShape getBaseShape();
+    method public float getBorderWidth();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape itemShape(int index, int count, optional androidx.compose.foundation.shape.CornerBasedShape baseShape);
+    property public final float BorderWidth;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.foundation.shape.CornerBasedShape baseShape;
+    field public static final androidx.compose.material3.SegmentedButtonDefaults INSTANCE;
+  }
+
+  public final class SegmentedButtonKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MultiChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.MultiChoiceSegmentedButtonRowScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.MultiChoiceSegmentedButtonRowScope, boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.SingleChoiceSegmentedButtonRowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SingleChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SingleChoiceSegmentedButtonRowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class SelectableChipColors {
+    ctor public SelectableChipColors(long containerColor, long labelColor, long leadingIconColor, long trailingIconColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconColor, long disabledTrailingIconColor, long selectedContainerColor, long disabledSelectedContainerColor, long selectedLabelColor, long selectedLeadingIconColor, long selectedTrailingIconColor);
+  }
+
+  @androidx.compose.runtime.Immutable public final class SelectableChipElevation {
+    ctor public SelectableChipElevation(float elevation, float pressedElevation, float focusedElevation, float hoveredElevation, float draggedElevation, float disabledElevation);
+    method public float getDisabledElevation();
+    method public float getDraggedElevation();
+    method public float getElevation();
+    method public float getFocusedElevation();
+    method public float getHoveredElevation();
+    method public float getPressedElevation();
+    property public final float disabledElevation;
+    property public final float draggedElevation;
+    property public final float elevation;
+    property public final float focusedElevation;
+    property public final float hoveredElevation;
+    property public final float pressedElevation;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableDates {
+    method public default boolean isSelectableDate(long utcTimeMillis);
+    method public default boolean isSelectableYear(int year);
+  }
+
+  public final class ShapeDefaults {
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Small;
+    field public static final androidx.compose.material3.ShapeDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shapes {
+    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape small;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SheetState {
+    ctor @Deprecated public SheetState(boolean skipPartiallyExpanded, optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+    ctor @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public SheetState(boolean skipPartiallyExpanded, androidx.compose.ui.unit.Density density, optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SheetValue getCurrentValue();
+    method public boolean getHasExpandedState();
+    method public boolean getHasPartiallyExpandedState();
+    method public androidx.compose.material3.SheetValue getTargetValue();
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean isVisible();
+    method public suspend Object? partialExpand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float requireOffset();
+    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SheetValue currentValue;
+    property public final boolean hasExpandedState;
+    property public final boolean hasPartiallyExpandedState;
+    property public final boolean isVisible;
+    property public final androidx.compose.material3.SheetValue targetValue;
+    field public static final androidx.compose.material3.SheetState.Companion Companion;
+  }
+
+  public static final class SheetState.Companion {
+    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SheetState,androidx.compose.material3.SheetValue> Saver(boolean skipPartiallyExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SheetState,androidx.compose.material3.SheetValue> Saver(boolean skipPartiallyExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, androidx.compose.ui.unit.Density density);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SheetValue {
+    method public static androidx.compose.material3.SheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SheetValue[] values();
+    enum_constant public static final androidx.compose.material3.SheetValue Expanded;
+    enum_constant public static final androidx.compose.material3.SheetValue Hidden;
+    enum_constant public static final androidx.compose.material3.SheetValue PartiallyExpanded;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface SingleChoiceSegmentedButtonRowScope extends androidx.compose.foundation.layout.RowScope {
+  }
+
+  @androidx.compose.runtime.Immutable public final class SliderColors {
+    ctor public SliderColors(long thumbColor, long activeTrackColor, long activeTickColor, long inactiveTrackColor, long inactiveTickColor, long disabledThumbColor, long disabledActiveTrackColor, long disabledActiveTickColor, long disabledInactiveTrackColor, long disabledInactiveTickColor);
+    method public long getActiveTickColor();
+    method public long getActiveTrackColor();
+    method public long getDisabledActiveTickColor();
+    method public long getDisabledActiveTrackColor();
+    method public long getDisabledInactiveTickColor();
+    method public long getDisabledInactiveTrackColor();
+    method public long getDisabledThumbColor();
+    method public long getInactiveTickColor();
+    method public long getInactiveTrackColor();
+    method public long getThumbColor();
+    property public final long activeTickColor;
+    property public final long activeTrackColor;
+    property public final long disabledActiveTickColor;
+    property public final long disabledActiveTrackColor;
+    property public final long disabledInactiveTickColor;
+    property public final long disabledInactiveTrackColor;
+    property public final long disabledThumbColor;
+    property public final long inactiveTickColor;
+    property public final long inactiveTrackColor;
+    property public final long thumbColor;
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.RangeSliderState rangeSliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @Deprecated @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderState sliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
+    field public static final androidx.compose.material3.SliderDefaults INSTANCE;
+  }
+
+  public final class SliderKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(androidx.compose.material3.RangeSliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track);
+    method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track, optional @IntRange(from=0L) int steps);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(androidx.compose.material3.SliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @Deprecated @androidx.compose.runtime.Stable public final class SliderPositions {
+    ctor @Deprecated public SliderPositions(optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> initialActiveRange, optional float[] initialTickFractions);
+    method @Deprecated public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getActiveRange();
+    method @Deprecated public float[] getTickFractions();
+    property @Deprecated public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> activeRange;
+    property @Deprecated public final float[] tickFractions;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SliderState implements androidx.compose.foundation.gestures.DraggableState {
+    ctor public SliderState(optional float value, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
+    method public void dispatchRawDelta(float delta);
+    method public suspend Object? drag(androidx.compose.foundation.MutatePriority dragPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.DragScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnValueChangeFinished();
+    method public int getSteps();
+    method public float getValue();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getValueRange();
+    method public void setValue(float);
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished;
+    property public final int steps;
+    property public final float value;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarData {
+    method public void dismiss();
+    method public androidx.compose.material3.SnackbarVisuals getVisuals();
+    method public void performAction();
+    property public abstract androidx.compose.material3.SnackbarVisuals visuals;
+  }
+
+  public final class SnackbarDefaults {
+    method @androidx.compose.runtime.Composable public long getActionColor();
+    method @androidx.compose.runtime.Composable public long getActionContentColor();
+    method @androidx.compose.runtime.Composable public long getColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getDismissActionContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property @androidx.compose.runtime.Composable public final long actionColor;
+    property @androidx.compose.runtime.Composable public final long actionContentColor;
+    property @androidx.compose.runtime.Composable public final long color;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long dismissActionContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SnackbarDefaults INSTANCE;
+  }
+
+  public enum SnackbarDuration {
+    method public static androidx.compose.material3.SnackbarDuration valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarDuration[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Indefinite;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Long;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Short;
+  }
+
+  public final class SnackbarHostKt {
+    method @androidx.compose.runtime.Composable public static void SnackbarHost(androidx.compose.material3.SnackbarHostState hostState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarData,kotlin.Unit> snackbar);
+  }
+
+  @androidx.compose.runtime.Stable public final class SnackbarHostState {
+    ctor public SnackbarHostState();
+    method public androidx.compose.material3.SnackbarData? getCurrentSnackbarData();
+    method public suspend Object? showSnackbar(androidx.compose.material3.SnackbarVisuals visuals, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    method public suspend Object? showSnackbar(String message, optional String? actionLabel, optional boolean withDismissAction, optional androidx.compose.material3.SnackbarDuration duration, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    property public final androidx.compose.material3.SnackbarData? currentSnackbarData;
+  }
+
+  public final class SnackbarKt {
+    method @androidx.compose.runtime.Composable public static void Snackbar(androidx.compose.material3.SnackbarData snackbarData, optional androidx.compose.ui.Modifier modifier, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionColor, optional long actionContentColor, optional long dismissActionContentColor);
+    method @androidx.compose.runtime.Composable public static void Snackbar(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissAction, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionContentColor, optional long dismissActionContentColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public enum SnackbarResult {
+    method public static androidx.compose.material3.SnackbarResult valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarResult[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarResult ActionPerformed;
+    enum_constant public static final androidx.compose.material3.SnackbarResult Dismissed;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarVisuals {
+    method public String? getActionLabel();
+    method public androidx.compose.material3.SnackbarDuration getDuration();
+    method public String getMessage();
+    method public boolean getWithDismissAction();
+    property public abstract String? actionLabel;
+    property public abstract androidx.compose.material3.SnackbarDuration duration;
+    property public abstract String message;
+    property public abstract boolean withDismissAction;
+  }
+
+  public final class SuggestionChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedSuggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedSuggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke suggestionChipBorder(boolean enabled, optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder suggestionChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors suggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation suggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SuggestionChipDefaults INSTANCE;
+  }
+
+  public final class SurfaceKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxDefaults {
+    method @androidx.compose.runtime.Composable public kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> getPositionalThreshold();
+    property @androidx.compose.runtime.Composable public final kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> positionalThreshold;
+    field public static final androidx.compose.material3.SwipeToDismissBoxDefaults INSTANCE;
+  }
+
+  public final class SwipeToDismissBoxKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.SwipeToDismissValue> directions);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState {
+    ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SwipeToDismissValue getCurrentValue();
+    method public androidx.compose.material3.SwipeToDismissValue getDismissDirection();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public androidx.compose.material3.SwipeToDismissValue getTargetValue();
+    method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
+    method public float requireOffset();
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SwipeToDismissValue currentValue;
+    property public final androidx.compose.material3.SwipeToDismissValue dismissDirection;
+    property @FloatRange(from=0.0, to=1.0) public final float progress;
+    property public final androidx.compose.material3.SwipeToDismissValue targetValue;
+    field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion;
+  }
+
+  public static final class SwipeToDismissState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SwipeToDismissState,androidx.compose.material3.SwipeToDismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue {
+    method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SwipeToDismissValue[] values();
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SwitchColors {
+    ctor public SwitchColors(long checkedThumbColor, long checkedTrackColor, long checkedBorderColor, long checkedIconColor, long uncheckedThumbColor, long uncheckedTrackColor, long uncheckedBorderColor, long uncheckedIconColor, long disabledCheckedThumbColor, long disabledCheckedTrackColor, long disabledCheckedBorderColor, long disabledCheckedIconColor, long disabledUncheckedThumbColor, long disabledUncheckedTrackColor, long disabledUncheckedBorderColor, long disabledUncheckedIconColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedIconColor();
+    method public long getCheckedThumbColor();
+    method public long getCheckedTrackColor();
+    method public long getDisabledCheckedBorderColor();
+    method public long getDisabledCheckedIconColor();
+    method public long getDisabledCheckedThumbColor();
+    method public long getDisabledCheckedTrackColor();
+    method public long getDisabledUncheckedBorderColor();
+    method public long getDisabledUncheckedIconColor();
+    method public long getDisabledUncheckedThumbColor();
+    method public long getDisabledUncheckedTrackColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedIconColor();
+    method public long getUncheckedThumbColor();
+    method public long getUncheckedTrackColor();
+    property public final long checkedBorderColor;
+    property public final long checkedIconColor;
+    property public final long checkedThumbColor;
+    property public final long checkedTrackColor;
+    property public final long disabledCheckedBorderColor;
+    property public final long disabledCheckedIconColor;
+    property public final long disabledCheckedThumbColor;
+    property public final long disabledCheckedTrackColor;
+    property public final long disabledUncheckedBorderColor;
+    property public final long disabledUncheckedIconColor;
+    property public final long disabledUncheckedThumbColor;
+    property public final long disabledUncheckedTrackColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedIconColor;
+    property public final long uncheckedThumbColor;
+    property public final long uncheckedTrackColor;
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SwitchColors colors(optional long checkedThumbColor, optional long checkedTrackColor, optional long checkedBorderColor, optional long checkedIconColor, optional long uncheckedThumbColor, optional long uncheckedTrackColor, optional long uncheckedBorderColor, optional long uncheckedIconColor, optional long disabledCheckedThumbColor, optional long disabledCheckedTrackColor, optional long disabledCheckedBorderColor, optional long disabledCheckedIconColor, optional long disabledUncheckedThumbColor, optional long disabledUncheckedTrackColor, optional long disabledUncheckedBorderColor, optional long disabledUncheckedIconColor);
+    method public float getIconSize();
+    property public final float IconSize;
+    field public static final androidx.compose.material3.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public interface TabIndicatorScope {
+    method public androidx.compose.ui.Modifier tabIndicatorLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super java.util.List<androidx.compose.material3.TabPosition>,? extends androidx.compose.ui.layout.MeasureResult> measure);
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, int selectedTabIndex, optional boolean matchContentSize);
+  }
+
+  public final class TabKt {
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TabPosition {
+    method public float getContentWidth();
+    method public float getLeft();
+    method public float getRight();
+    method public float getWidth();
+    property public final float contentWidth;
+    property public final float left;
+    property public final float right;
+    property public final float width;
+  }
+
+  public final class TabRowDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @androidx.compose.runtime.Composable public void PrimaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional long color, optional androidx.compose.ui.graphics.Shape shape);
+    method @androidx.compose.runtime.Composable public void SecondaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @Deprecated @androidx.compose.runtime.Composable public long getContainerColor();
+    method @Deprecated @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getPrimaryContainerColor();
+    method @androidx.compose.runtime.Composable public long getPrimaryContentColor();
+    method public float getScrollableTabRowEdgeStartPadding();
+    method @androidx.compose.runtime.Composable public long getSecondaryContainerColor();
+    method @androidx.compose.runtime.Composable public long getSecondaryContentColor();
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
+    property public final float ScrollableTabRowEdgeStartPadding;
+    property @Deprecated @androidx.compose.runtime.Composable public final long containerColor;
+    property @Deprecated @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long primaryContainerColor;
+    property @androidx.compose.runtime.Composable public final long primaryContentColor;
+    property @androidx.compose.runtime.Composable public final long secondaryContainerColor;
+    property @androidx.compose.runtime.Composable public final long secondaryContentColor;
+    field public static final androidx.compose.material3.TabRowDefaults INSTANCE;
+  }
+
+  public final class TabRowKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldColors {
+    ctor public TextFieldColors(long focusedTextColor, long unfocusedTextColor, long disabledTextColor, long errorTextColor, long focusedContainerColor, long unfocusedContainerColor, long disabledContainerColor, long errorContainerColor, long cursorColor, long errorCursorColor, androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors, long focusedIndicatorColor, long unfocusedIndicatorColor, long disabledIndicatorColor, long errorIndicatorColor, long focusedLeadingIconColor, long unfocusedLeadingIconColor, long disabledLeadingIconColor, long errorLeadingIconColor, long focusedTrailingIconColor, long unfocusedTrailingIconColor, long disabledTrailingIconColor, long errorTrailingIconColor, long focusedLabelColor, long unfocusedLabelColor, long disabledLabelColor, long errorLabelColor, long focusedPlaceholderColor, long unfocusedPlaceholderColor, long disabledPlaceholderColor, long errorPlaceholderColor, long focusedSupportingTextColor, long unfocusedSupportingTextColor, long disabledSupportingTextColor, long errorSupportingTextColor, long focusedPrefixColor, long unfocusedPrefixColor, long disabledPrefixColor, long errorPrefixColor, long focusedSuffixColor, long unfocusedSuffixColor, long disabledSuffixColor, long errorSuffixColor);
+    method public long getCursorColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledIndicatorColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledPlaceholderColor();
+    method public long getDisabledPrefixColor();
+    method public long getDisabledSuffixColor();
+    method public long getDisabledSupportingTextColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getErrorContainerColor();
+    method public long getErrorCursorColor();
+    method public long getErrorIndicatorColor();
+    method public long getErrorLabelColor();
+    method public long getErrorLeadingIconColor();
+    method public long getErrorPlaceholderColor();
+    method public long getErrorPrefixColor();
+    method public long getErrorSuffixColor();
+    method public long getErrorSupportingTextColor();
+    method public long getErrorTextColor();
+    method public long getErrorTrailingIconColor();
+    method public long getFocusedContainerColor();
+    method public long getFocusedIndicatorColor();
+    method public long getFocusedLabelColor();
+    method public long getFocusedLeadingIconColor();
+    method public long getFocusedPlaceholderColor();
+    method public long getFocusedPrefixColor();
+    method public long getFocusedSuffixColor();
+    method public long getFocusedSupportingTextColor();
+    method public long getFocusedTextColor();
+    method public long getFocusedTrailingIconColor();
+    method public androidx.compose.foundation.text.selection.TextSelectionColors getTextSelectionColors();
+    method public long getUnfocusedContainerColor();
+    method public long getUnfocusedIndicatorColor();
+    method public long getUnfocusedLabelColor();
+    method public long getUnfocusedLeadingIconColor();
+    method public long getUnfocusedPlaceholderColor();
+    method public long getUnfocusedPrefixColor();
+    method public long getUnfocusedSuffixColor();
+    method public long getUnfocusedSupportingTextColor();
+    method public long getUnfocusedTextColor();
+    method public long getUnfocusedTrailingIconColor();
+    property public final long cursorColor;
+    property public final long disabledContainerColor;
+    property public final long disabledIndicatorColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledPlaceholderColor;
+    property public final long disabledPrefixColor;
+    property public final long disabledSuffixColor;
+    property public final long disabledSupportingTextColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long errorContainerColor;
+    property public final long errorCursorColor;
+    property public final long errorIndicatorColor;
+    property public final long errorLabelColor;
+    property public final long errorLeadingIconColor;
+    property public final long errorPlaceholderColor;
+    property public final long errorPrefixColor;
+    property public final long errorSuffixColor;
+    property public final long errorSupportingTextColor;
+    property public final long errorTextColor;
+    property public final long errorTrailingIconColor;
+    property public final long focusedContainerColor;
+    property public final long focusedIndicatorColor;
+    property public final long focusedLabelColor;
+    property public final long focusedLeadingIconColor;
+    property public final long focusedPlaceholderColor;
+    property public final long focusedPrefixColor;
+    property public final long focusedSuffixColor;
+    property public final long focusedSupportingTextColor;
+    property public final long focusedTextColor;
+    property public final long focusedTrailingIconColor;
+    property public final androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors;
+    property public final long unfocusedContainerColor;
+    property public final long unfocusedIndicatorColor;
+    property public final long unfocusedLabelColor;
+    property public final long unfocusedLeadingIconColor;
+    property public final long unfocusedPlaceholderColor;
+    property public final long unfocusedPrefixColor;
+    property public final long unfocusedSuffixColor;
+    property public final long unfocusedSupportingTextColor;
+    property public final long unfocusedTextColor;
+    property public final long unfocusedTrailingIconColor;
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void ContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void DecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void FilledContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedBorderContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors colors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method public androidx.compose.foundation.layout.PaddingValues contentPaddingWithLabel(optional float start, optional float end, optional float top, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues contentPaddingWithoutLabel(optional float start, optional float top, optional float end, optional float bottom);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @Deprecated public float getFocusedBorderThickness();
+    method public float getFocusedIndicatorThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @Deprecated public float getUnfocusedBorderThickness();
+    method public float getUnfocusedIndicatorThickness();
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public androidx.compose.ui.Modifier indicatorLine(androidx.compose.ui.Modifier, boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional float focusedIndicatorLineThickness, optional float unfocusedIndicatorLineThickness);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
+    method @Deprecated public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
+    property @Deprecated public final float FocusedBorderThickness;
+    property public final float FocusedIndicatorThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property @Deprecated public final float UnfocusedBorderThickness;
+    property public final float UnfocusedIndicatorThickness;
+    property @Deprecated @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @Deprecated @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.TextFieldDefaults INSTANCE;
+  }
+
+  public final class TextFieldKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void ProvideTextStyle(androidx.compose.ui.text.TextStyle value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> getLocalTextStyle();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class TimePickerColors {
+    ctor public TimePickerColors(long clockDialColor, long selectorColor, long containerColor, long periodSelectorBorderColor, long clockDialSelectedContentColor, long clockDialUnselectedContentColor, long periodSelectorSelectedContainerColor, long periodSelectorUnselectedContainerColor, long periodSelectorSelectedContentColor, long periodSelectorUnselectedContentColor, long timeSelectorSelectedContainerColor, long timeSelectorUnselectedContainerColor, long timeSelectorSelectedContentColor, long timeSelectorUnselectedContentColor);
+    method public long getClockDialColor();
+    method public long getClockDialSelectedContentColor();
+    method public long getClockDialUnselectedContentColor();
+    method public long getContainerColor();
+    method public long getPeriodSelectorBorderColor();
+    method public long getPeriodSelectorSelectedContainerColor();
+    method public long getPeriodSelectorSelectedContentColor();
+    method public long getPeriodSelectorUnselectedContainerColor();
+    method public long getPeriodSelectorUnselectedContentColor();
+    method public long getSelectorColor();
+    method public long getTimeSelectorSelectedContainerColor();
+    method public long getTimeSelectorSelectedContentColor();
+    method public long getTimeSelectorUnselectedContainerColor();
+    method public long getTimeSelectorUnselectedContentColor();
+    property public final long clockDialColor;
+    property public final long clockDialSelectedContentColor;
+    property public final long clockDialUnselectedContentColor;
+    property public final long containerColor;
+    property public final long periodSelectorBorderColor;
+    property public final long periodSelectorSelectedContainerColor;
+    property public final long periodSelectorSelectedContentColor;
+    property public final long periodSelectorUnselectedContainerColor;
+    property public final long periodSelectorUnselectedContentColor;
+    property public final long selectorColor;
+    property public final long timeSelectorSelectedContainerColor;
+    property public final long timeSelectorSelectedContentColor;
+    property public final long timeSelectorUnselectedContainerColor;
+    property public final long timeSelectorUnselectedContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TimePickerColors colors(optional long clockDialColor, optional long clockDialSelectedContentColor, optional long clockDialUnselectedContentColor, optional long selectorColor, optional long containerColor, optional long periodSelectorBorderColor, optional long periodSelectorSelectedContainerColor, optional long periodSelectorUnselectedContainerColor, optional long periodSelectorSelectedContentColor, optional long periodSelectorUnselectedContentColor, optional long timeSelectorSelectedContainerColor, optional long timeSelectorUnselectedContainerColor, optional long timeSelectorSelectedContentColor, optional long timeSelectorUnselectedContentColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public int layoutType();
+    field public static final androidx.compose.material3.TimePickerDefaults INSTANCE;
+  }
+
+  public final class TimePickerKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TimeInput(androidx.compose.material3.TimePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.TimePickerColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TimePicker(androidx.compose.material3.TimePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.TimePickerColors colors, optional int layoutType);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TimePickerState rememberTimePickerState(optional int initialHour, optional int initialMinute, optional boolean is24Hour);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TimePickerLayoutType {
+    field public static final androidx.compose.material3.TimePickerLayoutType.Companion Companion;
+  }
+
+  public static final class TimePickerLayoutType.Companion {
+    method public int getHorizontal();
+    method public int getVertical();
+    property public final int Horizontal;
+    property public final int Vertical;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerState {
+    ctor public TimePickerState(int initialHour, int initialMinute, boolean is24Hour);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24hour();
+    method public suspend Object? settle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final int hour;
+    property public final boolean is24hour;
+    property public final int minute;
+    field public static final androidx.compose.material3.TimePickerState.Companion Companion;
+  }
+
+  public static final class TimePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TimePickerState,?> Saver();
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface TooltipBoxScope {
+    method @Deprecated public androidx.compose.ui.Modifier tooltipTrigger(androidx.compose.ui.Modifier);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class TooltipDefaults {
+    method @androidx.compose.runtime.Composable public long getPlainTooltipContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getPlainTooltipContainerShape();
+    method @androidx.compose.runtime.Composable public long getPlainTooltipContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getRichTooltipContainerShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.window.PopupPositionProvider rememberPlainTooltipPositionProvider(optional float spacingBetweenTooltipAndAnchor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.window.PopupPositionProvider rememberRichTooltipPositionProvider(optional float spacingBetweenTooltipAndAnchor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RichTooltipColors richTooltipColors(optional long containerColor, optional long contentColor, optional long titleContentColor, optional long actionContentColor);
+    property @androidx.compose.runtime.Composable public final long plainTooltipContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape plainTooltipContainerShape;
+    property @androidx.compose.runtime.Composable public final long plainTooltipContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape richTooltipContainerShape;
+    field public static final androidx.compose.material3.TooltipDefaults INSTANCE;
+  }
+
+  public final class TooltipKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(optional androidx.compose.ui.Modifier modifier, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltipBox(kotlin.jvm.functions.Function0<kotlin.Unit> tooltip, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional androidx.compose.material3.PlainTooltipState tooltipState, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional float tonalElevation, optional float shadowElevation, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipBoxScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltipBox(kotlin.jvm.functions.Function0<kotlin.Unit> text, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional androidx.compose.material3.RichTooltipState tooltipState, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipBoxScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TooltipBox(androidx.compose.ui.window.PopupPositionProvider positionProvider, kotlin.jvm.functions.Function0<kotlin.Unit> tooltip, androidx.compose.material3.TooltipState state, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional boolean enableUserInput, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.TooltipState TooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.PlainTooltipState rememberPlainTooltipState(optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.RichTooltipState rememberRichTooltipState(boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TooltipState rememberTooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface TooltipState extends androidx.compose.material3.BasicTooltipState {
+    method public androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> getTransition();
+    property public abstract androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> transition;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
+    ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
+    method public long getActionIconContentColor();
+    method public long getContainerColor();
+    method public long getNavigationIconContentColor();
+    method public long getScrolledContainerColor();
+    method public long getTitleContentColor();
+    property public final long actionIconContentColor;
+    property public final long containerColor;
+    property public final long navigationIconContentColor;
+    property public final long scrolledContainerColor;
+    property public final long titleContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class TopAppBarDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors centerAlignedTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior enterAlwaysScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior exitUntilCollapsedScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors largeTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors mediumTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior pinnedScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors smallTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors topAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.TopAppBarDefaults INSTANCE;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface TopAppBarScrollBehavior {
+    method public androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? getFlingAnimationSpec();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float>? getSnapAnimationSpec();
+    method public androidx.compose.material3.TopAppBarState getState();
+    method public boolean isPinned();
+    property public abstract androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec;
+    property public abstract boolean isPinned;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec;
+    property public abstract androidx.compose.material3.TopAppBarState state;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarState {
+    ctor public TopAppBarState(float initialHeightOffsetLimit, float initialHeightOffset, float initialContentOffset);
+    method public float getCollapsedFraction();
+    method public float getContentOffset();
+    method public float getHeightOffset();
+    method public float getHeightOffsetLimit();
+    method public float getOverlappedFraction();
+    method public void setContentOffset(float);
+    method public void setHeightOffset(float);
+    method public void setHeightOffsetLimit(float);
+    property public final float collapsedFraction;
+    property public final float contentOffset;
+    property public final float heightOffset;
+    property public final float heightOffsetLimit;
+    property public final float overlappedFraction;
+    field public static final androidx.compose.material3.TopAppBarState.Companion Companion;
+  }
+
+  public static final class TopAppBarState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,?> Saver;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Typography {
+    ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.ui.text.TextStyle getBodyLarge();
+    method public androidx.compose.ui.text.TextStyle getBodyMedium();
+    method public androidx.compose.ui.text.TextStyle getBodySmall();
+    method public androidx.compose.ui.text.TextStyle getDisplayLarge();
+    method public androidx.compose.ui.text.TextStyle getDisplayMedium();
+    method public androidx.compose.ui.text.TextStyle getDisplaySmall();
+    method public androidx.compose.ui.text.TextStyle getHeadlineLarge();
+    method public androidx.compose.ui.text.TextStyle getHeadlineMedium();
+    method public androidx.compose.ui.text.TextStyle getHeadlineSmall();
+    method public androidx.compose.ui.text.TextStyle getLabelLarge();
+    method public androidx.compose.ui.text.TextStyle getLabelMedium();
+    method public androidx.compose.ui.text.TextStyle getLabelSmall();
+    method public androidx.compose.ui.text.TextStyle getTitleLarge();
+    method public androidx.compose.ui.text.TextStyle getTitleMedium();
+    method public androidx.compose.ui.text.TextStyle getTitleSmall();
+    property public final androidx.compose.ui.text.TextStyle bodyLarge;
+    property public final androidx.compose.ui.text.TextStyle bodyMedium;
+    property public final androidx.compose.ui.text.TextStyle bodySmall;
+    property public final androidx.compose.ui.text.TextStyle displayLarge;
+    property public final androidx.compose.ui.text.TextStyle displayMedium;
+    property public final androidx.compose.ui.text.TextStyle displaySmall;
+    property public final androidx.compose.ui.text.TextStyle headlineLarge;
+    property public final androidx.compose.ui.text.TextStyle headlineMedium;
+    property public final androidx.compose.ui.text.TextStyle headlineSmall;
+    property public final androidx.compose.ui.text.TextStyle labelLarge;
+    property public final androidx.compose.ui.text.TextStyle labelMedium;
+    property public final androidx.compose.ui.text.TextStyle labelSmall;
+    property public final androidx.compose.ui.text.TextStyle titleLarge;
+    property public final androidx.compose.ui.text.TextStyle titleMedium;
+    property public final androidx.compose.ui.text.TextStyle titleSmall;
+  }
+
+}
+
+package androidx.compose.material3.pulltorefresh {
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class PullToRefreshDefaults {
+    method @androidx.compose.runtime.Composable public void Indicator(androidx.compose.material3.pulltorefresh.PullToRefreshState state, optional androidx.compose.ui.Modifier modifier, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method public float getPositionalThreshold();
+    method public androidx.compose.ui.graphics.Shape getShape();
+    property public final float PositionalThreshold;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.pulltorefresh.PullToRefreshDefaults INSTANCE;
+  }
+
+  public final class PullToRefreshKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PullToRefreshContainer(androidx.compose.material3.pulltorefresh.PullToRefreshState state, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.pulltorefresh.PullToRefreshState,kotlin.Unit> indicator, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.pulltorefresh.PullToRefreshState PullToRefreshState(float positionalThresholdPx, optional boolean initialRefreshing, optional kotlin.jvm.functions.Function0<java.lang.Boolean> enabled);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.pulltorefresh.PullToRefreshState rememberPullToRefreshState(optional float positionalThreshold, optional kotlin.jvm.functions.Function0<java.lang.Boolean> enabled);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface PullToRefreshState {
+    method public void endRefresh();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public float getPositionalThreshold();
+    method @FloatRange(from=0.0) public float getProgress();
+    method @FloatRange(from=0.0) public float getVerticalOffset();
+    method public boolean isRefreshing();
+    method public void setNestedScrollConnection(androidx.compose.ui.input.nestedscroll.NestedScrollConnection);
+    method public void startRefresh();
+    property public abstract boolean isRefreshing;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract float positionalThreshold;
+    property @FloatRange(from=0.0) public abstract float progress;
+    property @FloatRange(from=0.0) public abstract float verticalOffset;
+  }
+
+}
+
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index a623044..7ca2ade 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -597,43 +597,19 @@
     property public abstract kotlin.ranges.IntRange yearRange;
   }
 
-  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
-    method public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material3.DismissDirection[] values();
-    enum_constant public static final androidx.compose.material3.DismissDirection EndToStart;
-    enum_constant public static final androidx.compose.material3.DismissDirection StartToEnd;
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
+    method @Deprecated public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissDirection[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection EndToStart;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection StartToEnd;
   }
 
-  public final class DismissState {
-    ctor public DismissState(androidx.compose.material3.DismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
-    ctor @Deprecated public DismissState(androidx.compose.material3.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
-    method public suspend Object? dismiss(androidx.compose.material3.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material3.DismissValue getCurrentValue();
-    method public androidx.compose.material3.DismissDirection? getDismissDirection();
-    method public float getProgress();
-    method public androidx.compose.material3.DismissValue getTargetValue();
-    method public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
-    method public float requireOffset();
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? snapTo(androidx.compose.material3.DismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material3.DismissValue currentValue;
-    property public final androidx.compose.material3.DismissDirection? dismissDirection;
-    property public final float progress;
-    property public final androidx.compose.material3.DismissValue targetValue;
-    field public static final androidx.compose.material3.DismissState.Companion Companion;
-  }
-
-  public static final class DismissState.Companion {
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DismissState,androidx.compose.material3.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DismissState,androidx.compose.material3.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density);
-  }
-
-  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
-    method public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material3.DismissValue[] values();
-    enum_constant public static final androidx.compose.material3.DismissValue Default;
-    enum_constant public static final androidx.compose.material3.DismissValue DismissedToEnd;
-    enum_constant public static final androidx.compose.material3.DismissValue DismissedToStart;
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
+    method @Deprecated public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissValue[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue Default;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToEnd;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToStart;
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
@@ -1559,15 +1535,45 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxDefaults {
-    method @androidx.compose.runtime.Composable public kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> getFixedPositionalThreshold();
-    property @androidx.compose.runtime.Composable public final kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> fixedPositionalThreshold;
+    method @androidx.compose.runtime.Composable public kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> getPositionalThreshold();
+    property @androidx.compose.runtime.Composable public final kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> positionalThreshold;
     field public static final androidx.compose.material3.SwipeToDismissBoxDefaults INSTANCE;
   }
 
   public final class SwipeToDismissBoxKt {
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.DismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.DismissDirection> directions);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.DismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.DismissDirection> directions, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DismissState rememberDismissState(optional androidx.compose.material3.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.SwipeToDismissValue> directions);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState {
+    ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SwipeToDismissValue getCurrentValue();
+    method public androidx.compose.material3.SwipeToDismissValue getDismissDirection();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public androidx.compose.material3.SwipeToDismissValue getTargetValue();
+    method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
+    method public float requireOffset();
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SwipeToDismissValue currentValue;
+    property public final androidx.compose.material3.SwipeToDismissValue dismissDirection;
+    property @FloatRange(from=0.0, to=1.0) public final float progress;
+    property public final androidx.compose.material3.SwipeToDismissValue targetValue;
+    field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion;
+  }
+
+  public static final class SwipeToDismissState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SwipeToDismissState,androidx.compose.material3.SwipeToDismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue {
+    method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SwipeToDismissValue[] values();
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd;
   }
 
   @androidx.compose.runtime.Immutable public final class SwitchColors {
@@ -1617,6 +1623,11 @@
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
   }
 
+  public interface TabIndicatorScope {
+    method public androidx.compose.ui.Modifier tabIndicatorLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super java.util.List<androidx.compose.material3.TabPosition>,? extends androidx.compose.ui.layout.MeasureResult> measure);
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, int selectedTabIndex, optional boolean matchContentSize);
+  }
+
   public final class TabKt {
     method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
     method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
@@ -1658,10 +1669,10 @@
 
   public final class TabRowKt {
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
     method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
     method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
   }
 
diff --git a/compose/material3/material3/api/res-1.2.0-beta01.txt b/compose/material3/material3/api/res-1.2.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/compose/material3/material3/api/res-1.2.0-beta01.txt
diff --git a/compose/material3/material3/api/restricted_1.2.0-beta01.txt b/compose/material3/material3/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..7ca2ade
--- /dev/null
+++ b/compose/material3/material3/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,2073 @@
+// Signature format: 4.0
+package androidx.compose.material3 {
+
+  public final class AlertDialogDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getIconContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public long getTextContentColor();
+    method @androidx.compose.runtime.Composable public long getTitleContentColor();
+    method public float getTonalElevation();
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long iconContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final long textContentColor;
+    property @androidx.compose.runtime.Composable public final long titleContentColor;
+    field public static final androidx.compose.material3.AlertDialogDefaults INSTANCE;
+  }
+
+  public final class AndroidAlertDialog_androidKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long iconContentColor, optional long titleContentColor, optional long textContentColor, optional float tonalElevation, optional androidx.compose.ui.window.DialogProperties properties);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BasicAlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class AndroidMenu_androidKt {
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public final class AppBarKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.BottomAppBarScrollBehavior? scrollBehavior, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BottomAppBar(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.BottomAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.BottomAppBarState BottomAppBarState(float initialHeightOffsetLimit, float initialHeightOffset, float initialContentOffset);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void CenterAlignedTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void LargeTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MediumTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SmallTopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.TopAppBarColors colors, optional androidx.compose.material3.TopAppBarScrollBehavior? scrollBehavior);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.BottomAppBarState rememberBottomAppBarState(optional float initialHeightOffsetLimit, optional float initialHeightOffset, optional float initialContentOffset);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TopAppBarState rememberTopAppBarState(optional float initialHeightOffsetLimit, optional float initialHeightOffset, optional float initialContentOffset);
+  }
+
+  public final class AssistChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke assistChipBorder(boolean enabled, optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder assistChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors assistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation assistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedAssistChipColors(optional long containerColor, optional long labelColor, optional long leadingIconContentColor, optional long trailingIconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconContentColor, optional long disabledTrailingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedAssistChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.AssistChipDefaults INSTANCE;
+  }
+
+  public final class BadgeDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    field public static final androidx.compose.material3.BadgeDefaults INSTANCE;
+  }
+
+  public final class BadgeKt {
+    method @androidx.compose.runtime.Composable public static void Badge(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? content);
+    method @androidx.compose.runtime.Composable public static void BadgedBox(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> badge, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface BasicTooltipState {
+    method public void dismiss();
+    method public boolean isPersistent();
+    method public boolean isVisible();
+    method public void onDispose();
+    method public suspend Object? show(optional androidx.compose.foundation.MutatePriority mutatePriority, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract boolean isPersistent;
+    property public abstract boolean isVisible;
+  }
+
+  public final class BottomAppBarDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.BottomAppBarScrollBehavior exitAlwaysScrollBehavior(optional androidx.compose.material3.BottomAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @androidx.compose.runtime.Composable public long getBottomAppBarFabColor();
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getContainerElevation();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float ContainerElevation;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property @androidx.compose.runtime.Composable public final long bottomAppBarFabColor;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface BottomAppBarScrollBehavior {
+    method public androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? getFlingAnimationSpec();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float>? getSnapAnimationSpec();
+    method public androidx.compose.material3.BottomAppBarState getState();
+    method public boolean isPinned();
+    property public abstract androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec;
+    property public abstract boolean isPinned;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec;
+    property public abstract androidx.compose.material3.BottomAppBarState state;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface BottomAppBarState {
+    method public float getCollapsedFraction();
+    method public float getContentOffset();
+    method public float getHeightOffset();
+    method public float getHeightOffsetLimit();
+    method public void setContentOffset(float);
+    method public void setHeightOffset(float);
+    method public void setHeightOffsetLimit(float);
+    property public abstract float collapsedFraction;
+    property public abstract float contentOffset;
+    property public abstract float heightOffset;
+    property public abstract float heightOffsetLimit;
+    field public static final androidx.compose.material3.BottomAppBarState.Companion Companion;
+  }
+
+  public static final class BottomAppBarState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.BottomAppBarState,?> Saver;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetDefaults {
+    method @androidx.compose.runtime.Composable public void DragHandle(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional androidx.compose.ui.graphics.Shape shape, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExpandedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getHiddenShape();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method public float getSheetMaxWidth();
+    method public float getSheetPeekHeight();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape ExpandedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape HiddenShape;
+    property @androidx.compose.runtime.Composable public final long ScrimColor;
+    property public final float SheetMaxWidth;
+    property public final float SheetPeekHeight;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.BottomSheetDefaults INSTANCE;
+  }
+
+  public final class BottomSheetScaffoldKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void BottomSheetScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.BottomSheetScaffoldState scaffoldState, optional float sheetPeekHeight, optional float sheetMaxWidth, optional androidx.compose.ui.graphics.Shape sheetShape, optional long sheetContainerColor, optional long sheetContentColor, optional float sheetTonalElevation, optional float sheetShadowElevation, optional kotlin.jvm.functions.Function0<kotlin.Unit>? sheetDragHandle, optional boolean sheetSwipeEnabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarHostState,kotlin.Unit> snackbarHost, optional long containerColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material3.SheetState bottomSheetState, optional androidx.compose.material3.SnackbarHostState snackbarHostState);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SheetState rememberStandardBottomSheetState(optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class BottomSheetScaffoldState {
+    ctor public BottomSheetScaffoldState(androidx.compose.material3.SheetState bottomSheetState, androidx.compose.material3.SnackbarHostState snackbarHostState);
+    method public androidx.compose.material3.SheetState getBottomSheetState();
+    method public androidx.compose.material3.SnackbarHostState getSnackbarHostState();
+    property public final androidx.compose.material3.SheetState bottomSheetState;
+    property public final androidx.compose.material3.SnackbarHostState snackbarHostState;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ButtonColors {
+    ctor public ButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors buttonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation buttonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors elevatedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation elevatedButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors filledTonalButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonElevation filledTonalButtonElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float disabledElevation);
+    method public androidx.compose.foundation.layout.PaddingValues getButtonWithIconContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledTonalShape();
+    method public float getIconSize();
+    method public float getIconSpacing();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedButtonBorder();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonContentPadding();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonWithIconContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getTextShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors outlinedButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ButtonColors textButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ButtonWithIconContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float IconSize;
+    property public final float IconSpacing;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonContentPadding;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonWithIconContentPadding;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledTonalShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedButtonBorder;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape textShape;
+    field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class ButtonElevation {
+  }
+
+  public final class ButtonKt {
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public final class CalendarModelKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static String formatWithSkeleton(long utcTimeMillis, String skeleton, java.util.Locale locale, java.util.Map<java.lang.String,java.lang.Object> cache);
+  }
+
+  public final class CalendarModel_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static String formatWithSkeleton(long utcTimeMillis, String skeleton, java.util.Locale locale, java.util.Map<java.lang.String,java.lang.Object> cache);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardColors {
+    ctor public CardColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class CardDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation cardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors elevatedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation elevatedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getElevatedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardColors outlinedCardColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CardElevation outlinedCardElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape elevatedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.CardDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class CardElevation {
+  }
+
+  public final class CardKt {
+    method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CheckboxColors {
+    ctor public CheckboxColors(long checkedCheckmarkColor, long uncheckedCheckmarkColor, long checkedBoxColor, long uncheckedBoxColor, long disabledCheckedBoxColor, long disabledUncheckedBoxColor, long disabledIndeterminateBoxColor, long checkedBorderColor, long uncheckedBorderColor, long disabledBorderColor, long disabledUncheckedBorderColor, long disabledIndeterminateBorderColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedBoxColor();
+    method public long getCheckedCheckmarkColor();
+    method public long getDisabledBorderColor();
+    method public long getDisabledCheckedBoxColor();
+    method public long getDisabledIndeterminateBorderColor();
+    method public long getDisabledIndeterminateBoxColor();
+    method public long getDisabledUncheckedBorderColor();
+    method public long getDisabledUncheckedBoxColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedBoxColor();
+    method public long getUncheckedCheckmarkColor();
+    property public final long checkedBorderColor;
+    property public final long checkedBoxColor;
+    property public final long checkedCheckmarkColor;
+    property public final long disabledBorderColor;
+    property public final long disabledCheckedBoxColor;
+    property public final long disabledIndeterminateBorderColor;
+    property public final long disabledIndeterminateBoxColor;
+    property public final long disabledUncheckedBorderColor;
+    property public final long disabledUncheckedBoxColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedBoxColor;
+    property public final long uncheckedCheckmarkColor;
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.CheckboxColors colors(optional long checkedColor, optional long uncheckedColor, optional long checkmarkColor, optional long disabledCheckedColor, optional long disabledUncheckedColor, optional long disabledIndeterminateColor);
+    field public static final androidx.compose.material3.CheckboxDefaults INSTANCE;
+  }
+
+  public final class CheckboxKt {
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @Deprecated @androidx.compose.runtime.Immutable public final class ChipBorder {
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipColors {
+    ctor public ChipColors(long containerColor, long labelColor, long leadingIconContentColor, long trailingIconContentColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconContentColor, long disabledTrailingIconContentColor);
+    method public long getContainerColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconContentColor();
+    method public long getDisabledTrailingIconContentColor();
+    method public long getLabelColor();
+    method public long getLeadingIconContentColor();
+    method public long getTrailingIconContentColor();
+    property public final long containerColor;
+    property public final long disabledContainerColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconContentColor;
+    property public final long disabledTrailingIconContentColor;
+    property public final long labelColor;
+    property public final long leadingIconContentColor;
+    property public final long trailingIconContentColor;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ChipElevation {
+    ctor public ChipElevation(float elevation, float pressedElevation, float focusedElevation, float hoveredElevation, float draggedElevation, float disabledElevation);
+    method public float getDisabledElevation();
+    method public float getDraggedElevation();
+    method public float getElevation();
+    method public float getFocusedElevation();
+    method public float getHoveredElevation();
+    method public float getPressedElevation();
+    property public final float disabledElevation;
+    property public final float draggedElevation;
+    property public final float elevation;
+    property public final float focusedElevation;
+    property public final float hoveredElevation;
+    property public final float pressedElevation;
+  }
+
+  public final class ChipKt {
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @Deprecated @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ColorScheme {
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim);
+    ctor public ColorScheme(long primary, long onPrimary, long primaryContainer, long onPrimaryContainer, long inversePrimary, long secondary, long onSecondary, long secondaryContainer, long onSecondaryContainer, long tertiary, long onTertiary, long tertiaryContainer, long onTertiaryContainer, long background, long onBackground, long surface, long onSurface, long surfaceVariant, long onSurfaceVariant, long surfaceTint, long inverseSurface, long inverseOnSurface, long error, long onError, long errorContainer, long onErrorContainer, long outline, long outlineVariant, long scrim, long surfaceBright, long surfaceDim, long surfaceContainer, long surfaceContainerHigh, long surfaceContainerHighest, long surfaceContainerLow, long surfaceContainerLowest);
+    method @Deprecated public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public androidx.compose.material3.ColorScheme copy(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim, optional long surfaceBright, optional long surfaceDim, optional long surfaceContainer, optional long surfaceContainerHigh, optional long surfaceContainerHighest, optional long surfaceContainerLow, optional long surfaceContainerLowest);
+    method public long getBackground();
+    method public long getError();
+    method public long getErrorContainer();
+    method public long getInverseOnSurface();
+    method public long getInversePrimary();
+    method public long getInverseSurface();
+    method public long getOnBackground();
+    method public long getOnError();
+    method public long getOnErrorContainer();
+    method public long getOnPrimary();
+    method public long getOnPrimaryContainer();
+    method public long getOnSecondary();
+    method public long getOnSecondaryContainer();
+    method public long getOnSurface();
+    method public long getOnSurfaceVariant();
+    method public long getOnTertiary();
+    method public long getOnTertiaryContainer();
+    method public long getOutline();
+    method public long getOutlineVariant();
+    method public long getPrimary();
+    method public long getPrimaryContainer();
+    method public long getScrim();
+    method public long getSecondary();
+    method public long getSecondaryContainer();
+    method public long getSurface();
+    method public long getSurfaceBright();
+    method public long getSurfaceContainer();
+    method public long getSurfaceContainerHigh();
+    method public long getSurfaceContainerHighest();
+    method public long getSurfaceContainerLow();
+    method public long getSurfaceContainerLowest();
+    method public long getSurfaceDim();
+    method public long getSurfaceTint();
+    method public long getSurfaceVariant();
+    method public long getTertiary();
+    method public long getTertiaryContainer();
+    property public final long background;
+    property public final long error;
+    property public final long errorContainer;
+    property public final long inverseOnSurface;
+    property public final long inversePrimary;
+    property public final long inverseSurface;
+    property public final long onBackground;
+    property public final long onError;
+    property public final long onErrorContainer;
+    property public final long onPrimary;
+    property public final long onPrimaryContainer;
+    property public final long onSecondary;
+    property public final long onSecondaryContainer;
+    property public final long onSurface;
+    property public final long onSurfaceVariant;
+    property public final long onTertiary;
+    property public final long onTertiaryContainer;
+    property public final long outline;
+    property public final long outlineVariant;
+    property public final long primary;
+    property public final long primaryContainer;
+    property public final long scrim;
+    property public final long secondary;
+    property public final long secondaryContainer;
+    property public final long surface;
+    property public final long surfaceBright;
+    property public final long surfaceContainer;
+    property public final long surfaceContainerHigh;
+    property public final long surfaceContainerHighest;
+    property public final long surfaceContainerLow;
+    property public final long surfaceContainerLowest;
+    property public final long surfaceDim;
+    property public final long surfaceTint;
+    property public final long surfaceVariant;
+    property public final long tertiary;
+    property public final long tertiaryContainer;
+  }
+
+  public final class ColorSchemeKt {
+    method @androidx.compose.runtime.Stable public static long contentColorFor(androidx.compose.material3.ColorScheme, long backgroundColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
+    method @Deprecated public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme darkColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim, optional long surfaceBright, optional long surfaceContainer, optional long surfaceContainerHigh, optional long surfaceContainerHighest, optional long surfaceContainerLow, optional long surfaceContainerLowest, optional long surfaceDim);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalTonalElevationEnabled();
+    method @Deprecated public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim);
+    method public static androidx.compose.material3.ColorScheme lightColorScheme(optional long primary, optional long onPrimary, optional long primaryContainer, optional long onPrimaryContainer, optional long inversePrimary, optional long secondary, optional long onSecondary, optional long secondaryContainer, optional long onSecondaryContainer, optional long tertiary, optional long onTertiary, optional long tertiaryContainer, optional long onTertiaryContainer, optional long background, optional long onBackground, optional long surface, optional long onSurface, optional long surfaceVariant, optional long onSurfaceVariant, optional long surfaceTint, optional long inverseSurface, optional long inverseOnSurface, optional long error, optional long onError, optional long errorContainer, optional long onErrorContainer, optional long outline, optional long outlineVariant, optional long scrim, optional long surfaceBright, optional long surfaceContainer, optional long surfaceContainerHigh, optional long surfaceContainerHighest, optional long surfaceContainerLow, optional long surfaceContainerLowest, optional long surfaceDim);
+    method @androidx.compose.runtime.Stable public static long surfaceColorAtElevation(androidx.compose.material3.ColorScheme, float elevation);
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalTonalElevationEnabled;
+  }
+
+  public final class ContentColorKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> getLocalContentColor();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> LocalContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class DatePickerColors {
+    ctor public DatePickerColors(long containerColor, long titleContentColor, long headlineContentColor, long weekdayContentColor, long subheadContentColor, long navigationContentColor, long yearContentColor, long disabledYearContentColor, long currentYearContentColor, long selectedYearContentColor, long disabledSelectedYearContentColor, long selectedYearContainerColor, long disabledSelectedYearContainerColor, long dayContentColor, long disabledDayContentColor, long selectedDayContentColor, long disabledSelectedDayContentColor, long selectedDayContainerColor, long disabledSelectedDayContainerColor, long todayContentColor, long todayDateBorderColor, long dayInSelectionRangeContainerColor, long dayInSelectionRangeContentColor, long dividerColor, androidx.compose.material3.TextFieldColors dateTextFieldColors);
+    method public long getContainerColor();
+    method public long getCurrentYearContentColor();
+    method public androidx.compose.material3.TextFieldColors getDateTextFieldColors();
+    method public long getDayContentColor();
+    method public long getDayInSelectionRangeContainerColor();
+    method public long getDayInSelectionRangeContentColor();
+    method public long getDisabledDayContentColor();
+    method public long getDisabledSelectedDayContainerColor();
+    method public long getDisabledSelectedDayContentColor();
+    method public long getDisabledSelectedYearContainerColor();
+    method public long getDisabledSelectedYearContentColor();
+    method public long getDisabledYearContentColor();
+    method public long getDividerColor();
+    method public long getHeadlineContentColor();
+    method public long getNavigationContentColor();
+    method public long getSelectedDayContainerColor();
+    method public long getSelectedDayContentColor();
+    method public long getSelectedYearContainerColor();
+    method public long getSelectedYearContentColor();
+    method public long getSubheadContentColor();
+    method public long getTitleContentColor();
+    method public long getTodayContentColor();
+    method public long getTodayDateBorderColor();
+    method public long getWeekdayContentColor();
+    method public long getYearContentColor();
+    property public final long containerColor;
+    property public final long currentYearContentColor;
+    property public final androidx.compose.material3.TextFieldColors dateTextFieldColors;
+    property public final long dayContentColor;
+    property public final long dayInSelectionRangeContainerColor;
+    property public final long dayInSelectionRangeContentColor;
+    property public final long disabledDayContentColor;
+    property public final long disabledSelectedDayContainerColor;
+    property public final long disabledSelectedDayContentColor;
+    property public final long disabledSelectedYearContainerColor;
+    property public final long disabledSelectedYearContentColor;
+    property public final long disabledYearContentColor;
+    property public final long dividerColor;
+    property public final long headlineContentColor;
+    property public final long navigationContentColor;
+    property public final long selectedDayContainerColor;
+    property public final long selectedDayContentColor;
+    property public final long selectedYearContainerColor;
+    property public final long selectedYearContentColor;
+    property public final long subheadContentColor;
+    property public final long titleContentColor;
+    property public final long todayContentColor;
+    property public final long todayDateBorderColor;
+    property public final long weekdayContentColor;
+    property public final long yearContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DatePickerDefaults {
+    method @androidx.compose.runtime.Composable public void DatePickerHeadline(Long? selectedDateMillis, int displayMode, androidx.compose.material3.DatePickerFormatter dateFormatter, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public void DatePickerTitle(int displayMode, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.DatePickerColors colors(optional long containerColor, optional long titleContentColor, optional long headlineContentColor, optional long weekdayContentColor, optional long subheadContentColor, optional long navigationContentColor, optional long yearContentColor, optional long disabledYearContentColor, optional long currentYearContentColor, optional long selectedYearContentColor, optional long disabledSelectedYearContentColor, optional long selectedYearContainerColor, optional long disabledSelectedYearContainerColor, optional long dayContentColor, optional long disabledDayContentColor, optional long selectedDayContentColor, optional long disabledSelectedDayContentColor, optional long selectedDayContainerColor, optional long disabledSelectedDayContainerColor, optional long todayContentColor, optional long todayDateBorderColor, optional long dayInSelectionRangeContentColor, optional long dayInSelectionRangeContainerColor, optional long dividerColor, optional androidx.compose.material3.TextFieldColors dateTextFieldColors);
+    method public androidx.compose.material3.DatePickerFormatter dateFormatter(optional String yearSelectionSkeleton, optional String selectedDateSkeleton, optional String selectedDateDescriptionSkeleton);
+    method public androidx.compose.material3.SelectableDates getAllDates();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getTonalElevation();
+    method public kotlin.ranges.IntRange getYearRange();
+    property public final androidx.compose.material3.SelectableDates AllDates;
+    property public final float TonalElevation;
+    property public final kotlin.ranges.IntRange YearRange;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.DatePickerDefaults INSTANCE;
+    field public static final String YearAbbrMonthDaySkeleton = "yMMMd";
+    field public static final String YearMonthSkeleton = "yMMMM";
+    field public static final String YearMonthWeekdayDaySkeleton = "yMMMMEEEEd";
+  }
+
+  public final class DatePickerDialog_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DatePickerDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional androidx.compose.ui.graphics.Shape shape, optional float tonalElevation, optional androidx.compose.material3.DatePickerColors colors, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface DatePickerFormatter {
+    method public String? formatDate(Long? dateMillis, java.util.Locale locale, optional boolean forContentDescription);
+    method public String? formatMonthYear(Long? monthMillis, java.util.Locale locale);
+  }
+
+  public final class DatePickerKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DatePicker(androidx.compose.material3.DatePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.DatePickerState DatePickerState(java.util.Locale locale, optional Long? initialSelectedDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DatePickerState rememberDatePickerState(optional Long? initialSelectedDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface DatePickerState {
+    method public int getDisplayMode();
+    method public long getDisplayedMonthMillis();
+    method public androidx.compose.material3.SelectableDates getSelectableDates();
+    method public Long? getSelectedDateMillis();
+    method public kotlin.ranges.IntRange getYearRange();
+    method public void setDisplayMode(int);
+    method public void setDisplayedMonthMillis(long);
+    method public void setSelectedDateMillis(Long?);
+    property public abstract int displayMode;
+    property public abstract long displayedMonthMillis;
+    property public abstract androidx.compose.material3.SelectableDates selectableDates;
+    property public abstract Long? selectedDateMillis;
+    property public abstract kotlin.ranges.IntRange yearRange;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DateRangePickerDefaults {
+    method @androidx.compose.runtime.Composable public void DateRangePickerHeadline(Long? selectedStartDateMillis, Long? selectedEndDateMillis, int displayMode, androidx.compose.material3.DatePickerFormatter dateFormatter, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public void DateRangePickerTitle(int displayMode, optional androidx.compose.ui.Modifier modifier);
+    field public static final androidx.compose.material3.DateRangePickerDefaults INSTANCE;
+  }
+
+  public final class DateRangePickerKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DateRangePicker(androidx.compose.material3.DateRangePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DatePickerFormatter dateFormatter, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? headline, optional boolean showModeToggle, optional androidx.compose.material3.DatePickerColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.DateRangePickerState DateRangePickerState(java.util.Locale locale, optional Long? initialSelectedStartDateMillis, optional Long? initialSelectedEndDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DateRangePickerState rememberDateRangePickerState(optional Long? initialSelectedStartDateMillis, optional Long? initialSelectedEndDateMillis, optional Long? initialDisplayedMonthMillis, optional kotlin.ranges.IntRange yearRange, optional int initialDisplayMode, optional androidx.compose.material3.SelectableDates selectableDates);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface DateRangePickerState {
+    method public int getDisplayMode();
+    method public long getDisplayedMonthMillis();
+    method public androidx.compose.material3.SelectableDates getSelectableDates();
+    method public Long? getSelectedEndDateMillis();
+    method public Long? getSelectedStartDateMillis();
+    method public kotlin.ranges.IntRange getYearRange();
+    method public void setDisplayMode(int);
+    method public void setDisplayedMonthMillis(long);
+    method public void setSelection(Long? startDateMillis, Long? endDateMillis);
+    property public abstract int displayMode;
+    property public abstract long displayedMonthMillis;
+    property public abstract androidx.compose.material3.SelectableDates selectableDates;
+    property public abstract Long? selectedEndDateMillis;
+    property public abstract Long? selectedStartDateMillis;
+    property public abstract kotlin.ranges.IntRange yearRange;
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
+    method @Deprecated public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissDirection[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection EndToStart;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection StartToEnd;
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
+    method @Deprecated public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissValue[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue Default;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToEnd;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToStart;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
+    field public static final androidx.compose.material3.DisplayMode.Companion Companion;
+  }
+
+  public static final class DisplayMode.Companion {
+    method public int getInput();
+    method public int getPicker();
+    property public final int Input;
+    property public final int Picker;
+  }
+
+  public final class DividerDefaults {
+    method @androidx.compose.runtime.Composable public long getColor();
+    method public float getThickness();
+    property public final float Thickness;
+    property @androidx.compose.runtime.Composable public final long color;
+    field public static final androidx.compose.material3.DividerDefaults INSTANCE;
+  }
+
+  public final class DividerKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void Divider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+    method @androidx.compose.runtime.Composable public static void HorizontalDivider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+    method @androidx.compose.runtime.Composable public static void VerticalDivider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+  }
+
+  public final class DrawerDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getDismissibleDrawerElevation();
+    method public float getMaximumDrawerWidth();
+    method public float getModalDrawerElevation();
+    method public float getPermanentDrawerElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float DismissibleDrawerElevation;
+    property public final float MaximumDrawerWidth;
+    property public final float ModalDrawerElevation;
+    property public final float PermanentDrawerElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.DrawerDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class DrawerState {
+    ctor public DrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+    method @Deprecated public suspend Object? animateTo(androidx.compose.material3.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float getCurrentOffset();
+    method public androidx.compose.material3.DrawerValue getCurrentValue();
+    method @Deprecated public androidx.compose.runtime.State<java.lang.Float> getOffset();
+    method public androidx.compose.material3.DrawerValue getTargetValue();
+    method public boolean isAnimationRunning();
+    method public boolean isClosed();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.DrawerValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final float currentOffset;
+    property public final androidx.compose.material3.DrawerValue currentValue;
+    property public final boolean isAnimationRunning;
+    property public final boolean isClosed;
+    property public final boolean isOpen;
+    property @Deprecated public final androidx.compose.runtime.State<java.lang.Float> offset;
+    property public final androidx.compose.material3.DrawerValue targetValue;
+    field public static final androidx.compose.material3.DrawerState.Companion Companion;
+  }
+
+  public static final class DrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DrawerState,androidx.compose.material3.DrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DrawerValue {
+    method public static androidx.compose.material3.DrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.DrawerValue[] values();
+    enum_constant public static final androidx.compose.material3.DrawerValue Closed;
+    enum_constant public static final androidx.compose.material3.DrawerValue Open;
+  }
+
+  public final class DynamicTonalPaletteKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicDarkColorScheme(android.content.Context context);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public static androidx.compose.material3.ColorScheme dynamicLightColorScheme(android.content.Context context);
+  }
+
+  @SuppressCompatibility @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3Api {
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface ExposedDropdownMenuBoxScope {
+    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
+    method public androidx.compose.ui.Modifier menuAnchor(androidx.compose.ui.Modifier);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class ExposedDropdownMenuDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded);
+    method public androidx.compose.foundation.layout.PaddingValues getItemContentPadding();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ItemContentPadding;
+    field public static final androidx.compose.material3.ExposedDropdownMenuDefaults INSTANCE;
+  }
+
+  public final class ExposedDropdownMenu_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FabPosition {
+    field public static final androidx.compose.material3.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    method public int getEndOverlay();
+    method public int getStart();
+    property public final int Center;
+    property public final int End;
+    property public final int EndOverlay;
+    property public final int Start;
+  }
+
+  public final class FilterChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors elevatedFilterChipColors(optional long containerColor, optional long labelColor, optional long iconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation elevatedFilterChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke filterChipBorder(boolean enabled, boolean selected, optional long borderColor, optional long selectedBorderColor, optional long disabledBorderColor, optional long disabledSelectedBorderColor, optional float borderWidth, optional float selectedBorderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors filterChipColors(optional long containerColor, optional long labelColor, optional long iconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation filterChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.FilterChipDefaults INSTANCE;
+  }
+
+  public final class FloatingActionButtonDefaults {
+    method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
+    method public float getLargeIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getLargeShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getSmallShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation loweredElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
+    property public final float LargeIconSize;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape extendedFabShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape largeShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape smallShape;
+    field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
+  }
+
+  public final class FloatingActionButtonKt {
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconButtonColors {
+    ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class IconButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors filledTonalIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors filledTonalIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors iconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors iconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedIconButtonBorder(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconButtonColors outlinedIconButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke? outlinedIconToggleButtonBorder(boolean enabled, boolean checked);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.IconToggleButtonColors outlinedIconToggleButtonColors(optional long containerColor, optional long contentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long checkedContainerColor, optional long checkedContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    field public static final androidx.compose.material3.IconButtonDefaults INSTANCE;
+  }
+
+  public final class IconButtonKt {
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class IconKt {
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+    ctor public IconToggleButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor, long checkedContainerColor, long checkedContentColor);
+    method public long getCheckedContainerColor();
+    method public long getCheckedContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long checkedContainerColor;
+    property public final long checkedContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
+  }
+
+  public final class InputChipDefaults {
+    method public float getAvatarSize();
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke inputChipBorder(boolean enabled, boolean selected, optional long borderColor, optional long selectedBorderColor, optional long disabledBorderColor, optional long disabledSelectedBorderColor, optional float borderWidth, optional float selectedBorderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipColors inputChipColors(optional long containerColor, optional long labelColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor, optional long selectedContainerColor, optional long disabledSelectedContainerColor, optional long selectedLabelColor, optional long selectedLeadingIconColor, optional long selectedTrailingIconColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SelectableChipElevation inputChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float AvatarSize;
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.InputChipDefaults INSTANCE;
+  }
+
+  public final class InteractiveComponentSizeKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
+    property @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
+    property @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+  }
+
+  public final class LabelKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Label(kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean isPersistent, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ListItemColors {
+    ctor public ListItemColors(long containerColor, long headlineColor, long leadingIconColor, long overlineColor, long supportingTextColor, long trailingIconColor, long disabledHeadlineColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getContainerColor();
+    method public long getDisabledHeadlineColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getHeadlineColor();
+    method public long getLeadingIconColor();
+    method public long getOverlineColor();
+    method public long getSupportingTextColor();
+    method public long getTrailingIconColor();
+    property public final long containerColor;
+    property public final long disabledHeadlineColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTrailingIconColor;
+    property public final long headlineColor;
+    property public final long leadingIconColor;
+    property public final long overlineColor;
+    property public final long supportingTextColor;
+    property public final long trailingIconColor;
+  }
+
+  public final class ListItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ListItemColors colors(optional long containerColor, optional long headlineColor, optional long leadingIconColor, optional long overlineColor, optional long supportingColor, optional long trailingIconColor, optional long disabledHeadlineColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContainerColor();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContentColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getShape();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long containerColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long contentColor;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.ListItemDefaults INSTANCE;
+  }
+
+  public final class ListItemKt {
+    method @androidx.compose.runtime.Composable public static void ListItem(kotlin.jvm.functions.Function0<kotlin.Unit> headlineContent, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingContent, optional androidx.compose.material3.ListItemColors colors, optional float tonalElevation, optional float shadowElevation);
+  }
+
+  public final class MaterialTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.ColorScheme getColorScheme();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Shapes getShapes();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material3.Typography getTypography();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.ColorScheme colorScheme;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Shapes shapes;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material3.Typography typography;
+    field public static final androidx.compose.material3.MaterialTheme INSTANCE;
+  }
+
+  public final class MaterialThemeKt {
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material3.ColorScheme colorScheme, optional androidx.compose.material3.Shapes shapes, optional androidx.compose.material3.Typography typography, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class MenuDefaults {
+    method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
+    property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    field public static final androidx.compose.material3.MenuDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class MenuItemColors {
+    ctor public MenuItemColors(long textColor, long leadingIconColor, long trailingIconColor, long disabledTextColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getLeadingIconColor();
+    method public long getTextColor();
+    method public long getTrailingIconColor();
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long leadingIconColor;
+    property public final long textColor;
+    property public final long trailingIconColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class ModalBottomSheetDefaults {
+    method public androidx.compose.material3.ModalBottomSheetProperties properties(optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean isFocusable, optional boolean shouldDismissOnBackPress);
+    field public static final androidx.compose.material3.ModalBottomSheetDefaults INSTANCE;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class ModalBottomSheetProperties {
+    ctor public ModalBottomSheetProperties(androidx.compose.ui.window.SecureFlagPolicy securePolicy, boolean isFocusable, boolean shouldDismissOnBackPress);
+    method public androidx.compose.ui.window.SecureFlagPolicy getSecurePolicy();
+    method public boolean getShouldDismissOnBackPress();
+    method public boolean isFocusable();
+    property public final boolean isFocusable;
+    property public final androidx.compose.ui.window.SecureFlagPolicy securePolicy;
+    property public final boolean shouldDismissOnBackPress;
+  }
+
+  public final class ModalBottomSheet_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ModalBottomSheet(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SheetState sheetState, optional float sheetMaxWidth, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional float tonalElevation, optional long scrimColor, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dragHandle, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.material3.ModalBottomSheetProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SheetState rememberModalBottomSheetState(optional boolean skipPartiallyExpanded, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface MultiChoiceSegmentedButtonRowScope extends androidx.compose.foundation.layout.RowScope {
+  }
+
+  public final class NavigationBarDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+    ctor public NavigationBarItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
+  }
+
+  public final class NavigationBarItemDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationBarItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    field public static final androidx.compose.material3.NavigationBarItemDefaults INSTANCE;
+  }
+
+  public final class NavigationBarKt {
+    method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> badgeColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
+  }
+
+  public final class NavigationDrawerItemDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationDrawerItemColors colors(optional long selectedContainerColor, optional long unselectedContainerColor, optional long selectedIconColor, optional long unselectedIconColor, optional long selectedTextColor, optional long unselectedTextColor, optional long selectedBadgeColor, optional long unselectedBadgeColor);
+    method public androidx.compose.foundation.layout.PaddingValues getItemPadding();
+    property public final androidx.compose.foundation.layout.PaddingValues ItemPadding;
+    field public static final androidx.compose.material3.NavigationDrawerItemDefaults INSTANCE;
+  }
+
+  public final class NavigationDrawerKt {
+    method @androidx.compose.runtime.Composable public static void DismissibleDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public final class NavigationRailDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    property @androidx.compose.runtime.Composable public final long ContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+    ctor public NavigationRailItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
+  }
+
+  public final class NavigationRailItemDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.NavigationRailItemColors colors(optional long selectedIconColor, optional long selectedTextColor, optional long indicatorColor, optional long unselectedIconColor, optional long unselectedTextColor, optional long disabledIconColor, optional long disabledTextColor);
+    field public static final androidx.compose.material3.NavigationRailItemDefaults INSTANCE;
+  }
+
+  public final class NavigationRailKt {
+    method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class OutlinedTextFieldDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void ContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void DecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors colors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method public androidx.compose.foundation.layout.PaddingValues contentPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method public float getFocusedBorderThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getUnfocusedBorderThickness();
+    property public final float FocusedBorderThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final float UnfocusedBorderThickness;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.OutlinedTextFieldDefaults INSTANCE;
+  }
+
+  public final class OutlinedTextFieldKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface PlainTooltipState extends androidx.compose.material3.BasicTooltipState {
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method @androidx.compose.runtime.Composable public long getCircularColor();
+    method public int getCircularDeterminateStrokeCap();
+    method public int getCircularIndeterminateStrokeCap();
+    method public float getCircularStrokeWidth();
+    method @androidx.compose.runtime.Composable public long getCircularTrackColor();
+    method @androidx.compose.runtime.Composable public long getLinearColor();
+    method public int getLinearStrokeCap();
+    method @androidx.compose.runtime.Composable public long getLinearTrackColor();
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getProgressAnimationSpec();
+    property public final int CircularDeterminateStrokeCap;
+    property public final int CircularIndeterminateStrokeCap;
+    property public final float CircularStrokeWidth;
+    property public final int LinearStrokeCap;
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> ProgressAnimationSpec;
+    property @androidx.compose.runtime.Composable public final long circularColor;
+    property @androidx.compose.runtime.Composable public final long circularTrackColor;
+    property @androidx.compose.runtime.Composable public final long linearColor;
+    property @androidx.compose.runtime.Composable public final long linearTrackColor;
+    field public static final androidx.compose.material3.ProgressIndicatorDefaults INSTANCE;
+  }
+
+  public final class ProgressIndicatorKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(kotlin.jvm.functions.Function0<java.lang.Float> progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(kotlin.jvm.functions.Function0<java.lang.Float> progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor, optional int strokeCap);
+  }
+
+  @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+    ctor public RadioButtonColors(long selectedColor, long unselectedColor, long disabledSelectedColor, long disabledUnselectedColor);
+    method public long getDisabledSelectedColor();
+    method public long getDisabledUnselectedColor();
+    method public long getSelectedColor();
+    method public long getUnselectedColor();
+    property public final long disabledSelectedColor;
+    property public final long disabledUnselectedColor;
+    property public final long selectedColor;
+    property public final long unselectedColor;
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RadioButtonColors colors(optional long selectedColor, optional long unselectedColor, optional long disabledSelectedColor, optional long disabledUnselectedColor);
+    field public static final androidx.compose.material3.RadioButtonDefaults INSTANCE;
+  }
+
+  public final class RadioButtonKt {
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RangeSliderState {
+    ctor public RangeSliderState(optional float activeRangeStart, optional float activeRangeEnd, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
+    method public float getActiveRangeEnd();
+    method public float getActiveRangeStart();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnValueChangeFinished();
+    method public int getSteps();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getValueRange();
+    method public void setActiveRangeEnd(float);
+    method public void setActiveRangeStart(float);
+    property public final float activeRangeEnd;
+    property public final float activeRangeStart;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished;
+    property public final int steps;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @androidx.compose.runtime.Stable public final class RichTooltipColors {
+    ctor public RichTooltipColors(long containerColor, long contentColor, long titleContentColor, long actionContentColor);
+    method public long getActionContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getTitleContentColor();
+    property public final long actionContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long titleContentColor;
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface RichTooltipState extends androidx.compose.material3.BasicTooltipState {
+  }
+
+  public final class ScaffoldDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getContentWindowInsets();
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets contentWindowInsets;
+    field public static final androidx.compose.material3.ScaffoldDefaults INSTANCE;
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, optional androidx.compose.foundation.layout.WindowInsets contentWindowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static boolean getScaffoldSubcomposeInMeasureFix();
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static void setScaffoldSubcomposeInMeasureFix(boolean);
+    property @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static final boolean ScaffoldSubcomposeInMeasureFix;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SearchBarColors {
+    method public long getContainerColor();
+    method public long getDividerColor();
+    method public androidx.compose.material3.TextFieldColors getInputFieldColors();
+    property public final long containerColor;
+    property public final long dividerColor;
+    property public final androidx.compose.material3.TextFieldColors inputFieldColors;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SearchBarDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SearchBarColors colors(optional long containerColor, optional long dividerColor, optional androidx.compose.material3.TextFieldColors inputFieldColors);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getDockedShape();
+    method @Deprecated public float getElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFullScreenShape();
+    method public float getInputFieldHeight();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getInputFieldShape();
+    method public float getShadowElevation();
+    method public float getTonalElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors inputFieldColors(optional long textColor, optional long disabledTextColor, optional long cursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors inputFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long cursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor);
+    property @Deprecated public final float Elevation;
+    property public final float InputFieldHeight;
+    property public final float ShadowElevation;
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape dockedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape fullScreenShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape inputFieldShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.SearchBarDefaults INSTANCE;
+  }
+
+  public final class SearchBar_androidKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SegmentedButtonColors {
+    ctor public SegmentedButtonColors(long activeContainerColor, long activeContentColor, long activeBorderColor, long inactiveContainerColor, long inactiveContentColor, long inactiveBorderColor, long disabledActiveContainerColor, long disabledActiveContentColor, long disabledActiveBorderColor, long disabledInactiveContainerColor, long disabledInactiveContentColor, long disabledInactiveBorderColor);
+    method public long getActiveBorderColor();
+    method public long getActiveContainerColor();
+    method public long getActiveContentColor();
+    method public long getDisabledActiveBorderColor();
+    method public long getDisabledActiveContainerColor();
+    method public long getDisabledActiveContentColor();
+    method public long getDisabledInactiveBorderColor();
+    method public long getDisabledInactiveContainerColor();
+    method public long getDisabledInactiveContentColor();
+    method public long getInactiveBorderColor();
+    method public long getInactiveContainerColor();
+    method public long getInactiveContentColor();
+    property public final long activeBorderColor;
+    property public final long activeContainerColor;
+    property public final long activeContentColor;
+    property public final long disabledActiveBorderColor;
+    property public final long disabledActiveContainerColor;
+    property public final long disabledActiveContentColor;
+    property public final long disabledInactiveBorderColor;
+    property public final long disabledInactiveContainerColor;
+    property public final long disabledInactiveContentColor;
+    property public final long inactiveBorderColor;
+    property public final long inactiveContainerColor;
+    property public final long inactiveContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SegmentedButtonDefaults {
+    method @androidx.compose.runtime.Composable public void ActiveIcon();
+    method @androidx.compose.runtime.Composable public void Icon(boolean active, optional kotlin.jvm.functions.Function0<kotlin.Unit> activeContent, optional kotlin.jvm.functions.Function0<kotlin.Unit>? inactiveContent);
+    method public androidx.compose.foundation.BorderStroke borderStroke(long color, optional float width);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SegmentedButtonColors colors(optional long activeContainerColor, optional long activeContentColor, optional long activeBorderColor, optional long inactiveContainerColor, optional long inactiveContentColor, optional long inactiveBorderColor, optional long disabledActiveContainerColor, optional long disabledActiveContentColor, optional long disabledActiveBorderColor, optional long disabledInactiveContainerColor, optional long disabledInactiveContentColor, optional long disabledInactiveBorderColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.foundation.shape.CornerBasedShape getBaseShape();
+    method public float getBorderWidth();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape itemShape(int index, int count, optional androidx.compose.foundation.shape.CornerBasedShape baseShape);
+    property public final float BorderWidth;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.foundation.shape.CornerBasedShape baseShape;
+    field public static final androidx.compose.material3.SegmentedButtonDefaults INSTANCE;
+  }
+
+  public final class SegmentedButtonKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MultiChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.MultiChoiceSegmentedButtonRowScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.MultiChoiceSegmentedButtonRowScope, boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.SingleChoiceSegmentedButtonRowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SingleChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SingleChoiceSegmentedButtonRowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class SelectableChipColors {
+    ctor public SelectableChipColors(long containerColor, long labelColor, long leadingIconColor, long trailingIconColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconColor, long disabledTrailingIconColor, long selectedContainerColor, long disabledSelectedContainerColor, long selectedLabelColor, long selectedLeadingIconColor, long selectedTrailingIconColor);
+  }
+
+  @androidx.compose.runtime.Immutable public final class SelectableChipElevation {
+    ctor public SelectableChipElevation(float elevation, float pressedElevation, float focusedElevation, float hoveredElevation, float draggedElevation, float disabledElevation);
+    method public float getDisabledElevation();
+    method public float getDraggedElevation();
+    method public float getElevation();
+    method public float getFocusedElevation();
+    method public float getHoveredElevation();
+    method public float getPressedElevation();
+    property public final float disabledElevation;
+    property public final float draggedElevation;
+    property public final float elevation;
+    property public final float focusedElevation;
+    property public final float hoveredElevation;
+    property public final float pressedElevation;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableDates {
+    method public default boolean isSelectableDate(long utcTimeMillis);
+    method public default boolean isSelectableYear(int year);
+  }
+
+  public final class ShapeDefaults {
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape ExtraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape Small;
+    field public static final androidx.compose.material3.ShapeDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shapes {
+    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.material3.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape extraSmall, optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large, optional androidx.compose.foundation.shape.CornerBasedShape extraLarge);
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getExtraSmall();
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraLarge;
+    property public final androidx.compose.foundation.shape.CornerBasedShape extraSmall;
+    property public final androidx.compose.foundation.shape.CornerBasedShape large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape small;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SheetState {
+    ctor @Deprecated public SheetState(boolean skipPartiallyExpanded, optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+    ctor @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public SheetState(boolean skipPartiallyExpanded, androidx.compose.ui.unit.Density density, optional androidx.compose.material3.SheetValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHiddenState);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SheetValue getCurrentValue();
+    method public boolean getHasExpandedState();
+    method public boolean getHasPartiallyExpandedState();
+    method public androidx.compose.material3.SheetValue getTargetValue();
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean isVisible();
+    method public suspend Object? partialExpand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float requireOffset();
+    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SheetValue currentValue;
+    property public final boolean hasExpandedState;
+    property public final boolean hasPartiallyExpandedState;
+    property public final boolean isVisible;
+    property public final androidx.compose.material3.SheetValue targetValue;
+    field public static final androidx.compose.material3.SheetState.Companion Companion;
+  }
+
+  public static final class SheetState.Companion {
+    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SheetState,androidx.compose.material3.SheetValue> Saver(boolean skipPartiallyExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SheetState,androidx.compose.material3.SheetValue> Saver(boolean skipPartiallyExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SheetValue,java.lang.Boolean> confirmValueChange, androidx.compose.ui.unit.Density density);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SheetValue {
+    method public static androidx.compose.material3.SheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SheetValue[] values();
+    enum_constant public static final androidx.compose.material3.SheetValue Expanded;
+    enum_constant public static final androidx.compose.material3.SheetValue Hidden;
+    enum_constant public static final androidx.compose.material3.SheetValue PartiallyExpanded;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface SingleChoiceSegmentedButtonRowScope extends androidx.compose.foundation.layout.RowScope {
+  }
+
+  @androidx.compose.runtime.Immutable public final class SliderColors {
+    ctor public SliderColors(long thumbColor, long activeTrackColor, long activeTickColor, long inactiveTrackColor, long inactiveTickColor, long disabledThumbColor, long disabledActiveTrackColor, long disabledActiveTickColor, long disabledInactiveTrackColor, long disabledInactiveTickColor);
+    method public long getActiveTickColor();
+    method public long getActiveTrackColor();
+    method public long getDisabledActiveTickColor();
+    method public long getDisabledActiveTrackColor();
+    method public long getDisabledInactiveTickColor();
+    method public long getDisabledInactiveTrackColor();
+    method public long getDisabledThumbColor();
+    method public long getInactiveTickColor();
+    method public long getInactiveTrackColor();
+    method public long getThumbColor();
+    property public final long activeTickColor;
+    property public final long activeTrackColor;
+    property public final long disabledActiveTickColor;
+    property public final long disabledActiveTrackColor;
+    property public final long disabledInactiveTickColor;
+    property public final long disabledInactiveTrackColor;
+    property public final long disabledThumbColor;
+    property public final long inactiveTickColor;
+    property public final long inactiveTrackColor;
+    property public final long thumbColor;
+  }
+
+  @androidx.compose.runtime.Stable public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.RangeSliderState rangeSliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @Deprecated @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderState sliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
+    field public static final androidx.compose.material3.SliderDefaults INSTANCE;
+  }
+
+  public final class SliderKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(androidx.compose.material3.RangeSliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track);
+    method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track, optional @IntRange(from=0L) int steps);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(androidx.compose.material3.SliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  @Deprecated @androidx.compose.runtime.Stable public final class SliderPositions {
+    ctor @Deprecated public SliderPositions(optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> initialActiveRange, optional float[] initialTickFractions);
+    method @Deprecated public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getActiveRange();
+    method @Deprecated public float[] getTickFractions();
+    property @Deprecated public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> activeRange;
+    property @Deprecated public final float[] tickFractions;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class SliderState implements androidx.compose.foundation.gestures.DraggableState {
+    ctor public SliderState(optional float value, optional @IntRange(from=0L) int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
+    method public void dispatchRawDelta(float delta);
+    method public suspend Object? drag(androidx.compose.foundation.MutatePriority dragPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.DragScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnValueChangeFinished();
+    method public int getSteps();
+    method public float getValue();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getValueRange();
+    method public void setValue(float);
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished;
+    property public final int steps;
+    property public final float value;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarData {
+    method public void dismiss();
+    method public androidx.compose.material3.SnackbarVisuals getVisuals();
+    method public void performAction();
+    property public abstract androidx.compose.material3.SnackbarVisuals visuals;
+  }
+
+  public final class SnackbarDefaults {
+    method @androidx.compose.runtime.Composable public long getActionColor();
+    method @androidx.compose.runtime.Composable public long getActionContentColor();
+    method @androidx.compose.runtime.Composable public long getColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getDismissActionContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    property @androidx.compose.runtime.Composable public final long actionColor;
+    property @androidx.compose.runtime.Composable public final long actionContentColor;
+    property @androidx.compose.runtime.Composable public final long color;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long dismissActionContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SnackbarDefaults INSTANCE;
+  }
+
+  public enum SnackbarDuration {
+    method public static androidx.compose.material3.SnackbarDuration valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarDuration[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Indefinite;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Long;
+    enum_constant public static final androidx.compose.material3.SnackbarDuration Short;
+  }
+
+  public final class SnackbarHostKt {
+    method @androidx.compose.runtime.Composable public static void SnackbarHost(androidx.compose.material3.SnackbarHostState hostState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SnackbarData,kotlin.Unit> snackbar);
+  }
+
+  @androidx.compose.runtime.Stable public final class SnackbarHostState {
+    ctor public SnackbarHostState();
+    method public androidx.compose.material3.SnackbarData? getCurrentSnackbarData();
+    method public suspend Object? showSnackbar(androidx.compose.material3.SnackbarVisuals visuals, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    method public suspend Object? showSnackbar(String message, optional String? actionLabel, optional boolean withDismissAction, optional androidx.compose.material3.SnackbarDuration duration, kotlin.coroutines.Continuation<? super androidx.compose.material3.SnackbarResult>);
+    property public final androidx.compose.material3.SnackbarData? currentSnackbarData;
+  }
+
+  public final class SnackbarKt {
+    method @androidx.compose.runtime.Composable public static void Snackbar(androidx.compose.material3.SnackbarData snackbarData, optional androidx.compose.ui.Modifier modifier, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionColor, optional long actionContentColor, optional long dismissActionContentColor);
+    method @androidx.compose.runtime.Composable public static void Snackbar(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissAction, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional long actionContentColor, optional long dismissActionContentColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public enum SnackbarResult {
+    method public static androidx.compose.material3.SnackbarResult valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SnackbarResult[] values();
+    enum_constant public static final androidx.compose.material3.SnackbarResult ActionPerformed;
+    enum_constant public static final androidx.compose.material3.SnackbarResult Dismissed;
+  }
+
+  @androidx.compose.runtime.Stable public interface SnackbarVisuals {
+    method public String? getActionLabel();
+    method public androidx.compose.material3.SnackbarDuration getDuration();
+    method public String getMessage();
+    method public boolean getWithDismissAction();
+    property public abstract String? actionLabel;
+    property public abstract androidx.compose.material3.SnackbarDuration duration;
+    property public abstract String message;
+    property public abstract boolean withDismissAction;
+  }
+
+  public final class SuggestionChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors elevatedSuggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation elevatedSuggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    method public float getHeight();
+    method public float getIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke suggestionChipBorder(boolean enabled, optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.ChipBorder suggestionChipBorder(optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipColors suggestionChipColors(optional long containerColor, optional long labelColor, optional long iconContentColor, optional long disabledContainerColor, optional long disabledLabelColor, optional long disabledIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.ChipElevation suggestionChipElevation(optional float elevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation, optional float draggedElevation, optional float disabledElevation);
+    property public final float Height;
+    property public final float IconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.SuggestionChipDefaults INSTANCE;
+  }
+
+  public final class SurfaceKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxDefaults {
+    method @androidx.compose.runtime.Composable public kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> getPositionalThreshold();
+    property @androidx.compose.runtime.Composable public final kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> positionalThreshold;
+    field public static final androidx.compose.material3.SwipeToDismissBoxDefaults INSTANCE;
+  }
+
+  public final class SwipeToDismissBoxKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.SwipeToDismissValue> directions);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState {
+    ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SwipeToDismissValue getCurrentValue();
+    method public androidx.compose.material3.SwipeToDismissValue getDismissDirection();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public androidx.compose.material3.SwipeToDismissValue getTargetValue();
+    method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
+    method public float requireOffset();
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SwipeToDismissValue currentValue;
+    property public final androidx.compose.material3.SwipeToDismissValue dismissDirection;
+    property @FloatRange(from=0.0, to=1.0) public final float progress;
+    property public final androidx.compose.material3.SwipeToDismissValue targetValue;
+    field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion;
+  }
+
+  public static final class SwipeToDismissState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SwipeToDismissState,androidx.compose.material3.SwipeToDismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue {
+    method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SwipeToDismissValue[] values();
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SwitchColors {
+    ctor public SwitchColors(long checkedThumbColor, long checkedTrackColor, long checkedBorderColor, long checkedIconColor, long uncheckedThumbColor, long uncheckedTrackColor, long uncheckedBorderColor, long uncheckedIconColor, long disabledCheckedThumbColor, long disabledCheckedTrackColor, long disabledCheckedBorderColor, long disabledCheckedIconColor, long disabledUncheckedThumbColor, long disabledUncheckedTrackColor, long disabledUncheckedBorderColor, long disabledUncheckedIconColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedIconColor();
+    method public long getCheckedThumbColor();
+    method public long getCheckedTrackColor();
+    method public long getDisabledCheckedBorderColor();
+    method public long getDisabledCheckedIconColor();
+    method public long getDisabledCheckedThumbColor();
+    method public long getDisabledCheckedTrackColor();
+    method public long getDisabledUncheckedBorderColor();
+    method public long getDisabledUncheckedIconColor();
+    method public long getDisabledUncheckedThumbColor();
+    method public long getDisabledUncheckedTrackColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedIconColor();
+    method public long getUncheckedThumbColor();
+    method public long getUncheckedTrackColor();
+    property public final long checkedBorderColor;
+    property public final long checkedIconColor;
+    property public final long checkedThumbColor;
+    property public final long checkedTrackColor;
+    property public final long disabledCheckedBorderColor;
+    property public final long disabledCheckedIconColor;
+    property public final long disabledCheckedThumbColor;
+    property public final long disabledCheckedTrackColor;
+    property public final long disabledUncheckedBorderColor;
+    property public final long disabledUncheckedIconColor;
+    property public final long disabledUncheckedThumbColor;
+    property public final long disabledUncheckedTrackColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedIconColor;
+    property public final long uncheckedThumbColor;
+    property public final long uncheckedTrackColor;
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.SwitchColors colors(optional long checkedThumbColor, optional long checkedTrackColor, optional long checkedBorderColor, optional long checkedIconColor, optional long uncheckedThumbColor, optional long uncheckedTrackColor, optional long uncheckedBorderColor, optional long uncheckedIconColor, optional long disabledCheckedThumbColor, optional long disabledCheckedTrackColor, optional long disabledCheckedBorderColor, optional long disabledCheckedIconColor, optional long disabledUncheckedThumbColor, optional long disabledUncheckedTrackColor, optional long disabledUncheckedBorderColor, optional long disabledUncheckedIconColor);
+    method public float getIconSize();
+    property public final float IconSize;
+    field public static final androidx.compose.material3.SwitchDefaults INSTANCE;
+  }
+
+  public final class SwitchKt {
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+  }
+
+  public interface TabIndicatorScope {
+    method public androidx.compose.ui.Modifier tabIndicatorLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super java.util.List<androidx.compose.material3.TabPosition>,? extends androidx.compose.ui.layout.MeasureResult> measure);
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, int selectedTabIndex, optional boolean matchContentSize);
+  }
+
+  public final class TabKt {
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TabPosition {
+    method public float getContentWidth();
+    method public float getLeft();
+    method public float getRight();
+    method public float getWidth();
+    property public final float contentWidth;
+    property public final float left;
+    property public final float right;
+    property public final float width;
+  }
+
+  public final class TabRowDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @androidx.compose.runtime.Composable public void PrimaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional long color, optional androidx.compose.ui.graphics.Shape shape);
+    method @androidx.compose.runtime.Composable public void SecondaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method @Deprecated @androidx.compose.runtime.Composable public long getContainerColor();
+    method @Deprecated @androidx.compose.runtime.Composable public long getContentColor();
+    method @androidx.compose.runtime.Composable public long getPrimaryContainerColor();
+    method @androidx.compose.runtime.Composable public long getPrimaryContentColor();
+    method public float getScrollableTabRowEdgeStartPadding();
+    method @androidx.compose.runtime.Composable public long getSecondaryContainerColor();
+    method @androidx.compose.runtime.Composable public long getSecondaryContentColor();
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
+    property public final float ScrollableTabRowEdgeStartPadding;
+    property @Deprecated @androidx.compose.runtime.Composable public final long containerColor;
+    property @Deprecated @androidx.compose.runtime.Composable public final long contentColor;
+    property @androidx.compose.runtime.Composable public final long primaryContainerColor;
+    property @androidx.compose.runtime.Composable public final long primaryContentColor;
+    property @androidx.compose.runtime.Composable public final long secondaryContainerColor;
+    property @androidx.compose.runtime.Composable public final long secondaryContentColor;
+    field public static final androidx.compose.material3.TabRowDefaults INSTANCE;
+  }
+
+  public final class TabRowKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldColors {
+    ctor public TextFieldColors(long focusedTextColor, long unfocusedTextColor, long disabledTextColor, long errorTextColor, long focusedContainerColor, long unfocusedContainerColor, long disabledContainerColor, long errorContainerColor, long cursorColor, long errorCursorColor, androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors, long focusedIndicatorColor, long unfocusedIndicatorColor, long disabledIndicatorColor, long errorIndicatorColor, long focusedLeadingIconColor, long unfocusedLeadingIconColor, long disabledLeadingIconColor, long errorLeadingIconColor, long focusedTrailingIconColor, long unfocusedTrailingIconColor, long disabledTrailingIconColor, long errorTrailingIconColor, long focusedLabelColor, long unfocusedLabelColor, long disabledLabelColor, long errorLabelColor, long focusedPlaceholderColor, long unfocusedPlaceholderColor, long disabledPlaceholderColor, long errorPlaceholderColor, long focusedSupportingTextColor, long unfocusedSupportingTextColor, long disabledSupportingTextColor, long errorSupportingTextColor, long focusedPrefixColor, long unfocusedPrefixColor, long disabledPrefixColor, long errorPrefixColor, long focusedSuffixColor, long unfocusedSuffixColor, long disabledSuffixColor, long errorSuffixColor);
+    method public long getCursorColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledIndicatorColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledPlaceholderColor();
+    method public long getDisabledPrefixColor();
+    method public long getDisabledSuffixColor();
+    method public long getDisabledSupportingTextColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getErrorContainerColor();
+    method public long getErrorCursorColor();
+    method public long getErrorIndicatorColor();
+    method public long getErrorLabelColor();
+    method public long getErrorLeadingIconColor();
+    method public long getErrorPlaceholderColor();
+    method public long getErrorPrefixColor();
+    method public long getErrorSuffixColor();
+    method public long getErrorSupportingTextColor();
+    method public long getErrorTextColor();
+    method public long getErrorTrailingIconColor();
+    method public long getFocusedContainerColor();
+    method public long getFocusedIndicatorColor();
+    method public long getFocusedLabelColor();
+    method public long getFocusedLeadingIconColor();
+    method public long getFocusedPlaceholderColor();
+    method public long getFocusedPrefixColor();
+    method public long getFocusedSuffixColor();
+    method public long getFocusedSupportingTextColor();
+    method public long getFocusedTextColor();
+    method public long getFocusedTrailingIconColor();
+    method public androidx.compose.foundation.text.selection.TextSelectionColors getTextSelectionColors();
+    method public long getUnfocusedContainerColor();
+    method public long getUnfocusedIndicatorColor();
+    method public long getUnfocusedLabelColor();
+    method public long getUnfocusedLeadingIconColor();
+    method public long getUnfocusedPlaceholderColor();
+    method public long getUnfocusedPrefixColor();
+    method public long getUnfocusedSuffixColor();
+    method public long getUnfocusedSupportingTextColor();
+    method public long getUnfocusedTextColor();
+    method public long getUnfocusedTrailingIconColor();
+    property public final long cursorColor;
+    property public final long disabledContainerColor;
+    property public final long disabledIndicatorColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledPlaceholderColor;
+    property public final long disabledPrefixColor;
+    property public final long disabledSuffixColor;
+    property public final long disabledSupportingTextColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long errorContainerColor;
+    property public final long errorCursorColor;
+    property public final long errorIndicatorColor;
+    property public final long errorLabelColor;
+    property public final long errorLeadingIconColor;
+    property public final long errorPlaceholderColor;
+    property public final long errorPrefixColor;
+    property public final long errorSuffixColor;
+    property public final long errorSupportingTextColor;
+    property public final long errorTextColor;
+    property public final long errorTrailingIconColor;
+    property public final long focusedContainerColor;
+    property public final long focusedIndicatorColor;
+    property public final long focusedLabelColor;
+    property public final long focusedLeadingIconColor;
+    property public final long focusedPlaceholderColor;
+    property public final long focusedPrefixColor;
+    property public final long focusedSuffixColor;
+    property public final long focusedSupportingTextColor;
+    property public final long focusedTextColor;
+    property public final long focusedTrailingIconColor;
+    property public final androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors;
+    property public final long unfocusedContainerColor;
+    property public final long unfocusedIndicatorColor;
+    property public final long unfocusedLabelColor;
+    property public final long unfocusedLeadingIconColor;
+    property public final long unfocusedPlaceholderColor;
+    property public final long unfocusedPrefixColor;
+    property public final long unfocusedSuffixColor;
+    property public final long unfocusedSupportingTextColor;
+    property public final long unfocusedTextColor;
+    property public final long unfocusedTrailingIconColor;
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void ContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void DecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void FilledContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedBorderContainerBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> container);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors colors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long focusedContainerColor, optional long unfocusedContainerColor, optional long disabledContainerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method public androidx.compose.foundation.layout.PaddingValues contentPaddingWithLabel(optional float start, optional float end, optional float top, optional float bottom);
+    method public androidx.compose.foundation.layout.PaddingValues contentPaddingWithoutLabel(optional float start, optional float top, optional float end, optional float bottom);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFilledShape();
+    method @Deprecated public float getFocusedBorderThickness();
+    method public float getFocusedIndicatorThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getOutlinedShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method @Deprecated public float getUnfocusedBorderThickness();
+    method public float getUnfocusedIndicatorThickness();
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public androidx.compose.ui.Modifier indicatorLine(androidx.compose.ui.Modifier, boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material3.TextFieldColors colors, optional float focusedIndicatorLineThickness, optional float unfocusedIndicatorLineThickness);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long containerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long focusedTextColor, optional long unfocusedTextColor, optional long disabledTextColor, optional long errorTextColor, optional long containerColor, optional long errorContainerColor, optional long cursorColor, optional long errorCursorColor, optional androidx.compose.foundation.text.selection.TextSelectionColors selectionColors, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long focusedPlaceholderColor, optional long unfocusedPlaceholderColor, optional long disabledPlaceholderColor, optional long errorPlaceholderColor, optional long focusedSupportingTextColor, optional long unfocusedSupportingTextColor, optional long disabledSupportingTextColor, optional long errorSupportingTextColor, optional long focusedPrefixColor, optional long unfocusedPrefixColor, optional long disabledPrefixColor, optional long errorPrefixColor, optional long focusedSuffixColor, optional long unfocusedSuffixColor, optional long disabledSuffixColor, optional long errorSuffixColor);
+    method @Deprecated public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
+    method @Deprecated public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
+    property @Deprecated public final float FocusedBorderThickness;
+    property public final float FocusedIndicatorThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property @Deprecated public final float UnfocusedBorderThickness;
+    property public final float UnfocusedIndicatorThickness;
+    property @Deprecated @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape filledShape;
+    property @Deprecated @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape outlinedShape;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.TextFieldDefaults INSTANCE;
+  }
+
+  public final class TextFieldKt {
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void ProvideTextStyle(androidx.compose.ui.text.TextStyle value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> getLocalTextStyle();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class TimePickerColors {
+    ctor public TimePickerColors(long clockDialColor, long selectorColor, long containerColor, long periodSelectorBorderColor, long clockDialSelectedContentColor, long clockDialUnselectedContentColor, long periodSelectorSelectedContainerColor, long periodSelectorUnselectedContainerColor, long periodSelectorSelectedContentColor, long periodSelectorUnselectedContentColor, long timeSelectorSelectedContainerColor, long timeSelectorUnselectedContainerColor, long timeSelectorSelectedContentColor, long timeSelectorUnselectedContentColor);
+    method public long getClockDialColor();
+    method public long getClockDialSelectedContentColor();
+    method public long getClockDialUnselectedContentColor();
+    method public long getContainerColor();
+    method public long getPeriodSelectorBorderColor();
+    method public long getPeriodSelectorSelectedContainerColor();
+    method public long getPeriodSelectorSelectedContentColor();
+    method public long getPeriodSelectorUnselectedContainerColor();
+    method public long getPeriodSelectorUnselectedContentColor();
+    method public long getSelectorColor();
+    method public long getTimeSelectorSelectedContainerColor();
+    method public long getTimeSelectorSelectedContentColor();
+    method public long getTimeSelectorUnselectedContainerColor();
+    method public long getTimeSelectorUnselectedContentColor();
+    property public final long clockDialColor;
+    property public final long clockDialSelectedContentColor;
+    property public final long clockDialUnselectedContentColor;
+    property public final long containerColor;
+    property public final long periodSelectorBorderColor;
+    property public final long periodSelectorSelectedContainerColor;
+    property public final long periodSelectorSelectedContentColor;
+    property public final long periodSelectorUnselectedContainerColor;
+    property public final long periodSelectorUnselectedContentColor;
+    property public final long selectorColor;
+    property public final long timeSelectorSelectedContainerColor;
+    property public final long timeSelectorSelectedContentColor;
+    property public final long timeSelectorUnselectedContainerColor;
+    property public final long timeSelectorUnselectedContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TimePickerColors colors(optional long clockDialColor, optional long clockDialSelectedContentColor, optional long clockDialUnselectedContentColor, optional long selectorColor, optional long containerColor, optional long periodSelectorBorderColor, optional long periodSelectorSelectedContainerColor, optional long periodSelectorUnselectedContainerColor, optional long periodSelectorSelectedContentColor, optional long periodSelectorUnselectedContentColor, optional long timeSelectorSelectedContainerColor, optional long timeSelectorUnselectedContainerColor, optional long timeSelectorSelectedContentColor, optional long timeSelectorUnselectedContentColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public int layoutType();
+    field public static final androidx.compose.material3.TimePickerDefaults INSTANCE;
+  }
+
+  public final class TimePickerKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TimeInput(androidx.compose.material3.TimePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.TimePickerColors colors);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TimePicker(androidx.compose.material3.TimePickerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.TimePickerColors colors, optional int layoutType);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TimePickerState rememberTimePickerState(optional int initialHour, optional int initialMinute, optional boolean is24Hour);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TimePickerLayoutType {
+    field public static final androidx.compose.material3.TimePickerLayoutType.Companion Companion;
+  }
+
+  public static final class TimePickerLayoutType.Companion {
+    method public int getHorizontal();
+    method public int getVertical();
+    property public final int Horizontal;
+    property public final int Vertical;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerState {
+    ctor public TimePickerState(int initialHour, int initialMinute, boolean is24Hour);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24hour();
+    method public suspend Object? settle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final int hour;
+    property public final boolean is24hour;
+    property public final int minute;
+    field public static final androidx.compose.material3.TimePickerState.Companion Companion;
+  }
+
+  public static final class TimePickerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TimePickerState,?> Saver();
+  }
+
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface TooltipBoxScope {
+    method @Deprecated public androidx.compose.ui.Modifier tooltipTrigger(androidx.compose.ui.Modifier);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class TooltipDefaults {
+    method @androidx.compose.runtime.Composable public long getPlainTooltipContainerColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getPlainTooltipContainerShape();
+    method @androidx.compose.runtime.Composable public long getPlainTooltipContentColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getRichTooltipContainerShape();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.window.PopupPositionProvider rememberPlainTooltipPositionProvider(optional float spacingBetweenTooltipAndAnchor);
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.window.PopupPositionProvider rememberRichTooltipPositionProvider(optional float spacingBetweenTooltipAndAnchor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.RichTooltipColors richTooltipColors(optional long containerColor, optional long contentColor, optional long titleContentColor, optional long actionContentColor);
+    property @androidx.compose.runtime.Composable public final long plainTooltipContainerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape plainTooltipContainerShape;
+    property @androidx.compose.runtime.Composable public final long plainTooltipContentColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape richTooltipContainerShape;
+    field public static final androidx.compose.material3.TooltipDefaults INSTANCE;
+  }
+
+  public final class TooltipKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(optional androidx.compose.ui.Modifier modifier, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltipBox(kotlin.jvm.functions.Function0<kotlin.Unit> tooltip, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional androidx.compose.material3.PlainTooltipState tooltipState, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional float tonalElevation, optional float shadowElevation, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipBoxScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltipBox(kotlin.jvm.functions.Function0<kotlin.Unit> text, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional androidx.compose.material3.RichTooltipState tooltipState, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipBoxScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TooltipBox(androidx.compose.ui.window.PopupPositionProvider positionProvider, kotlin.jvm.functions.Function0<kotlin.Unit> tooltip, androidx.compose.material3.TooltipState state, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional boolean enableUserInput, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.TooltipState TooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.PlainTooltipState rememberPlainTooltipState(optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.RichTooltipState rememberRichTooltipState(boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TooltipState rememberTooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface TooltipState extends androidx.compose.material3.BasicTooltipState {
+    method public androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> getTransition();
+    property public abstract androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> transition;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
+    ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
+    method public long getActionIconContentColor();
+    method public long getContainerColor();
+    method public long getNavigationIconContentColor();
+    method public long getScrolledContainerColor();
+    method public long getTitleContentColor();
+    property public final long actionIconContentColor;
+    property public final long containerColor;
+    property public final long navigationIconContentColor;
+    property public final long scrolledContainerColor;
+    property public final long titleContentColor;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class TopAppBarDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors centerAlignedTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior enterAlwaysScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior exitUntilCollapsedScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors largeTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors mediumTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarScrollBehavior pinnedScrollBehavior(optional androidx.compose.material3.TopAppBarState state, optional kotlin.jvm.functions.Function0<java.lang.Boolean> canScroll);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors smallTopAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TopAppBarColors topAppBarColors(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+    field public static final androidx.compose.material3.TopAppBarDefaults INSTANCE;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface TopAppBarScrollBehavior {
+    method public androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? getFlingAnimationSpec();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float>? getSnapAnimationSpec();
+    method public androidx.compose.material3.TopAppBarState getState();
+    method public boolean isPinned();
+    property public abstract androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>? flingAnimationSpec;
+    property public abstract boolean isPinned;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract androidx.compose.animation.core.AnimationSpec<java.lang.Float>? snapAnimationSpec;
+    property public abstract androidx.compose.material3.TopAppBarState state;
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarState {
+    ctor public TopAppBarState(float initialHeightOffsetLimit, float initialHeightOffset, float initialContentOffset);
+    method public float getCollapsedFraction();
+    method public float getContentOffset();
+    method public float getHeightOffset();
+    method public float getHeightOffsetLimit();
+    method public float getOverlappedFraction();
+    method public void setContentOffset(float);
+    method public void setHeightOffset(float);
+    method public void setHeightOffsetLimit(float);
+    property public final float collapsedFraction;
+    property public final float contentOffset;
+    property public final float heightOffset;
+    property public final float heightOffsetLimit;
+    property public final float overlappedFraction;
+    field public static final androidx.compose.material3.TopAppBarState.Companion Companion;
+  }
+
+  public static final class TopAppBarState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.material3.TopAppBarState,?> Saver;
+  }
+
+  @androidx.compose.runtime.Immutable public final class Typography {
+    ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
+    method public androidx.compose.ui.text.TextStyle getBodyLarge();
+    method public androidx.compose.ui.text.TextStyle getBodyMedium();
+    method public androidx.compose.ui.text.TextStyle getBodySmall();
+    method public androidx.compose.ui.text.TextStyle getDisplayLarge();
+    method public androidx.compose.ui.text.TextStyle getDisplayMedium();
+    method public androidx.compose.ui.text.TextStyle getDisplaySmall();
+    method public androidx.compose.ui.text.TextStyle getHeadlineLarge();
+    method public androidx.compose.ui.text.TextStyle getHeadlineMedium();
+    method public androidx.compose.ui.text.TextStyle getHeadlineSmall();
+    method public androidx.compose.ui.text.TextStyle getLabelLarge();
+    method public androidx.compose.ui.text.TextStyle getLabelMedium();
+    method public androidx.compose.ui.text.TextStyle getLabelSmall();
+    method public androidx.compose.ui.text.TextStyle getTitleLarge();
+    method public androidx.compose.ui.text.TextStyle getTitleMedium();
+    method public androidx.compose.ui.text.TextStyle getTitleSmall();
+    property public final androidx.compose.ui.text.TextStyle bodyLarge;
+    property public final androidx.compose.ui.text.TextStyle bodyMedium;
+    property public final androidx.compose.ui.text.TextStyle bodySmall;
+    property public final androidx.compose.ui.text.TextStyle displayLarge;
+    property public final androidx.compose.ui.text.TextStyle displayMedium;
+    property public final androidx.compose.ui.text.TextStyle displaySmall;
+    property public final androidx.compose.ui.text.TextStyle headlineLarge;
+    property public final androidx.compose.ui.text.TextStyle headlineMedium;
+    property public final androidx.compose.ui.text.TextStyle headlineSmall;
+    property public final androidx.compose.ui.text.TextStyle labelLarge;
+    property public final androidx.compose.ui.text.TextStyle labelMedium;
+    property public final androidx.compose.ui.text.TextStyle labelSmall;
+    property public final androidx.compose.ui.text.TextStyle titleLarge;
+    property public final androidx.compose.ui.text.TextStyle titleMedium;
+    property public final androidx.compose.ui.text.TextStyle titleSmall;
+  }
+
+}
+
+package androidx.compose.material3.pulltorefresh {
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class PullToRefreshDefaults {
+    method @androidx.compose.runtime.Composable public void Indicator(androidx.compose.material3.pulltorefresh.PullToRefreshState state, optional androidx.compose.ui.Modifier modifier, optional long color);
+    method @androidx.compose.runtime.Composable public long getContainerColor();
+    method @androidx.compose.runtime.Composable public long getContentColor();
+    method public float getPositionalThreshold();
+    method public androidx.compose.ui.graphics.Shape getShape();
+    property public final float PositionalThreshold;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final long contentColor;
+    property public final androidx.compose.ui.graphics.Shape shape;
+    field public static final androidx.compose.material3.pulltorefresh.PullToRefreshDefaults INSTANCE;
+  }
+
+  public final class PullToRefreshKt {
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PullToRefreshContainer(androidx.compose.material3.pulltorefresh.PullToRefreshState state, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.pulltorefresh.PullToRefreshState,kotlin.Unit> indicator, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.pulltorefresh.PullToRefreshState PullToRefreshState(float positionalThresholdPx, optional boolean initialRefreshing, optional kotlin.jvm.functions.Function0<java.lang.Boolean> enabled);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.pulltorefresh.PullToRefreshState rememberPullToRefreshState(optional float positionalThreshold, optional kotlin.jvm.functions.Function0<java.lang.Boolean> enabled);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface PullToRefreshState {
+    method public void endRefresh();
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection getNestedScrollConnection();
+    method public float getPositionalThreshold();
+    method @FloatRange(from=0.0) public float getProgress();
+    method @FloatRange(from=0.0) public float getVerticalOffset();
+    method public boolean isRefreshing();
+    method public void setNestedScrollConnection(androidx.compose.ui.input.nestedscroll.NestedScrollConnection);
+    method public void startRefresh();
+    property public abstract boolean isRefreshing;
+    property public abstract androidx.compose.ui.input.nestedscroll.NestedScrollConnection nestedScrollConnection;
+    property public abstract float positionalThreshold;
+    property @FloatRange(from=0.0) public abstract float progress;
+    property @FloatRange(from=0.0) public abstract float verticalOffset;
+  }
+
+}
+
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index a623044..7ca2ade 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -597,43 +597,19 @@
     property public abstract kotlin.ranges.IntRange yearRange;
   }
 
-  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
-    method public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material3.DismissDirection[] values();
-    enum_constant public static final androidx.compose.material3.DismissDirection EndToStart;
-    enum_constant public static final androidx.compose.material3.DismissDirection StartToEnd;
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissDirection {
+    method @Deprecated public static androidx.compose.material3.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissDirection[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection EndToStart;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissDirection StartToEnd;
   }
 
-  public final class DismissState {
-    ctor public DismissState(androidx.compose.material3.DismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
-    ctor @Deprecated public DismissState(androidx.compose.material3.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
-    method public suspend Object? dismiss(androidx.compose.material3.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material3.DismissValue getCurrentValue();
-    method public androidx.compose.material3.DismissDirection? getDismissDirection();
-    method public float getProgress();
-    method public androidx.compose.material3.DismissValue getTargetValue();
-    method public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
-    method public float requireOffset();
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? snapTo(androidx.compose.material3.DismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material3.DismissValue currentValue;
-    property public final androidx.compose.material3.DismissDirection? dismissDirection;
-    property public final float progress;
-    property public final androidx.compose.material3.DismissValue targetValue;
-    field public static final androidx.compose.material3.DismissState.Companion Companion;
-  }
-
-  public static final class DismissState.Companion {
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DismissState,androidx.compose.material3.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.DismissState,androidx.compose.material3.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density);
-  }
-
-  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
-    method public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material3.DismissValue[] values();
-    enum_constant public static final androidx.compose.material3.DismissValue Default;
-    enum_constant public static final androidx.compose.material3.DismissValue DismissedToEnd;
-    enum_constant public static final androidx.compose.material3.DismissValue DismissedToStart;
+  @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum DismissValue {
+    method @Deprecated public static androidx.compose.material3.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method @Deprecated public static androidx.compose.material3.DismissValue[] values();
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue Default;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToEnd;
+    enum_constant @Deprecated public static final androidx.compose.material3.DismissValue DismissedToStart;
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DisplayMode {
@@ -1559,15 +1535,45 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxDefaults {
-    method @androidx.compose.runtime.Composable public kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> getFixedPositionalThreshold();
-    property @androidx.compose.runtime.Composable public final kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> fixedPositionalThreshold;
+    method @androidx.compose.runtime.Composable public kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> getPositionalThreshold();
+    property @androidx.compose.runtime.Composable public final kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Float> positionalThreshold;
     field public static final androidx.compose.material3.SwipeToDismissBoxDefaults INSTANCE;
   }
 
   public final class SwipeToDismissBoxKt {
-    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.DismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.DismissDirection> directions);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.DismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.DismissDirection> directions, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.DismissState rememberDismissState(optional androidx.compose.material3.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material3.SwipeToDismissValue> directions);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState {
+    ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold);
+    method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material3.SwipeToDismissValue getCurrentValue();
+    method public androidx.compose.material3.SwipeToDismissValue getDismissDirection();
+    method @FloatRange(from=0.0, to=1.0) public float getProgress();
+    method public androidx.compose.material3.SwipeToDismissValue getTargetValue();
+    method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction);
+    method public float requireOffset();
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material3.SwipeToDismissValue currentValue;
+    property public final androidx.compose.material3.SwipeToDismissValue dismissDirection;
+    property @FloatRange(from=0.0, to=1.0) public final float progress;
+    property public final androidx.compose.material3.SwipeToDismissValue targetValue;
+    field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion;
+  }
+
+  public static final class SwipeToDismissState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material3.SwipeToDismissState,androidx.compose.material3.SwipeToDismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density);
+  }
+
+  @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue {
+    method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material3.SwipeToDismissValue[] values();
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled;
+    enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd;
   }
 
   @androidx.compose.runtime.Immutable public final class SwitchColors {
@@ -1617,6 +1623,11 @@
     method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
   }
 
+  public interface TabIndicatorScope {
+    method public androidx.compose.ui.Modifier tabIndicatorLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super java.util.List<androidx.compose.material3.TabPosition>,? extends androidx.compose.ui.layout.MeasureResult> measure);
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, int selectedTabIndex, optional boolean matchContentSize);
+  }
+
   public final class TabKt {
     method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
     method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
@@ -1658,10 +1669,10 @@
 
   public final class TabRowKt {
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PrimaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
     method @androidx.compose.runtime.Composable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, optional long containerColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SecondaryTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.TabIndicatorScope,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
     method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
   }
 
diff --git a/compose/material3/material3/integration-tests/material3-catalog/build.gradle b/compose/material3/material3/integration-tests/material3-catalog/build.gradle
index 1313927..4d02722 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/build.gradle
+++ b/compose/material3/material3/integration-tests/material3-catalog/build.gradle
@@ -30,7 +30,7 @@
     implementation project(":compose:runtime:runtime")
     implementation project(":compose:foundation:foundation-layout")
     implementation project(":compose:ui:ui")
-    implementation project(":compose:material:material")
+    implementation("androidx.compose.material:material:1.6.0-beta01")
     implementation project(":compose:material:material-icons-extended")
     implementation project(":compose:material3:material3")
     implementation project(":compose:material3:material3:material3-samples")
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Components.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Components.kt
index 3c26f67..b49c3b3 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Components.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Components.kt
@@ -105,6 +105,18 @@
     examples = CardExamples
 )
 
+private val Carousel = Component(
+    id = nextId(),
+    name = "Carousel",
+    description = "Carousels are stylized versions of lists that provide a unique viewing and " +
+        "behavior that suit large imagery and other visually rich content.",
+    // No carousel icon
+    guidelinesUrl = "$StyleGuidelinesUrl/carousel",
+    docsUrl = "$PackageSummaryUrl#carousel",
+    sourceUrl = "$Material3SourceUrl/Carousel.kt",
+    examples = CarouselExamples
+)
+
 private val Checkboxes = Component(
     id = nextId(),
     name = "Checkboxes",
@@ -414,6 +426,7 @@
     BottomSheets,
     Buttons,
     Card,
+    Carousel,
     Checkboxes,
     Chips,
     DatePickers,
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
index 63dc67e..08cafdb 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
@@ -35,6 +35,7 @@
 import androidx.compose.material3.samples.ButtonSample
 import androidx.compose.material3.samples.ButtonWithIconSample
 import androidx.compose.material3.samples.CardSample
+import androidx.compose.material3.samples.CarouselSample
 import androidx.compose.material3.samples.CheckboxSample
 import androidx.compose.material3.samples.CheckboxWithTextSample
 import androidx.compose.material3.samples.ChipGroupReflowSample
@@ -286,6 +287,18 @@
     }
 )
 
+private const val CarouselExampleDescription = "Carousel examples"
+private const val CarouselExampleSourceUrl = "$SampleSourceUrl/CarouselSamples.kt"
+val CarouselExamples = listOf(
+    Example(
+        name = ::CarouselSample.name,
+        description = CarouselExampleDescription,
+        sourceUrl = CarouselExampleSourceUrl
+    ) {
+        CarouselSample()
+    }
+)
+
 private const val CheckboxesExampleDescription = "Checkboxes examples"
 private const val CheckboxesExampleSourceUrl = "$SampleSourceUrl/CheckboxSamples.kt"
 val CheckboxesExamples = listOf(
diff --git a/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt b/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt
index 6f691ed..f751e9f 100644
--- a/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt
+++ b/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt
@@ -16,10 +16,8 @@
 
 package androidx.compose.material3.demos
 
-import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.animateColorAsState
 import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.shrinkHorizontally
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
@@ -30,14 +28,13 @@
 import androidx.compose.material.icons.filled.Delete
 import androidx.compose.material.icons.filled.Done
 import androidx.compose.material3.Card
-import androidx.compose.material3.DismissDirection
-import androidx.compose.material3.DismissValue
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.Icon
 import androidx.compose.material3.ListItem
 import androidx.compose.material3.SwipeToDismissBox
+import androidx.compose.material3.SwipeToDismissValue
 import androidx.compose.material3.Text
-import androidx.compose.material3.rememberDismissState
+import androidx.compose.material3.rememberSwipeToDismissState
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -86,79 +83,75 @@
             var unread by remember { mutableStateOf(false) }
             val scope = rememberCoroutineScope()
 
-            val dismissState = rememberDismissState(
+            val dismissState = rememberSwipeToDismissState(
                 confirmValueChange = {
-                    if (it == DismissValue.DismissedToEnd) unread = !unread
-                    it != DismissValue.DismissedToEnd
+                    if (it == SwipeToDismissValue.StartToEnd) unread = !unread
+                    it != SwipeToDismissValue.StartToEnd
                 },
                 positionalThreshold = { distance -> distance * .25f }
             )
-            val isDismissed = dismissState.isDismissed(DismissDirection.EndToStart)
-            AnimatedVisibility(
-                visible = !isDismissed,
-                exit = shrinkHorizontally(shrinkTowards = Alignment.Start)
-            ) {
-                SwipeToDismissBox(
-                    state = dismissState,
-                    backgroundContent = {
-                        val direction = dismissState.dismissDirection ?: return@SwipeToDismissBox
-                        val color by animateColorAsState(
-                            when (dismissState.targetValue) {
-                                DismissValue.Default -> Color.LightGray
-                                DismissValue.DismissedToEnd -> Color.Green
-                                DismissValue.DismissedToStart -> Color.Red
-                            }
-                        )
-                        val alignment = when (direction) {
-                            DismissDirection.StartToEnd -> Alignment.CenterStart
-                            DismissDirection.EndToStart -> Alignment.CenterEnd
+            SwipeToDismissBox(
+                state = dismissState,
+                modifier = Modifier.padding(vertical = 4.dp),
+                backgroundContent = {
+                    val direction = dismissState.dismissDirection
+                    val color by animateColorAsState(
+                        when (dismissState.targetValue) {
+                            SwipeToDismissValue.Settled -> Color.LightGray
+                            SwipeToDismissValue.StartToEnd -> Color.Green
+                            SwipeToDismissValue.EndToStart -> Color.Red
                         }
-                        val icon = when (direction) {
-                            DismissDirection.StartToEnd -> Icons.Default.Done
-                            DismissDirection.EndToStart -> Icons.Default.Delete
-                        }
-                        val scale by animateFloatAsState(
-                            if (dismissState.targetValue == DismissValue.Default)
-                                0.75f else 1f
-                        )
-                        Box(
-                            Modifier
-                                .fillMaxSize()
-                                .background(color)
-                                .padding(horizontal = 20.dp),
-                            contentAlignment = alignment
-                        ) {
-                            Icon(
-                                icon,
-                                contentDescription = "Localized description",
-                                modifier = Modifier.scale(scale)
-                            )
-                        }
-                    },
-                    modifier = Modifier.padding(vertical = 4.dp)
-                ) {
-                    Card {
-                        ListItem(
-                            headlineContent = {
-                                Text(item, fontWeight = if (unread) FontWeight.Bold else null)
-                            },
-                            modifier = Modifier.semantics {
-                                // Provide accessible alternatives to swipe actions.
-                                val label = if (unread) "Mark Read" else "Mark Unread"
-                                customActions = listOf(
-                                    CustomAccessibilityAction(label) { unread = !unread; true },
-                                    CustomAccessibilityAction("Delete") {
-                                        scope.launch {
-                                            dismissState.dismiss(DismissDirection.EndToStart)
-                                        }
-                                        true
-                                    }
-                                )
-                            },
-                            supportingContent = { Text("Swipe me left or right!") },
+                    )
+                    val alignment = when (direction) {
+                        SwipeToDismissValue.StartToEnd,
+                        SwipeToDismissValue.Settled -> Alignment.CenterStart
+                        SwipeToDismissValue.EndToStart -> Alignment.CenterEnd
+                    }
+                    val icon = when (direction) {
+                        SwipeToDismissValue.StartToEnd,
+                        SwipeToDismissValue.Settled -> Icons.Default.Done
+                        SwipeToDismissValue.EndToStart -> Icons.Default.Delete
+                    }
+                    val scale by animateFloatAsState(
+                        if (dismissState.targetValue == SwipeToDismissValue.Settled)
+                            0.75f else 1f
+                    )
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .background(color)
+                            .padding(horizontal = 20.dp),
+                        contentAlignment = alignment
+                    ) {
+                        Icon(
+                            icon,
+                            contentDescription = "Localized description",
+                            modifier = Modifier.scale(scale)
                         )
                     }
                 }
+            ) {
+                Card {
+                    ListItem(
+                        headlineContent = {
+                            Text(item, fontWeight = if (unread) FontWeight.Bold else null)
+                        },
+                        modifier = Modifier.semantics {
+                            // Provide accessible alternatives to swipe actions.
+                            val label = if (unread) "Mark Read" else "Mark Unread"
+                            customActions = listOf(
+                                CustomAccessibilityAction(label) { unread = !unread; true },
+                                CustomAccessibilityAction("Delete") {
+                                    scope.launch {
+                                        dismissState.dismiss(SwipeToDismissValue.EndToStart)
+                                    }
+                                    true
+                                }
+                            )
+                        },
+                        supportingContent = { Text("Swipe me left or right!") },
+                    )
+                }
             }
         }
     }
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/CarouselSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/CarouselSamples.kt
new file mode 100644
index 0000000..a55a9bd
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/CarouselSamples.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.compose.material3.samples
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.material3.Card
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+
+@Preview
+@Composable
+fun CarouselSample() {
+    data class CarouselItem(
+        val id: Int,
+        @DrawableRes val imageResId: Int,
+        @StringRes val contentDescriptionResId: Int
+    )
+
+    val Items = listOf(
+        CarouselItem(0, R.drawable.carousel_image_1, R.string.carousel_image_1_description),
+        CarouselItem(1, R.drawable.carousel_image_2, R.string.carousel_image_2_description),
+        CarouselItem(2, R.drawable.carousel_image_3, R.string.carousel_image_3_description),
+        CarouselItem(3, R.drawable.carousel_image_4, R.string.carousel_image_4_description),
+        CarouselItem(4, R.drawable.carousel_image_5, R.string.carousel_image_5_description),
+    )
+
+    LazyRow(
+        modifier = Modifier.fillMaxWidth(),
+        state = rememberLazyListState()
+    ) {
+        itemsIndexed(Items) { _, item ->
+            Card(
+                modifier = Modifier
+                    .width(350.dp)
+                    .height(200.dp),
+            ) {
+                Image(
+                    painter = painterResource(id = item.imageResId),
+                    contentDescription = stringResource(item.contentDescriptionResId),
+                    modifier = Modifier.fillMaxSize(),
+                    contentScale = ContentScale.Crop
+                )
+            }
+        }
+    }
+}
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt
index 81d3b8e..b883b78 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt
@@ -22,15 +22,13 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material3.Card
-import androidx.compose.material3.DismissValue.Default
-import androidx.compose.material3.DismissValue.DismissedToEnd
-import androidx.compose.material3.DismissValue.DismissedToStart
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.ListItem
 import androidx.compose.material3.SwipeToDismissBox
+import androidx.compose.material3.SwipeToDismissValue
 import androidx.compose.material3.Text
-import androidx.compose.material3.rememberDismissState
+import androidx.compose.material3.rememberSwipeToDismissState
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
@@ -42,15 +40,15 @@
 @Composable
 @ExperimentalMaterial3Api
 fun SwipeToDismissListItems() {
-    val dismissState = rememberDismissState()
+    val dismissState = rememberSwipeToDismissState()
     SwipeToDismissBox(
         state = dismissState,
         backgroundContent = {
             val color by animateColorAsState(
                 when (dismissState.targetValue) {
-                    Default -> Color.LightGray
-                    DismissedToEnd -> Color.Green
-                    DismissedToStart -> Color.Red
+                    SwipeToDismissValue.Settled -> Color.LightGray
+                    SwipeToDismissValue.StartToEnd -> Color.Green
+                    SwipeToDismissValue.EndToStart -> Color.Red
                 }
             )
             Box(Modifier.fillMaxSize().background(color))
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
index 65be78f..3ee638f 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
@@ -18,6 +18,10 @@
 
 import androidx.annotation.Sampled
 import androidx.compose.animation.animateColor
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.animation.core.VectorConverter
 import androidx.compose.animation.core.animateDp
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.spring
@@ -48,6 +52,7 @@
 import androidx.compose.material3.SecondaryScrollableTabRow
 import androidx.compose.material3.SecondaryTabRow
 import androidx.compose.material3.Tab
+import androidx.compose.material3.TabIndicatorScope
 import androidx.compose.material3.TabPosition
 import androidx.compose.material3.TabRowDefaults
 import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
@@ -56,13 +61,21 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.geometry.CornerRadius
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.launch
 
 @Preview
 @Composable
@@ -386,18 +399,15 @@
     var state by remember { mutableStateOf(0) }
     val titles = listOf("Tab 1", "Tab 2", "Tab 3")
 
-    // Reuse the default offset animation modifier, but use our own indicator
-    val indicator = @Composable { tabPositions: List<TabPosition> ->
-        FancyIndicator(
-            MaterialTheme.colorScheme.primary,
-            Modifier.tabIndicatorOffset(tabPositions[state])
-        )
-    }
-
     Column {
         SecondaryTabRow(
             selectedTabIndex = state,
-            indicator = indicator
+            indicator = {
+                FancyIndicator(
+                    MaterialTheme.colorScheme.primary,
+                    Modifier.tabIndicatorOffset(state)
+                )
+            }
         ) {
             titles.forEachIndexed { index, title ->
                 Tab(
@@ -423,14 +433,10 @@
     var state by remember { mutableStateOf(0) }
     val titles = listOf("Tab 1", "Tab 2", "Tab 3")
 
-    val indicator = @Composable { tabPositions: List<TabPosition> ->
-        FancyAnimatedIndicator(tabPositions = tabPositions, selectedTabIndex = state)
-    }
-
     Column {
         SecondaryTabRow(
             selectedTabIndex = state,
-            indicator = indicator
+            indicator = { FancyAnimatedIndicatorWithModifier(state) }
         ) {
             titles.forEachIndexed { index, title ->
                 Tab(
@@ -448,6 +454,103 @@
     }
 }
 
+@Sampled
+@Composable
+fun FancyIndicator(color: Color, modifier: Modifier = Modifier) {
+    // Draws a rounded rectangular with border around the Tab, with a 5.dp padding from the edges
+    // Color is passed in as a parameter [color]
+    Box(
+        modifier
+            .padding(5.dp)
+            .fillMaxSize()
+            .border(BorderStroke(2.dp, color), RoundedCornerShape(5.dp))
+    )
+}
+
+@Sampled
+@Composable
+fun TabIndicatorScope.FancyAnimatedIndicatorWithModifier(index: Int) {
+    val colors = listOf(
+        MaterialTheme.colorScheme.primary,
+        MaterialTheme.colorScheme.secondary,
+        MaterialTheme.colorScheme.tertiary,
+    )
+    var startAnimatable by remember { mutableStateOf<Animatable<Dp, AnimationVector1D>?>(null) }
+    var endAnimatable by remember { mutableStateOf<Animatable<Dp, AnimationVector1D>?>(null) }
+    val coroutineScope = rememberCoroutineScope()
+    val indicatorColor: Color by animateColorAsState(colors[index % colors.size], label = "")
+
+    Box(
+        Modifier
+            .tabIndicatorLayout { measurable: Measurable, constraints: Constraints,
+                tabPositions: List<TabPosition> ->
+                val newStart = tabPositions[index].left
+                val newEnd = tabPositions[index].right
+                val startAnim = startAnimatable ?: Animatable(newStart, Dp.VectorConverter)
+                    .also { startAnimatable = it }
+
+                val endAnim = endAnimatable ?: Animatable(newEnd, Dp.VectorConverter)
+                    .also { endAnimatable = it }
+
+                if (endAnim.targetValue != newEnd) {
+                    coroutineScope.launch {
+                        endAnim.animateTo(
+                            newEnd,
+                            animationSpec =
+                            if (endAnim.targetValue < newEnd) {
+                                spring(dampingRatio = 1f, stiffness = 1000f)
+                            } else {
+                                spring(dampingRatio = 1f, stiffness = 50f)
+                            }
+
+                        )
+                    }
+                }
+
+                if (startAnim.targetValue != newStart) {
+                    coroutineScope.launch {
+                        startAnim.animateTo(
+                            newStart,
+                            animationSpec =
+                            // Handle directionality here, if we are moving to the right, we
+                            // want the right side of the indicator to move faster, if we are
+                            // moving to the left, we want the left side to move faster.
+                            if (startAnim.targetValue < newStart) {
+                                spring(dampingRatio = 1f, stiffness = 50f)
+                            } else {
+                                spring(dampingRatio = 1f, stiffness = 1000f)
+                            }
+
+                        )
+                    }
+                }
+
+                val indicatorEnd = endAnim.value.roundToPx()
+                val indicatorStart = startAnim.value.roundToPx()
+
+                // Apply an offset from the start to correctly position the indicator around the tab
+                val placeable = measurable.measure(
+                    constraints.copy(
+                        maxWidth = indicatorEnd - indicatorStart,
+                        minWidth = indicatorEnd - indicatorStart,
+                    )
+                )
+                layout(constraints.maxWidth, constraints.maxHeight) {
+                    placeable.place(indicatorStart, 0)
+                }
+            }
+            .padding(5.dp)
+            .fillMaxSize()
+            .drawWithContent {
+                drawRoundRect(
+                    color = indicatorColor,
+                    cornerRadius = CornerRadius(5.dp.toPx()),
+                    style = Stroke(width = 2.dp.toPx())
+                )
+            }
+    )
+}
+
 @Preview
 @Composable
 @OptIn(ExperimentalMaterial3Api::class)
@@ -495,11 +598,15 @@
 fun FancyTab(title: String, onClick: () -> Unit, selected: Boolean) {
     Tab(selected, onClick) {
         Column(
-            Modifier.padding(10.dp).height(50.dp).fillMaxWidth(),
+            Modifier
+                .padding(10.dp)
+                .height(50.dp)
+                .fillMaxWidth(),
             verticalArrangement = Arrangement.SpaceBetween
         ) {
             Box(
-                Modifier.size(10.dp)
+                Modifier
+                    .size(10.dp)
                     .align(Alignment.CenterHorizontally)
                     .background(
                         color = if (selected) MaterialTheme.colorScheme.primary
@@ -517,26 +624,13 @@
 
 @Sampled
 @Composable
-fun FancyIndicator(color: Color, modifier: Modifier = Modifier) {
-    // Draws a rounded rectangular with border around the Tab, with a 5.dp padding from the edges
-    // Color is passed in as a parameter [color]
-    Box(
-        modifier
-            .padding(5.dp)
-            .fillMaxSize()
-            .border(BorderStroke(2.dp, color), RoundedCornerShape(5.dp))
-    )
-}
-
-@Sampled
-@Composable
 fun FancyAnimatedIndicator(tabPositions: List<TabPosition>, selectedTabIndex: Int) {
     val colors = listOf(
         MaterialTheme.colorScheme.primary,
         MaterialTheme.colorScheme.secondary,
         MaterialTheme.colorScheme.tertiary,
     )
-    val transition = updateTransition(selectedTabIndex)
+    val transition = updateTransition(selectedTabIndex, label = "")
     val indicatorStart by transition.animateDp(
         transitionSpec = {
             // Handle directionality here, if we are moving to the right, we
@@ -547,7 +641,7 @@
             } else {
                 spring(dampingRatio = 1f, stiffness = 1000f)
             }
-        }
+        }, label = "fancy_indicator"
     ) {
         tabPositions[it].left
     }
@@ -562,12 +656,12 @@
             } else {
                 spring(dampingRatio = 1f, stiffness = 50f)
             }
-        }
+        }, label = "indicator_position"
     ) {
         tabPositions[it].right
     }
 
-    val indicatorColor by transition.animateColor {
+    val indicatorColor by transition.animateColor(label = "indicator_color") {
         colors[it % colors.size]
     }
 
diff --git a/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_1.jpg b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_1.jpg
new file mode 100644
index 0000000..b02612e
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_1.jpg
Binary files differ
diff --git a/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_2.jpg b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_2.jpg
new file mode 100644
index 0000000..73162bb
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_2.jpg
Binary files differ
diff --git a/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_3.jpg b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_3.jpg
new file mode 100644
index 0000000..d31f632
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_3.jpg
Binary files differ
diff --git a/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_4.jpg b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_4.jpg
new file mode 100644
index 0000000..8362062
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_4.jpg
Binary files differ
diff --git a/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_5.jpg b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_5.jpg
new file mode 100644
index 0000000..f5eb364
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/res/drawable-nodpi/carousel_image_5.jpg
Binary files differ
diff --git a/compose/material3/material3/samples/src/main/res/values/strings.xml b/compose/material3/material3/samples/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b52b1ea
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<resources>
+    <string name="carousel_image_1_description">A racecar</string>
+    <string name="carousel_image_2_description">Dotonburi, Osaka</string>
+    <string name="carousel_image_3_description">The Grand Canyon</string>
+    <string name="carousel_image_4_description">A rock structure with its reflection mirrored over the sea</string>
+    <string name="carousel_image_5_description">A car on a long stretch of desert road</string>
+</resources>
\ No newline at end of file
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MaterialRippleThemeTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MaterialRippleThemeTest.kt
index e3556a4..2ba6774 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MaterialRippleThemeTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MaterialRippleThemeTest.kt
@@ -34,10 +34,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.ripple.LocalRippleTheme
 import androidx.compose.material.ripple.RippleAlpha
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
@@ -85,6 +82,7 @@
     // color.
     maxSdkVersion = Build.VERSION_CODES.R
 )
+@Suppress("DEPRECATION_ERROR")
 class MaterialRippleThemeTest {
 
     @get:Rule
@@ -268,10 +266,12 @@
         val expectedAlpha = 0.5f
         val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
 
-        val rippleTheme = object : RippleTheme {
+        val rippleTheme = object : androidx.compose.material.ripple.RippleTheme {
+            @Deprecated("Super method deprecated")
             @Composable
             override fun defaultColor() = rippleColor
 
+            @Deprecated("Super method deprecated")
             @Composable
             override fun rippleAlpha() = rippleAlpha
         }
@@ -281,12 +281,14 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides rippleTheme
+                ) {
                     Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             RippleBoxWithBackground(
                                 interactionSource,
-                                rememberRipple(),
+                                androidx.compose.material.ripple.rememberRipple(),
                                 bounded = true
                             )
                         }
@@ -318,10 +320,12 @@
         val expectedAlpha = 0.5f
         val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
 
-        val rippleTheme = object : RippleTheme {
+        val rippleTheme = object : androidx.compose.material.ripple.RippleTheme {
+            @Deprecated("Super method deprecated")
             @Composable
             override fun defaultColor() = rippleColor
 
+            @Deprecated("Super method deprecated")
             @Composable
             override fun rippleAlpha() = rippleAlpha
         }
@@ -331,12 +335,14 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides rippleTheme
+                ) {
                     Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             RippleBoxWithBackground(
                                 interactionSource,
-                                rememberRipple(),
+                                androidx.compose.material.ripple.rememberRipple(),
                                 bounded = true
                             )
                         }
@@ -368,10 +374,12 @@
         val expectedAlpha = 0.5f
         val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
 
-        val rippleTheme = object : RippleTheme {
+        val rippleTheme = object : androidx.compose.material.ripple.RippleTheme {
+            @Deprecated("Super method deprecated")
             @Composable
             override fun defaultColor() = rippleColor
 
+            @Deprecated("Super method deprecated")
             @Composable
             override fun rippleAlpha() = rippleAlpha
         }
@@ -381,12 +389,14 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides rippleTheme
+                ) {
                     Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             RippleBoxWithBackground(
                                 interactionSource,
-                                rememberRipple(),
+                                androidx.compose.material.ripple.rememberRipple(),
                                 bounded = true
                             )
                         }
@@ -418,9 +428,11 @@
         val expectedAlpha = 0.5f
         val rippleAlpha = RippleAlpha(expectedAlpha, expectedAlpha, expectedAlpha, expectedAlpha)
 
-        val rippleTheme = object : RippleTheme {
+        val rippleTheme = object : androidx.compose.material.ripple.RippleTheme {
+            @Deprecated("Super method deprecated")
             @Composable
             override fun defaultColor() = rippleColor
+            @Deprecated("Super method deprecated")
             @Composable
             override fun rippleAlpha() = rippleAlpha
         }
@@ -430,12 +442,14 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides rippleTheme
+                ) {
                     Surface(contentColor = contentColor) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             RippleBoxWithBackground(
                                 interactionSource,
-                                rememberRipple(),
+                                androidx.compose.material.ripple.rememberRipple(),
                                 bounded = true
                             )
                         }
@@ -466,14 +480,18 @@
     fun themeChangeDuringRipple_dragged() {
         val interactionSource = MutableInteractionSource()
 
-        fun createRippleTheme(color: Color, alpha: Float) = object : RippleTheme {
-            val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
-            @Composable
-            override fun defaultColor() = color
+        fun createRippleTheme(color: Color, alpha: Float):
+            androidx.compose.material.ripple.RippleTheme =
+            object : androidx.compose.material.ripple.RippleTheme {
+                val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
+                @Deprecated("Super method deprecated")
+                @Composable
+                override fun defaultColor() = color
 
-            @Composable
-            override fun rippleAlpha() = rippleAlpha
-        }
+                @Deprecated("Super method deprecated")
+                @Composable
+                override fun rippleAlpha() = rippleAlpha
+            }
 
         val initialColor = Color.Red
         val initialAlpha = 0.5f
@@ -485,12 +503,14 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides rippleTheme) {
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides rippleTheme
+                ) {
                     Surface(contentColor = Color.Black) {
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             RippleBoxWithBackground(
                                 interactionSource,
-                                rememberRipple(),
+                                androidx.compose.material.ripple.rememberRipple(),
                                 bounded = true
                             )
                         }
@@ -547,10 +567,12 @@
         val rippleAlpha = RippleAlpha(alpha, alpha, alpha, alpha)
         val expectedRippleColor = Color.Red
 
-        val theme = object : RippleTheme {
+        val theme = object : androidx.compose.material.ripple.RippleTheme {
+            @Deprecated("Super method deprecated")
             @Composable
             override fun defaultColor() = LocalContentColor.current
 
+            @Deprecated("Super method deprecated")
             @Composable
             override fun rippleAlpha() = rippleAlpha
         }
@@ -560,10 +582,12 @@
         rule.setContent {
             scope = rememberCoroutineScope()
             MaterialTheme {
-                CompositionLocalProvider(LocalRippleTheme provides theme) {
+                CompositionLocalProvider(
+                    androidx.compose.material.ripple.LocalRippleTheme provides theme
+                ) {
                     Surface(contentColor = Color.Black) {
                         // Create ripple where contentColor is black
-                        val ripple = rememberRipple()
+                        val ripple = androidx.compose.material.ripple.rememberRipple()
                         Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                             Surface(contentColor = expectedRippleColor) {
                                 // Ripple is used where contentColor is red, so the instance
@@ -695,6 +719,7 @@
  * @param lightTheme whether the theme is light or dark
  * @param contentColor the contentColor that will be used for the ripple color
  */
+@Suppress("DEPRECATION_ERROR")
 private fun ComposeContentTestRule.setRippleContent(
     interactionSource: MutableInteractionSource,
     bounded: Boolean,
@@ -710,7 +735,11 @@
         MaterialTheme(colors) {
             Surface(contentColor = contentColor) {
                 Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
-                    RippleBoxWithBackground(interactionSource, rememberRipple(bounded), bounded)
+                    RippleBoxWithBackground(
+                        interactionSource,
+                        androidx.compose.material.ripple.rememberRipple(bounded),
+                        bounded
+                    )
                 }
             }
         }
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
index 5927542..7a5781b 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
@@ -631,6 +631,40 @@
     }
 
     @Test
+    fun testOutlinedTextField_placeholderColor_whenInputEmptyAndFocused() {
+        var focused = false
+        rule.setMaterialContent(lightColorScheme()) {
+            val text = remember { mutableStateOf("") }
+            OutlinedTextField(
+                modifier = Modifier.testTag(TextFieldTag),
+                value = text.value,
+                onValueChange = { text.value = it },
+                colors = OutlinedTextFieldDefaults.colors(
+                    focusedPlaceholderColor = Color.Red,
+                    unfocusedPlaceholderColor = Color.Green,
+                ),
+                placeholder = {
+                    Text("Placeholder")
+                    assertThat(LocalContentColor.current)
+                        .isEqualTo(if (focused) Color.Red else Color.Green)
+                },
+            )
+        }
+
+        // click to focus
+        focused = true
+        rule.onNodeWithTag(TextFieldTag).performClick()
+
+        // enter some text (placeholder hidden)
+        rule.onNodeWithTag(TextFieldTag).performTextInput("input")
+        rule.runOnIdle {}
+
+        // delete the text (placeholder shown)
+        rule.onNodeWithTag(TextFieldTag).performTextClearance()
+        rule.runOnIdle {}
+    }
+
+    @Test
     fun testOutlinedTextField_labelAndPlaceholderPosition_whenSmallerThanMinimumHeight() {
         val labelSize = 10.dp
         val labelPosition = Ref<Offset>()
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarTest.kt
index 89721c6..b025a39 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SearchBarTest.kt
@@ -17,6 +17,7 @@
 package androidx.compose.material3
 
 import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
+import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxSize
@@ -70,6 +71,9 @@
                 val dispatcher = LocalOnBackPressedDispatcherOwner.current!!.onBackPressedDispatcher
                 var active by remember { mutableStateOf(false) }
 
+                // Extra item for initial focus.
+                Box(Modifier.size(10.dp).focusable())
+
                 SearchBar(
                     modifier = Modifier.testTag(SearchBarTestTag),
                     query = "Query",
@@ -249,6 +253,9 @@
                 val dispatcher = LocalOnBackPressedDispatcherOwner.current!!.onBackPressedDispatcher
                 var active by remember { mutableStateOf(false) }
 
+                // Extra item for initial focus.
+                Box(Modifier.size(10.dp).focusable())
+
                 DockedSearchBar(
                     modifier = Modifier.testTag(SearchBarTestTag),
                     query = "Query",
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt
index 0ce7603..05a5858 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt
@@ -69,7 +69,7 @@
     fun swipeDismiss_testOffset_whenDefault() {
         rule.setContent {
             SwipeToDismissBox(
-                state = rememberDismissState(DismissValue.Default),
+                state = rememberSwipeToDismissState(SwipeToDismissValue.Settled),
                 backgroundContent = { }
             ) {
                     Box(
@@ -87,7 +87,7 @@
     fun swipeDismiss_testOffset_whenDismissedToEnd() {
         rule.setContent {
             SwipeToDismissBox(
-                state = rememberDismissState(DismissValue.DismissedToEnd),
+                state = rememberSwipeToDismissState(SwipeToDismissValue.StartToEnd),
                 backgroundContent = { }
             ) {
                     Box(
@@ -106,8 +106,8 @@
     fun swipeDismiss_testOffset_whenDismissedToStart() {
         rule.setContent {
             SwipeToDismissBox(
-                state = rememberDismissState(DismissValue.DismissedToStart),
-                backgroundContent = { }
+                state = rememberSwipeToDismissState(SwipeToDismissValue.EndToStart),
+                backgroundContent = { },
             ) {
                     Box(
                         Modifier
@@ -125,7 +125,7 @@
     fun swipeDismiss_testBackgroundMatchesContentSize() {
         rule.setContent {
             SwipeToDismissBox(
-                state = rememberDismissState(DismissValue.Default),
+                state = rememberSwipeToDismissState(SwipeToDismissValue.Settled),
                 backgroundContent = {
                     Box(
                         Modifier
@@ -142,14 +142,15 @@
 
     @Test
     fun swipeDismiss_dismissBySwipe_toEnd() {
-        lateinit var dismissState: DismissState
+        lateinit var swipeToDismissState: SwipeToDismissState
         rule.setContent {
-            dismissState = rememberDismissState(DismissValue.Default)
+            swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled)
             SwipeToDismissBox(
-                state = dismissState,
-                backgroundContent = { },
+                state = swipeToDismissState,
                 modifier = Modifier.testTag(swipeDismissTag),
-                directions = setOf(DismissDirection.StartToEnd)
+                enableDismissFromStartToEnd = true,
+                enableDismissFromEndToStart = false,
+                backgroundContent = { }
             ) { Box(Modifier.fillMaxSize()) }
         }
 
@@ -158,20 +159,21 @@
         advanceClock()
 
         rule.runOnIdle {
-            assertThat(dismissState.currentValue).isEqualTo(DismissValue.DismissedToEnd)
+            assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.StartToEnd)
         }
     }
 
     @Test
     fun swipeDismiss_dismissBySwipe_toStart() {
-        lateinit var dismissState: DismissState
+        lateinit var swipeToDismissState: SwipeToDismissState
         rule.setContent {
-            dismissState = rememberDismissState(DismissValue.Default)
+            swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled)
             SwipeToDismissBox(
-                state = dismissState,
-                backgroundContent = { },
+                state = swipeToDismissState,
                 modifier = Modifier.testTag(swipeDismissTag),
-                directions = setOf(DismissDirection.EndToStart)
+                enableDismissFromStartToEnd = false,
+                enableDismissFromEndToStart = true,
+                backgroundContent = { },
             ) { Box(Modifier.fillMaxSize()) }
         }
 
@@ -180,21 +182,22 @@
         advanceClock()
 
         rule.runOnIdle {
-            assertThat(dismissState.currentValue).isEqualTo(DismissValue.DismissedToStart)
+            assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.EndToStart)
         }
     }
 
     @Test
     fun swipeDismiss_dismissBySwipe_toEnd_rtl() {
-        lateinit var dismissState: DismissState
+        lateinit var swipeToDismissState: SwipeToDismissState
         rule.setContent {
-            dismissState = rememberDismissState(DismissValue.Default)
+            swipeToDismissState = rememberSwipeToDismissState()
             CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
                 SwipeToDismissBox(
-                    state = dismissState,
-                    backgroundContent = { },
+                    state = swipeToDismissState,
                     modifier = Modifier.testTag(swipeDismissTag),
-                    directions = setOf(DismissDirection.StartToEnd)
+                    enableDismissFromStartToEnd = true,
+                    enableDismissFromEndToStart = false,
+                    backgroundContent = { },
                 ) { Box(Modifier.fillMaxSize()) }
             }
         }
@@ -204,21 +207,22 @@
         advanceClock()
 
         rule.runOnIdle {
-            assertThat(dismissState.currentValue).isEqualTo(DismissValue.DismissedToEnd)
+            assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.StartToEnd)
         }
     }
 
     @Test
     fun swipeDismiss_dismissBySwipe_toStart_rtl() {
-        lateinit var dismissState: DismissState
+        lateinit var swipeToDismissState: SwipeToDismissState
         rule.setContent {
-            dismissState = rememberDismissState(DismissValue.Default)
+            swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled)
             CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
                 SwipeToDismissBox(
-                    state = dismissState,
-                    backgroundContent = { },
+                    state = swipeToDismissState,
                     modifier = Modifier.testTag(swipeDismissTag),
-                    directions = setOf(DismissDirection.EndToStart)
+                    enableDismissFromStartToEnd = false,
+                    enableDismissFromEndToStart = true,
+                    backgroundContent = { },
                 ) { Box(Modifier.fillMaxSize()) }
             }
         }
@@ -228,20 +232,21 @@
         advanceClock()
 
         rule.runOnIdle {
-            assertThat(dismissState.currentValue).isEqualTo(DismissValue.DismissedToStart)
+            assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.EndToStart)
         }
     }
 
     @Test
     fun swipeDismiss_dismissBySwipe_disabled() {
-        lateinit var dismissState: DismissState
+        lateinit var swipeToDismissState: SwipeToDismissState
         rule.setContent {
-            dismissState = rememberDismissState(DismissValue.Default)
+            swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled)
             SwipeToDismissBox(
-                state = dismissState,
-                backgroundContent = { },
+                state = swipeToDismissState,
                 modifier = Modifier.testTag(swipeDismissTag),
-                directions = setOf()
+                enableDismissFromStartToEnd = false,
+                enableDismissFromEndToStart = false,
+                backgroundContent = { },
             ) { Box(Modifier.fillMaxSize()) }
         }
 
@@ -250,7 +255,7 @@
         advanceClock()
 
         rule.runOnIdle {
-            assertThat(dismissState.currentValue).isEqualTo(DismissValue.Default)
+            assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.Settled)
         }
 
         rule.onNodeWithTag(swipeDismissTag).performTouchInput { swipeLeft() }
@@ -258,7 +263,7 @@
         advanceClock()
 
         rule.runOnIdle {
-            assertThat(dismissState.currentValue).isEqualTo(DismissValue.Default)
+            assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.Settled)
         }
     }
 
@@ -273,7 +278,7 @@
         lateinit var lazyState: LazyListState
         lateinit var scope: CoroutineScope
         val amountOfItems = 100
-        val composedItems = mutableMapOf<Int, DismissState>()
+        val composedItems = mutableMapOf<Int, SwipeToDismissState>()
 
         rule.setContent {
             scope = rememberCoroutineScope()
@@ -281,9 +286,9 @@
                 lazyState = rememberLazyListState()
                 LazyColumn(state = lazyState) {
                     items(amountOfItems, key = { item -> item }) { index ->
-                        composedItems[index] = rememberDismissState()
-                        val isDismissed = composedItems[index]!!
-                            .isDismissed(DismissDirection.EndToStart)
+                        composedItems[index] = rememberSwipeToDismissState()
+                        val isDismissed =
+                            composedItems[index]!!.currentValue == SwipeToDismissValue.EndToStart
                         AnimatedVisibility(visible = !isDismissed) {
                             SwipeToDismissBox(
                                 modifier = Modifier
@@ -320,7 +325,7 @@
 
         // Dismiss an item so that the lazy layout is required to compose a new item
         scope.launch {
-            composedItems[initiallyVisibleItems - 1]!!.dismiss(DismissDirection.EndToStart)
+            composedItems[initiallyVisibleItems - 1]!!.dismiss(SwipeToDismissValue.EndToStart)
         }
         rule.waitForIdle()
 
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt
index 2ad9550..ab22980 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt
@@ -546,12 +546,7 @@
         Modifier
             .semantics(mergeDescendants = true) {}
             .testTag(TAG)) {
-        PrimaryTabRow(selectedTabIndex = 0, indicator = @Composable { tabPositions ->
-            TabRowDefaults.PrimaryIndicator(
-                modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
-                width = tabPositions[0].contentWidth
-            )
-        }) {
+        PrimaryTabRow(selectedTabIndex = 0) {
             Tab(
                 selected = true,
                 onClick = {},
@@ -629,15 +624,10 @@
         Modifier
             .semantics(mergeDescendants = true) {}
             .testTag(TAG)) {
-        PrimaryTabRow(selectedTabIndex = 0,
-            containerColor = containerColor,
-            indicator = @Composable { tabPositions ->
-                TabRowDefaults.PrimaryIndicator(
-                    modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
-                    width = tabPositions[0].contentWidth,
-                    color = selectedContentColor
-                )
-            }) {
+        PrimaryTabRow(
+            selectedTabIndex = 0,
+            containerColor = containerColor
+        ) {
             Tab(
                 selected = true,
                 onClick = {},
@@ -685,14 +675,16 @@
         Modifier
             .semantics(mergeDescendants = true) {}
             .testTag(TAG)) {
-        SecondaryTabRow(selectedTabIndex = 0,
+        SecondaryTabRow(
+            selectedTabIndex = 0,
             containerColor = containerColor,
-            indicator = @Composable { tabPositions ->
+            indicator = {
                 TabRowDefaults.SecondaryIndicator(
-                    modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
+                    modifier = Modifier.tabIndicatorOffset(0),
                     color = selectedContentColor
                 )
-            }) {
+            }
+        ) {
             Tab(
                 selected = true,
                 onClick = {},
@@ -735,12 +727,7 @@
         Modifier
             .semantics(mergeDescendants = true) {}
             .testTag(TAG)) {
-        PrimaryTabRow(selectedTabIndex = 0, indicator = @Composable { tabPositions ->
-            TabRowDefaults.PrimaryIndicator(
-                modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
-                width = tabPositions[0].contentWidth
-            )
-        }) {
+        PrimaryTabRow(selectedTabIndex = 0) {
             LeadingIconTab(
                 selected = true,
                 onClick = {},
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabTest.kt
index d2364ef..11e09d2 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TabTest.kt
@@ -249,21 +249,19 @@
             var state by remember { mutableStateOf(0) }
             val titles = listOf("TAB 1", "TAB 2")
 
-            val indicator = @Composable { tabPositions: List<TabPosition> ->
-                Box(
-                    Modifier
-                        .tabIndicatorOffset(tabPositions[state])
-                        .fillMaxWidth()
-                        .height(indicatorHeight)
-                        .background(color = Color.Red)
-                        .testTag("indicator")
-                )
-            }
-
             Box(Modifier.testTag("tabRow")) {
                 SecondaryTabRow(
                     selectedTabIndex = state,
-                    indicator = indicator
+                    indicator = {
+                        Box(
+                            Modifier
+                                .tabIndicatorOffset(state)
+                                .fillMaxWidth()
+                                .height(indicatorHeight)
+                                .background(color = Color.Red)
+                                .testTag("indicator")
+                        )
+                    }
                 ) {
                     titles.forEachIndexed { index, title ->
                         Tab(
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TextFieldTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TextFieldTest.kt
index 8f1f3a3..0248140 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TextFieldTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/TextFieldTest.kt
@@ -80,6 +80,7 @@
 import androidx.compose.ui.test.onNodeWithText
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performTextClearance
+import androidx.compose.ui.test.performTextInput
 import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.buildAnnotatedString
@@ -590,6 +591,40 @@
     }
 
     @Test
+    fun testTextField_placeholderColor_whenInputEmptyAndFocused() {
+        var focused = false
+        rule.setMaterialContent(lightColorScheme()) {
+            val text = remember { mutableStateOf("") }
+            TextField(
+                modifier = Modifier.testTag(TextFieldTag),
+                value = text.value,
+                onValueChange = { text.value = it },
+                colors = TextFieldDefaults.colors(
+                    focusedPlaceholderColor = Color.Red,
+                    unfocusedPlaceholderColor = Color.Green,
+                ),
+                placeholder = {
+                    Text("Placeholder")
+                    assertThat(LocalContentColor.current)
+                        .isEqualTo(if (focused) Color.Red else Color.Green)
+                },
+            )
+        }
+
+        // click to focus
+        focused = true
+        rule.onNodeWithTag(TextFieldTag).performClick()
+
+        // enter some text (placeholder hidden)
+        rule.onNodeWithTag(TextFieldTag).performTextInput("input")
+        rule.runOnIdle {}
+
+        // delete the text (placeholder shown)
+        rule.onNodeWithTag(TextFieldTag).performTextClearance()
+        rule.runOnIdle {}
+    }
+
+    @Test
     fun testTextField_labelAndPlaceholderPosition_whenSmallerThanMinimumHeight() {
         val labelSize = 10.dp
         val labelPosition = Ref<Offset>()
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshIndicatorTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshIndicatorTest.kt
index 4481eec..9771d2b 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshIndicatorTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshIndicatorTest.kt
@@ -20,8 +20,9 @@
 import androidx.compose.foundation.gestures.awaitFirstDown
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.size
 import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableFloatStateOf
 import androidx.compose.runtime.mutableStateOf
@@ -118,7 +119,11 @@
 
     @Test
     fun indicatorRespects_changingOffset() {
+        val containerSize = 30.dp
         val verticalOffsetDp = mutableStateOf(0.dp)
+        val expectedOffset = derivedStateOf {
+            verticalOffsetDp.value - (containerSize + SpinnerSize) / 2
+        }
         rule.setContent {
             val density = LocalDensity.current
             Box(Modifier.fillMaxSize()) {
@@ -141,14 +146,15 @@
                             TODO("Not yet implemented")
                         }
                     },
-                    modifier = Modifier.heightIn(min = 30.dp).testTag(INDICATOR_TAG)
+                    modifier = Modifier.size(containerSize).testTag(INDICATOR_TAG)
                 )
             }
         }
+        rule.waitForIdle()
         rule
             .onNodeWithTag(INDICATOR_TAG)
             .onChild()
-            .assertTopPositionInRootIsEqualTo(verticalOffsetDp.value - 30.dp)
+            .assertTopPositionInRootIsEqualTo(expectedOffset.value)
 
         verticalOffsetDp.value = 100.dp
         rule.waitForIdle()
@@ -156,7 +162,7 @@
         rule
             .onNodeWithTag(INDICATOR_TAG)
             .onChild()
-            .assertTopPositionInRootIsEqualTo(verticalOffsetDp.value - 30.dp)
+            .assertTopPositionInRootIsEqualTo(expectedOffset.value)
     }
 
     // Regression test for b/271777421
diff --git a/compose/material3/material3/src/androidMain/res/values-gl/strings.xml b/compose/material3/material3/src/androidMain/res/values-gl/strings.xml
index 0d2dad7..bc6bb20 100644
--- a/compose/material3/material3/src/androidMain/res/values-gl/strings.xml
+++ b/compose/material3/material3/src/androidMain/res/values-gl/strings.xml
@@ -61,8 +61,8 @@
     <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Desprega o panel inferior"</string>
     <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Cadro de información"</string>
     <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar o cadro de información"</string>
-    <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
-    <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+    <string name="m3c_time_picker_pm" msgid="6616362054113087709">"p.m."</string>
+    <string name="m3c_time_picker_am" msgid="2786685010796619560">"a.m."</string>
     <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecciona a.m. ou p.m."</string>
     <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selecciona a hora"</string>
     <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selecciona os minutos"</string>
diff --git a/compose/material3/material3/src/androidMain/res/values-ro/strings.xml b/compose/material3/material3/src/androidMain/res/values-ro/strings.xml
index 9810ca8..91ff286 100644
--- a/compose/material3/material3/src/androidMain/res/values-ro/strings.xml
+++ b/compose/material3/material3/src/androidMain/res/values-ro/strings.xml
@@ -61,8 +61,8 @@
     <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Extinde foaia din partea de jos"</string>
     <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Balon explicativ"</string>
     <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Afișează balonul explicativ"</string>
-    <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
-    <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+    <string name="m3c_time_picker_pm" msgid="6616362054113087709">"p.m."</string>
+    <string name="m3c_time_picker_am" msgid="2786685010796619560">"a.m."</string>
     <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selectează AM sau PM"</string>
     <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selectează ora"</string>
     <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selectează minutele"</string>
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
index 3191c2f..b17607d 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
@@ -29,7 +29,6 @@
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.triStateToggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.CheckboxTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
@@ -145,13 +144,14 @@
 ) {
     val toggleableModifier =
         if (onClick != null) {
+            @Suppress("DEPRECATION_ERROR")
             Modifier.triStateToggleable(
                 state = state,
                 onClick = onClick,
                 enabled = enabled,
                 role = Role.Checkbox,
                 interactionSource = interactionSource,
-                indication = rememberRipple(
+                indication = androidx.compose.material.ripple.rememberRipple(
                     bounded = false,
                     radius = CheckboxTokens.StateLayerSize / 2
                 )
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
index e9d0618..ad8a03e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
@@ -28,13 +28,10 @@
 import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.IntrinsicSize
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.defaultMinSize
 import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
 import androidx.compose.material3.tokens.AssistChipTokens
 import androidx.compose.material3.tokens.FilterChipTokens
 import androidx.compose.material3.tokens.InputChipTokens
@@ -56,12 +53,18 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.Placeable
+import androidx.compose.ui.layout.layoutId
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.role
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.offset
+import androidx.compose.ui.util.fastFirst
+import androidx.compose.ui.util.fastFirstOrNull
 
 /**
  * <a href="https://m3.material.io/components/chips/overview" class="external" target="_blank">Material Design assist chip</a>.
@@ -1778,31 +1781,80 @@
         LocalContentColor provides labelColor,
         LocalTextStyle provides labelTextStyle
     ) {
-        Row(
-            Modifier
-                .width(IntrinsicSize.Max)
+        Layout(
+            modifier = Modifier
                 .defaultMinSize(minHeight = minHeight)
                 .padding(paddingValues),
-            horizontalArrangement = Arrangement.Start,
-            verticalAlignment = Alignment.CenterVertically
-        ) {
-            if (avatar != null) {
-                avatar()
-            } else if (leadingIcon != null) {
-                CompositionLocalProvider(
-                    LocalContentColor provides leadingIconColor, content = leadingIcon
+            content = {
+                if (avatar != null || leadingIcon != null) {
+                    Box(
+                        modifier = Modifier
+                            .layoutId(LeadingIconLayoutId),
+                        contentAlignment = Alignment.Center,
+                        content = {
+                            if (avatar != null) {
+                                avatar()
+                            } else if (leadingIcon != null) {
+                                CompositionLocalProvider(
+                                    LocalContentColor provides leadingIconColor,
+                                    content = leadingIcon
+                                )
+                            }
+                        }
+                    )
+                }
+                Row(
+                    modifier = Modifier
+                        .layoutId(LabelLayoutId)
+                        .padding(HorizontalElementsPadding, 0.dp),
+                    horizontalArrangement = Arrangement.Start,
+                    verticalAlignment = Alignment.CenterVertically,
+                    content = { label() }
                 )
+                if (trailingIcon != null) {
+                    Box(
+                        modifier = Modifier
+                            .layoutId(TrailingIconLayoutId),
+                        contentAlignment = Alignment.Center,
+                        content = {
+                            CompositionLocalProvider(
+                                LocalContentColor provides trailingIconColor,
+                                content = trailingIcon
+                            )
+                        }
+                    )
+                }
             }
-            Spacer(Modifier.width(HorizontalElementsPadding))
-            Row(
-                modifier = Modifier.weight(1f),
-                horizontalArrangement = Arrangement.Start,
-                verticalAlignment = Alignment.CenterVertically
-            ) { label() }
-            Spacer(Modifier.width(HorizontalElementsPadding))
-            if (trailingIcon != null) {
-                CompositionLocalProvider(
-                    LocalContentColor provides trailingIconColor, content = trailingIcon
+        ) { measurables, constraints ->
+            val leadingIconPlaceable: Placeable? =
+                measurables.fastFirstOrNull { it.layoutId == LeadingIconLayoutId }
+                    ?.measure(constraints.copy(minWidth = 0, minHeight = 0))
+            val leadingIconWidth = widthOrZero(leadingIconPlaceable)
+            val leadingIconHeight = heightOrZero(leadingIconPlaceable)
+
+            val trailingIconPlaceable: Placeable? =
+                measurables.fastFirstOrNull { it.layoutId == TrailingIconLayoutId }
+                    ?.measure(constraints.copy(minWidth = 0, minHeight = 0))
+            val trailingIconWidth = widthOrZero(trailingIconPlaceable)
+            val trailingIconHeight = heightOrZero(trailingIconPlaceable)
+
+            val labelPlaceable = measurables.fastFirst { it.layoutId == LabelLayoutId }
+                .measure(
+                    constraints.offset(horizontal = -(leadingIconWidth + trailingIconWidth))
+                )
+
+            val width = leadingIconWidth + labelPlaceable.width + trailingIconWidth
+            val height = maxOf(leadingIconHeight, labelPlaceable.height, trailingIconHeight)
+
+            layout(width, height) {
+                leadingIconPlaceable?.placeRelative(
+                    0,
+                    Alignment.CenterVertically.align(leadingIconHeight, height)
+                )
+                labelPlaceable.placeRelative(leadingIconWidth, 0)
+                trailingIconPlaceable?.placeRelative(
+                    leadingIconWidth + labelPlaceable.width,
+                    Alignment.CenterVertically.align(trailingIconHeight, height)
                 )
             }
         }
@@ -2435,3 +2487,7 @@
  * Returns the [PaddingValues] for the suggestion chip.
  */
 private val SuggestionChipPadding = PaddingValues(horizontal = HorizontalElementsPadding)
+
+private const val LeadingIconLayoutId = "leadingIcon"
+private const val LabelLayoutId = "label"
+private const val TrailingIconLayoutId = "trailingIcon"
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
index f194bc7..ccf0005 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
@@ -23,7 +23,6 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.FilledIconButtonTokens
 import androidx.compose.material3.tokens.FilledTonalIconButtonTokens
 import androidx.compose.material3.tokens.IconButtonTokens
@@ -80,6 +79,7 @@
     interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable () -> Unit
 ) {
+    @Suppress("DEPRECATION_ERROR")
     Box(
         modifier = modifier
             .minimumInteractiveComponentSize()
@@ -91,7 +91,7 @@
                 enabled = enabled,
                 role = Role.Button,
                 interactionSource = interactionSource,
-                indication = rememberRipple(
+                indication = androidx.compose.material.ripple.rememberRipple(
                     bounded = false,
                     radius = IconButtonTokens.StateLayerSize / 2
                 )
@@ -141,6 +141,7 @@
     interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     content: @Composable () -> Unit
 ) {
+    @Suppress("DEPRECATION_ERROR")
     Box(
         modifier = modifier
             .minimumInteractiveComponentSize()
@@ -153,7 +154,7 @@
                 enabled = enabled,
                 role = Role.Checkbox,
                 interactionSource = interactionSource,
-                indication = rememberRipple(
+                indication = androidx.compose.material.ripple.rememberRipple(
                     bounded = false,
                     radius = IconButtonTokens.StateLayerSize / 2
                 )
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
index 546efcd..649da88 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
@@ -19,10 +19,7 @@
 import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.text.selection.LocalTextSelectionColors
 import androidx.compose.foundation.text.selection.TextSelectionColors
-import androidx.compose.material.ripple.LocalRippleTheme
 import androidx.compose.material.ripple.RippleAlpha
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.StateTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -54,6 +51,7 @@
  * @param typography A set of text styles to be used as this hierarchy's typography system
  * @param shapes A set of corner shapes to be used as this hierarchy's shape system
  */
+@Suppress("DEPRECATION_ERROR")
 @Composable
 fun MaterialTheme(
     colorScheme: ColorScheme = MaterialTheme.colorScheme,
@@ -61,12 +59,12 @@
     typography: Typography = MaterialTheme.typography,
     content: @Composable () -> Unit
 ) {
-    val rippleIndication = rememberRipple()
+    val rippleIndication = androidx.compose.material.ripple.rememberRipple()
     val selectionColors = rememberTextSelectionColors(colorScheme)
     CompositionLocalProvider(
         LocalColorScheme provides colorScheme,
         LocalIndication provides rippleIndication,
-        LocalRippleTheme provides MaterialRippleTheme,
+        androidx.compose.material.ripple.LocalRippleTheme provides MaterialRippleTheme,
         LocalShapes provides shapes,
         LocalTextSelectionColors provides selectionColors,
         LocalTypography provides typography,
@@ -105,11 +103,14 @@
         get() = LocalShapes.current
 }
 
+@Suppress("DEPRECATION_ERROR")
 @Immutable
-private object MaterialRippleTheme : RippleTheme {
+private object MaterialRippleTheme : androidx.compose.material.ripple.RippleTheme {
+    @Deprecated("Super method deprecated")
     @Composable
     override fun defaultColor() = LocalContentColor.current
 
+    @Deprecated("Super method deprecated")
     @Composable
     override fun rippleAlpha() = DefaultRippleAlpha
 }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
index 3337530..cc3554b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
@@ -36,7 +36,6 @@
 import androidx.compose.foundation.layout.sizeIn
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.MenuTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -261,13 +260,14 @@
     contentPadding: PaddingValues,
     interactionSource: MutableInteractionSource
 ) {
+    @Suppress("DEPRECATION_ERROR")
     Row(
         modifier = modifier
             .clickable(
                 enabled = enabled,
                 onClick = onClick,
                 interactionSource = interactionSource,
-                indication = rememberRipple(true)
+                indication = androidx.compose.material.ripple.rememberRipple(true)
             )
             .fillMaxWidth()
             // Preferred min and max width used during the intrinsic measurement.
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
index abe86f4..c480fda 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
@@ -36,7 +36,6 @@
 import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.selectableGroup
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.NavigationBarTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -236,11 +235,15 @@
         // The indicator has a width-expansion animation which interferes with the timing of the
         // ripple, which is why they are separate composables
         val indicatorRipple = @Composable {
+            @Suppress("DEPRECATION_ERROR")
             Box(
                 Modifier
                     .layoutId(IndicatorRippleLayoutIdTag)
                     .clip(NavigationBarTokens.ActiveIndicatorShape.value)
-                    .indication(offsetInteractionSource, rememberRipple())
+                    .indication(
+                        offsetInteractionSource,
+                        androidx.compose.material.ripple.rememberRipple()
+                    )
             )
         }
         val indicator = @Composable {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
index edbc9d9..bb86de8 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
@@ -39,7 +39,6 @@
 import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.selectableGroup
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.NavigationRailTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -237,11 +236,15 @@
         // The indicator has a width-expansion animation which interferes with the timing of the
         // ripple, which is why they are separate composables
         val indicatorRipple = @Composable {
+            @Suppress("DEPRECATION_ERROR")
             Box(
                 Modifier
                     .layoutId(IndicatorRippleLayoutIdTag)
                     .clip(indicatorShape)
-                    .indication(offsetInteractionSource, rememberRipple())
+                    .indication(
+                        offsetInteractionSource,
+                        androidx.compose.material.ripple.rememberRipple()
+                    )
             )
         }
         val indicator = @Composable {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
index d55064c..44ac870 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
@@ -28,7 +28,6 @@
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.selectable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.RadioButtonTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
@@ -85,13 +84,14 @@
     val radioColor = colors.radioColor(enabled, selected)
     val selectableModifier =
         if (onClick != null) {
+            @Suppress("DEPRECATION_ERROR")
             Modifier.selectable(
                 selected = selected,
                 onClick = onClick,
                 enabled = enabled,
                 role = Role.RadioButton,
                 interactionSource = interactionSource,
-                indication = rememberRipple(
+                indication = androidx.compose.material.ripple.rememberRipple(
                     bounded = false,
                     radius = RadioButtonTokens.StateLayerSize / 2
                 )
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
index ecd2960..fb94876 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
@@ -43,7 +43,6 @@
 import androidx.compose.foundation.layout.requiredSizeIn
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.progressSemantics
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.SliderTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
@@ -988,12 +987,13 @@
         }
         val shape = SliderTokens.HandleShape.value
 
+        @Suppress("DEPRECATION_ERROR")
         Spacer(
             modifier
                 .size(thumbSize)
                 .indication(
                     interactionSource = interactionSource,
-                    indication = rememberRipple(
+                    indication = androidx.compose.material.ripple.rememberRipple(
                         bounded = false,
                         radius = SliderTokens.StateLayerSize / 2
                     )
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt
index 82eed15..0b479e3 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt
@@ -26,7 +26,6 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.NonRestartableComposable
@@ -220,6 +219,7 @@
         LocalContentColor provides contentColor,
         LocalAbsoluteTonalElevation provides absoluteElevation
     ) {
+        @Suppress("DEPRECATION_ERROR")
         Box(
             modifier = modifier
                 .minimumInteractiveComponentSize()
@@ -234,7 +234,7 @@
                 )
                 .clickable(
                     interactionSource = interactionSource,
-                    indication = rememberRipple(),
+                    indication = androidx.compose.material.ripple.rememberRipple(),
                     enabled = enabled,
                     onClick = onClick
                 ),
@@ -329,6 +329,7 @@
         LocalContentColor provides contentColor,
         LocalAbsoluteTonalElevation provides absoluteElevation
     ) {
+        @Suppress("DEPRECATION_ERROR")
         Box(
             modifier = modifier
                 .minimumInteractiveComponentSize()
@@ -344,7 +345,7 @@
                 .selectable(
                     selected = selected,
                     interactionSource = interactionSource,
-                    indication = rememberRipple(),
+                    indication = androidx.compose.material.ripple.rememberRipple(),
                     enabled = enabled,
                     onClick = onClick
                 ),
@@ -439,6 +440,7 @@
         LocalContentColor provides contentColor,
         LocalAbsoluteTonalElevation provides absoluteElevation
     ) {
+        @Suppress("DEPRECATION_ERROR")
         Box(
             modifier = modifier
                 .minimumInteractiveComponentSize()
@@ -454,7 +456,7 @@
                 .toggleable(
                     value = checked,
                     interactionSource = interactionSource,
-                    indication = rememberRipple(),
+                    indication = androidx.compose.material.ripple.rememberRipple(),
                     enabled = enabled,
                     onValueChange = onCheckedChange
                 ),
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
index a22cbe7..ebbe7c7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
@@ -16,18 +16,13 @@
 
 package androidx.compose.material3
 
+import androidx.annotation.FloatRange
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.RowScope
-import androidx.compose.material3.DismissDirection.EndToStart
-import androidx.compose.material3.DismissDirection.StartToEnd
-import androidx.compose.material3.DismissState.Companion.Saver
-import androidx.compose.material3.DismissValue.Default
-import androidx.compose.material3.DismissValue.DismissedToEnd
-import androidx.compose.material3.DismissValue.DismissedToStart
+import androidx.compose.material3.SwipeToDismissState.Companion.Saver
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
@@ -52,7 +47,7 @@
  * The directions in which a [SwipeToDismissBox] can be dismissed.
  */
 @ExperimentalMaterial3Api
-enum class DismissDirection {
+enum class SwipeToDismissValue {
     /**
      * Can be dismissed by swiping in the reading direction.
      */
@@ -61,81 +56,38 @@
     /**
      * Can be dismissed by swiping in the reverse of the reading direction.
      */
-    EndToStart
-}
-
-/**
- * Possible values of [DismissState].
- */
-@ExperimentalMaterial3Api
-enum class DismissValue {
-    /**
-     * Indicates the component has not been dismissed yet.
-     */
-    Default,
+    EndToStart,
 
     /**
-     * Indicates the component has been dismissed in the reading direction.
+     * Cannot currently be dismissed.
      */
-    DismissedToEnd,
-
-    /**
-     * Indicates the component has been dismissed in the reverse of the reading direction.
-     */
-    DismissedToStart
+    Settled
 }
 
 /**
  * State of the [SwipeToDismissBox] composable.
  *
  * @param initialValue The initial value of the state.
+ * @param density The density that this state can use to convert values to and from dp.
  * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
  * @param positionalThreshold The positional threshold to be used when calculating the target state
  * while a swipe is in progress and when settling after the swipe ends. This is the distance from
  * the start of a transition. It will be, depending on the direction of the interaction, added or
  * subtracted from/to the origin offset. It should always be a positive value.
  */
-@OptIn(ExperimentalMaterial3Api::class)
-class DismissState @Deprecated(
-    message = "This constructor is deprecated. " +
-        "Please use the constructor that provides a [Density]",
-    replaceWith = ReplaceWith(
-        "DismissState(" +
-            "initialValue, LocalDensity.current, confirmValueChange, positionalThreshold)"
-    )
-) constructor(
-    initialValue: DismissValue,
-    confirmValueChange: (DismissValue) -> Boolean = { true },
+@ExperimentalMaterial3Api
+class SwipeToDismissState(
+    initialValue: SwipeToDismissValue,
+    internal val density: Density,
+    confirmValueChange: (SwipeToDismissValue) -> Boolean = { true },
     positionalThreshold: (totalDistance: Float) -> Float
 ) {
-
-    /**
-     * State of the [SwipeToDismissBox] composable.
-     *
-     * @param initialValue The initial value of the state.
-     * @param density The density that this state can use to convert values to and from dp.
-     * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
-     * @param positionalThreshold The positional threshold to be used when calculating the target state
-     * while a swipe is in progress and when settling after the swipe ends. This is the distance from
-     * the start of a transition. It will be, depending on the direction of the interaction, added or
-     * subtracted from/to the origin offset. It should always be a positive value.
-     */
-    @Suppress("Deprecation")
-    constructor(
-        initialValue: DismissValue,
-        density: Density,
-        confirmValueChange: (DismissValue) -> Boolean = { true },
-        positionalThreshold: (totalDistance: Float) -> Float
-    ) : this(initialValue, confirmValueChange, positionalThreshold) {
-        this.density = density
-    }
-
     internal val anchoredDraggableState = AnchoredDraggableState(
         initialValue = initialValue,
         animationSpec = AnchoredDraggableDefaults.AnimationSpec,
         confirmValueChange = confirmValueChange,
         positionalThreshold = positionalThreshold,
-        velocityThreshold = { with(requireDensity()) { DismissThreshold.toPx() } }
+        velocityThreshold = { with(density) { DismissThreshold.toPx() } }
     )
 
     internal val offset: Float get() = anchoredDraggableState.offset
@@ -148,40 +100,53 @@
     fun requireOffset(): Float = anchoredDraggableState.requireOffset()
 
     /**
-     * The current state value of the [DismissState].
+     * The current state value of the [SwipeToDismissState].
      */
-    val currentValue: DismissValue get() = anchoredDraggableState.currentValue
+    val currentValue: SwipeToDismissValue get() = anchoredDraggableState.currentValue
 
     /**
      * The target state. This is the closest state to the current offset (taking into account
      * positional thresholds). If no interactions like animations or drags are in progress, this
      * will be the current state.
      */
-    val targetValue: DismissValue get() = anchoredDraggableState.targetValue
+    val targetValue: SwipeToDismissValue get() = anchoredDraggableState.targetValue
 
     /**
      * The fraction of the progress going from currentValue to targetValue, within [0f..1f] bounds.
      */
+    @get:FloatRange(from = 0.0, to = 1.0)
     val progress: Float get() = anchoredDraggableState.progress
 
     /**
      * The direction (if any) in which the composable has been or is being dismissed.
      *
-     * If the composable is settled at the default state, then this will be null. Use this to
-     * change the background of the [SwipeToDismissBox] if you want different actions on each side.
+     * Use this to change the background of the [SwipeToDismissBox] if you want different actions on each
+     * side.
      */
-    val dismissDirection: DismissDirection?
+    val dismissDirection: SwipeToDismissValue
         get() = if (offset == 0f || offset.isNaN())
-            null
-        else if (offset > 0f) StartToEnd else EndToStart
+            SwipeToDismissValue.Settled
+        else if (offset > 0f) SwipeToDismissValue.StartToEnd else SwipeToDismissValue.EndToStart
 
     /**
      * Whether the component has been dismissed in the given [direction].
      *
      * @param direction The dismiss direction.
      */
+    @Deprecated(
+        message = "DismissDirection is no longer used by SwipeToDismissState. Please compare " +
+            "currentValue against SwipeToDismissValue instead.",
+        level = DeprecationLevel.HIDDEN
+    )
+    @Suppress("DEPRECATION")
     fun isDismissed(direction: DismissDirection): Boolean {
-        return currentValue == if (direction == StartToEnd) DismissedToEnd else DismissedToStart
+        return currentValue == (
+                if (direction == DismissDirection.StartToEnd) {
+                    SwipeToDismissValue.StartToEnd
+                } else {
+                    SwipeToDismissValue.EndToStart
+                }
+            )
     }
 
     /**
@@ -189,7 +154,7 @@
      *
      * @param targetValue The new target value
      */
-    suspend fun snapTo(targetValue: DismissValue) {
+    suspend fun snapTo(targetValue: SwipeToDismissValue) {
         anchoredDraggableState.snapTo(targetValue)
     }
 
@@ -200,7 +165,9 @@
      *
      * @return the reason the reset animation ended
      */
-    suspend fun reset() = anchoredDraggableState.animateTo(targetValue = Default)
+    suspend fun reset() = anchoredDraggableState.animateTo(
+        targetValue = SwipeToDismissValue.Settled
+    )
 
     /**
      * Dismiss the component in the given [direction], with an animation and suspend. This method
@@ -208,64 +175,32 @@
      *
      * @param direction The dismiss direction.
      */
-    suspend fun dismiss(direction: DismissDirection) {
-        val targetValue = if (direction == StartToEnd) DismissedToEnd else DismissedToStart
-        anchoredDraggableState.animateTo(targetValue = targetValue)
-    }
-
-    internal var density: Density? = null
-    private fun requireDensity() = requireNotNull(density) {
-        "DismissState did not have a density attached. Are you using DismissState with " +
-            "the SwipeDismiss component?"
+    suspend fun dismiss(direction: SwipeToDismissValue) {
+        anchoredDraggableState.animateTo(targetValue = direction)
     }
 
     companion object {
 
         /**
-         * The default [Saver] implementation for [DismissState].
+         * The default [Saver] implementation for [SwipeToDismissState].
          */
         fun Saver(
-            confirmValueChange: (DismissValue) -> Boolean,
+            confirmValueChange: (SwipeToDismissValue) -> Boolean,
             positionalThreshold: (totalDistance: Float) -> Float,
             density: Density
-        ) =
-            Saver<DismissState, DismissValue>(
-                save = { it.currentValue },
-                restore = {
-                    DismissState(
-                        it, density, confirmValueChange, positionalThreshold
-                    )
-                }
-            )
-
-        /**
-         * The default [Saver] implementation for [DismissState].
-         */
-        @Deprecated(
-            message = "This function is deprecated. Please use the overload where Density is" +
-                " provided.",
-            replaceWith = ReplaceWith(
-                "Saver(confirmValueChange, positionalThreshold, LocalDensity.current)"
-            )
+        ) = Saver<SwipeToDismissState, SwipeToDismissValue>(
+            save = { it.currentValue },
+            restore = {
+                SwipeToDismissState(
+                    it, density, confirmValueChange, positionalThreshold
+                )
+            }
         )
-        @Suppress("Deprecation")
-        fun Saver(
-            confirmValueChange: (DismissValue) -> Boolean,
-            positionalThreshold: (totalDistance: Float) -> Float,
-        ) =
-            Saver<DismissState, DismissValue>(
-                save = { it.currentValue },
-                restore = {
-                    DismissState(
-                        it, confirmValueChange, positionalThreshold
-                    )
-                }
-            )
     }
 }
 
 /**
- * Create and [remember] a [DismissState].
+ * Create and [remember] a [SwipeToDismissState].
  *
  * @param initialValue The initial value of the state.
  * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
@@ -276,12 +211,12 @@
  */
 @Composable
 @ExperimentalMaterial3Api
-fun rememberDismissState(
-    initialValue: DismissValue = Default,
-    confirmValueChange: (DismissValue) -> Boolean = { true },
+fun rememberSwipeToDismissState(
+    initialValue: SwipeToDismissValue = SwipeToDismissValue.Settled,
+    confirmValueChange: (SwipeToDismissValue) -> Boolean = { true },
     positionalThreshold: (totalDistance: Float) -> Float =
-        SwipeToDismissBoxDefaults.fixedPositionalThreshold,
-): DismissState {
+        SwipeToDismissBoxDefaults.positionalThreshold,
+): SwipeToDismissState {
     val density = LocalDensity.current
     return rememberSaveable(
         saver = Saver(
@@ -290,7 +225,7 @@
             positionalThreshold = positionalThreshold
         )
     ) {
-        DismissState(initialValue, density, confirmValueChange, positionalThreshold)
+        SwipeToDismissState(initialValue, density, confirmValueChange, positionalThreshold)
     }
 }
 
@@ -311,16 +246,26 @@
     level = DeprecationLevel.WARNING,
     message = "Use SwipeToDismissBox instead",
     replaceWith =
-        ReplaceWith("SwipeToDismissBox(state, background, modifier, directions, dismissContent)")
+        ReplaceWith("SwipeToDismissBox(state, background, modifier, " +
+            "enableDismissFromStartToEnd, enableDismissFromEndToStart, dismissContent)")
 )
 @ExperimentalMaterial3Api
 fun SwipeToDismiss(
-    state: DismissState,
+    state: SwipeToDismissState,
     background: @Composable RowScope.() -> Unit,
     dismissContent: @Composable RowScope.() -> Unit,
     modifier: Modifier = Modifier,
-    directions: Set<DismissDirection> = setOf(EndToStart, StartToEnd),
-) = SwipeToDismissBox(state, background, modifier, directions, dismissContent)
+    directions: Set<SwipeToDismissValue> = setOf(SwipeToDismissValue.EndToStart,
+        SwipeToDismissValue.StartToEnd
+    ),
+) = SwipeToDismissBox(
+    state = state,
+    backgroundContent = background,
+    modifier = modifier,
+    enableDismissFromStartToEnd = SwipeToDismissValue.StartToEnd in directions,
+    enableDismissFromEndToStart = SwipeToDismissValue.EndToStart in directions,
+    content = dismissContent
+)
 
 /**
  * A composable that can be dismissed by swiping left or right.
@@ -328,27 +273,23 @@
  * @sample androidx.compose.material3.samples.SwipeToDismissListItems
  *
  * @param state The state of this component.
- * @param backgroundContent A composable that is stacked behind the content and is exposed when the
+ * @param backgroundContent A composable that is stacked behind the [content] and is exposed when the
  * content is swiped. You can/should use the [state] to have different backgrounds on each side.
- * @param content The content that can be dismissed.
  * @param modifier Optional [Modifier] for this component.
- * @param directions The set of directions in which the component can be dismissed.
+ * @param enableDismissFromStartToEnd Whether SwipeToDismissBox can be dismissed from start to end.
+ * @param enableDismissFromEndToStart Whether SwipeToDismissBox can be dismissed from end to start.
+ * @param content The content that can be dismissed.
  */
 @Composable
 @ExperimentalMaterial3Api
 fun SwipeToDismissBox(
-    state: DismissState,
+    state: SwipeToDismissState,
     backgroundContent: @Composable RowScope.() -> Unit,
     modifier: Modifier = Modifier,
-    directions: Set<DismissDirection> = setOf(EndToStart, StartToEnd),
+    enableDismissFromStartToEnd: Boolean = true,
+    enableDismissFromEndToStart: Boolean = true,
     content: @Composable RowScope.() -> Unit,
 ) {
-    // b/278692145 Remove this once deprecated methods without density are removed
-    val density = LocalDensity.current
-    SideEffect {
-        state.density = density
-    }
-
     val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
 
     Box(
@@ -356,7 +297,7 @@
             .anchoredDraggable(
                 state = state.anchoredDraggableState,
                 orientation = Orientation.Horizontal,
-                enabled = state.currentValue == Default,
+                enabled = state.currentValue == SwipeToDismissValue.Settled,
                 reverseDirection = isRtl,
             ),
         propagateMinConstraints = true
@@ -367,66 +308,134 @@
         )
         Row(
             content = content,
-            modifier = Modifier.swipeDismissAnchors(state, directions)
+            modifier = Modifier.swipeToDismissAnchors(
+                state,
+                enableDismissFromStartToEnd,
+                enableDismissFromEndToStart
+            )
         )
     }
 }
 
-/** Contains default values for [SwipeToDismissBox] and [DismissState]. */
+/** Contains default values for [SwipeToDismissBox] and [SwipeToDismissState]. */
 @ExperimentalMaterial3Api
 object SwipeToDismissBoxDefaults {
-    /** Default positional threshold of 56.dp for [DismissState]. */
-    val fixedPositionalThreshold: (totalDistance: Float) -> Float
+    /** Default positional threshold of 56.dp for [SwipeToDismissState]. */
+    val positionalThreshold: (totalDistance: Float) -> Float
         @Composable get() = with(LocalDensity.current) {
             { 56.dp.toPx() }
         }
 }
 
+/**
+ * The directions in which a [SwipeToDismissBox] can be dismissed.
+ */
+@ExperimentalMaterial3Api
+@Deprecated(
+    message = "Dismiss direction is no longer used by SwipeToDismissState. Please use " +
+        "SwipeToDismissValue instead.",
+    level = DeprecationLevel.WARNING
+)
+enum class DismissDirection {
+    /**
+     * Can be dismissed by swiping in the reading direction.
+     */
+    StartToEnd,
+
+    /**
+     * Can be dismissed by swiping in the reverse of the reading direction.
+     */
+    EndToStart,
+}
+
+/**
+ * Possible values of [SwipeToDismissState].
+ */
+@ExperimentalMaterial3Api
+@Deprecated(
+    message = "DismissValue is no longer used by SwipeToDismissState. Please use " +
+        "SwipeToDismissValue instead.",
+    level = DeprecationLevel.WARNING
+)
+enum class DismissValue {
+    /**
+     * Indicates the component has not been dismissed yet.
+     */
+    Default,
+
+    /**
+     * Indicates the component has been dismissed in the reading direction.
+     */
+    DismissedToEnd,
+
+    /**
+     * Indicates the component has been dismissed in the reverse of the reading direction.
+     */
+    DismissedToStart
+}
+
 private val DismissThreshold = 125.dp
 
 @OptIn(ExperimentalMaterial3Api::class)
-private fun Modifier.swipeDismissAnchors(state: DismissState, directions: Set<DismissDirection>) =
-    this then SwipeDismissAnchorsElement(state, directions)
+private fun Modifier.swipeToDismissAnchors(
+    state: SwipeToDismissState,
+    enableDismissFromStartToEnd: Boolean,
+    enableDismissFromEndToStart: Boolean
+) = this then SwipeToDismissAnchorsElement(
+    state,
+    enableDismissFromStartToEnd,
+    enableDismissFromEndToStart
+)
 
 @OptIn(ExperimentalMaterial3Api::class)
-private class SwipeDismissAnchorsElement(
-    private val state: DismissState,
-    private val directions: Set<DismissDirection>,
-) : ModifierNodeElement<SwipeDismissAnchorsNode>() {
+private class SwipeToDismissAnchorsElement(
+    private val state: SwipeToDismissState,
+    private val enableDismissFromStartToEnd: Boolean,
+    private val enableDismissFromEndToStart: Boolean,
+) : ModifierNodeElement<SwipeToDismissAnchorsNode>() {
 
-    override fun create() = SwipeDismissAnchorsNode(state, directions)
+    override fun create() = SwipeToDismissAnchorsNode(
+        state,
+        enableDismissFromStartToEnd,
+        enableDismissFromEndToStart,
+    )
 
-    override fun update(node: SwipeDismissAnchorsNode) {
+    override fun update(node: SwipeToDismissAnchorsNode) {
         node.state = state
-        node.directions = directions
+        node.enableDismissFromStartToEnd = enableDismissFromStartToEnd
+        node.enableDismissFromEndToStart = enableDismissFromEndToStart
     }
 
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
-        other as SwipeDismissAnchorsElement
+        other as SwipeToDismissAnchorsElement
         if (state != other.state) return false
-        if (directions != other.directions) return false
+        if (enableDismissFromStartToEnd != other.enableDismissFromStartToEnd) return false
+        if (enableDismissFromEndToStart != other.enableDismissFromEndToStart) return false
         return true
     }
 
     override fun hashCode(): Int {
         var result = state.hashCode()
-        result = 31 * result + directions.hashCode()
+        result = 31 * result + enableDismissFromStartToEnd.hashCode()
+        result = 31 * result + enableDismissFromEndToStart.hashCode()
         return result
     }
 
     override fun InspectorInfo.inspectableProperties() {
         debugInspectorInfo {
             properties["state"] = state
-            properties["directions"] = directions
+            properties["enableDismissFromStartToEnd"] = enableDismissFromStartToEnd
+            properties["enableDismissFromEndToStart"] = enableDismissFromEndToStart
         }
     }
 }
 
 @OptIn(ExperimentalMaterial3Api::class)
-private class SwipeDismissAnchorsNode(
-    var state: DismissState,
-    var directions: Set<DismissDirection>
+private class SwipeToDismissAnchorsNode(
+    var state: SwipeToDismissState,
+    var enableDismissFromStartToEnd: Boolean,
+    var enableDismissFromEndToStart: Boolean,
 ) : Modifier.Node(), LayoutModifierNode {
     private var didLookahead: Boolean = false
 
@@ -445,12 +454,12 @@
         if (isLookingAhead || !didLookahead) {
             val width = placeable.width.toFloat()
             val newAnchors = DraggableAnchors {
-                Default at 0f
-                if (StartToEnd in directions) {
-                    DismissedToEnd at width
+                SwipeToDismissValue.Settled at 0f
+                if (enableDismissFromStartToEnd) {
+                    SwipeToDismissValue.StartToEnd at width
                 }
-                if (EndToStart in directions) {
-                    DismissedToStart at -width
+                if (enableDismissFromEndToStart) {
+                    SwipeToDismissValue.EndToStart at -width
                 }
             }
             state.anchoredDraggableState.updateAnchors(newAnchors)
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
index f3617ab3..9b0e46a 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
@@ -33,7 +33,6 @@
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.SwitchTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -222,13 +221,17 @@
 
     Box(modifier) {
         val resolvedThumbColor = colors.thumbColor(enabled, checked)
+        @Suppress("DEPRECATION_ERROR")
         Box(
             modifier = Modifier
                 .align(Alignment.CenterStart)
                 .offset { IntOffset(thumbOffset.roundToInt(), 0) }
                 .indication(
                     interactionSource = interactionSource,
-                    indication = rememberRipple(bounded = false, SwitchTokens.StateLayerSize / 2)
+                    indication = androidx.compose.material.ripple.rememberRipple(
+                        bounded = false,
+                        SwitchTokens.StateLayerSize / 2
+                    )
                 )
                 .requiredSize(thumbSizeDp)
                 .background(resolvedThumbColor, thumbShape),
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
index c02ecd2..ba87bba 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
@@ -33,7 +33,6 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.selection.selectable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.PrimaryNavigationTabTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -166,7 +165,11 @@
     // The color of the Ripple should always the be selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
     // provided by TabTransition.
-    val ripple = rememberRipple(bounded = true, color = selectedContentColor)
+    @Suppress("DEPRECATION_ERROR")
+    val ripple = androidx.compose.material.ripple.rememberRipple(
+        bounded = true,
+        color = selectedContentColor
+    )
 
     TabTransition(selectedContentColor, unselectedContentColor, selected) {
         Row(
@@ -237,7 +240,11 @@
     // The color of the Ripple should always the selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
     // provided by TabTransition.
-    val ripple = rememberRipple(bounded = true, color = selectedContentColor)
+    @Suppress("DEPRECATION_ERROR")
+    val ripple = androidx.compose.material.ripple.rememberRipple(
+        bounded = true,
+        color = selectedContentColor
+    )
 
     TabTransition(selectedContentColor, unselectedContentColor, selected) {
         Column(
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
index f37a97b..e9c9f99 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
@@ -16,8 +16,11 @@
 
 package androidx.compose.material3
 
+import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.AnimationVector1D
 import androidx.compose.animation.core.FastOutSlowInEasing
+import androidx.compose.animation.core.VectorConverter
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.ScrollState
@@ -28,7 +31,8 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.requiredHeight
+import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.rememberScrollState
@@ -38,7 +42,9 @@
 import androidx.compose.material3.tokens.SecondaryNavigationTabTokens
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
@@ -47,8 +53,16 @@
 import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.layout.SubcomposeLayout
+import androidx.compose.ui.layout.layout
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.platform.InspectorInfo
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
@@ -136,14 +150,14 @@
     modifier: Modifier = Modifier,
     containerColor: Color = TabRowDefaults.primaryContainerColor,
     contentColor: Color = TabRowDefaults.primaryContentColor,
-    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions ->
-        if (selectedTabIndex < tabPositions.size) {
-            val width by animateDpAsState(targetValue = tabPositions[selectedTabIndex].contentWidth)
-            TabRowDefaults.PrimaryIndicator(
-                Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]),
-                width = width
-            )
-        }
+    indicator: @Composable TabIndicatorScope.() -> Unit = {
+        TabRowDefaults.PrimaryIndicator(
+            modifier = Modifier.tabIndicatorOffset(
+                selectedTabIndex,
+                matchContentSize = true
+            ),
+            width = Dp.Unspecified,
+        )
     },
     divider: @Composable () -> Unit = @Composable {
         HorizontalDivider()
@@ -193,12 +207,10 @@
     modifier: Modifier = Modifier,
     containerColor: Color = TabRowDefaults.secondaryContainerColor,
     contentColor: Color = TabRowDefaults.secondaryContentColor,
-    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions ->
-        if (selectedTabIndex < tabPositions.size) {
-            TabRowDefaults.SecondaryIndicator(
-                Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
-            )
-        }
+    indicator: @Composable TabIndicatorScope.() -> Unit = @Composable {
+        TabRowDefaults.SecondaryIndicator(
+            Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false)
+        )
     },
     divider: @Composable () -> Unit = @Composable {
         HorizontalDivider()
@@ -299,7 +311,46 @@
     },
     tabs: @Composable () -> Unit
 ) {
-    TabRowImpl(modifier, containerColor, contentColor, indicator, divider, tabs)
+    TabRowWithSubcomposeImpl(modifier, containerColor, contentColor, indicator, divider, tabs)
+}
+
+/**
+ * Scope for the composable used to render a Tab indicator,
+ * this can be used for more complex indicators requiring layout information about the tabs
+ * like [TabRowDefaults.PrimaryIndicator] and [TabRowDefaults.SecondaryIndicator]
+ */
+interface TabIndicatorScope {
+
+    /**
+     * A layout modifier that provides tab positions, this can be used to animate and layout
+     * a TabIndicator depending on size, position, and content size of each Tab.
+     *
+     * @sample androidx.compose.material3.samples.FancyAnimatedIndicatorWithModifier
+     */
+    fun Modifier.tabIndicatorLayout(
+        measure: MeasureScope.(
+            Measurable,
+            Constraints,
+            List<TabPosition>,
+        ) -> MeasureResult
+    ): Modifier
+
+    /**
+     * A Modifier that follows the default offset and animation
+     *
+     * @param selectedTabIndex the index of the current selected tab
+     * @param matchContentSize this modifier can also animate the width of the indicator \
+     * to match the content size of the tab.
+     */
+    fun Modifier.tabIndicatorOffset(
+        selectedTabIndex: Int,
+        matchContentSize: Boolean = false
+    ): Modifier
+}
+
+internal interface TabPositionsHolder {
+
+    fun setTabPositions(positions: List<TabPosition>)
 }
 
 @Composable
@@ -307,6 +358,223 @@
     modifier: Modifier,
     containerColor: Color,
     contentColor: Color,
+    indicator: @Composable TabIndicatorScope.() -> Unit,
+    divider: @Composable () -> Unit,
+    tabs: @Composable () -> Unit
+) {
+    Surface(
+        modifier = modifier.selectableGroup(),
+        color = containerColor,
+        contentColor = contentColor
+    ) {
+        val scope = remember {
+            object : TabIndicatorScope, TabPositionsHolder {
+
+                val tabPositions = mutableStateOf<(List<TabPosition>)>(listOf())
+
+                override fun Modifier.tabIndicatorLayout(
+                    measure: MeasureScope.(
+                        Measurable,
+                        Constraints,
+                        List<TabPosition>,
+                    ) -> MeasureResult
+                ): Modifier =
+                    this.layout { measurable: Measurable, constraints: Constraints ->
+                        measure(
+                            measurable,
+                            constraints,
+                            tabPositions.value,
+                        )
+                    }
+
+                override fun Modifier.tabIndicatorOffset(
+                    selectedTabIndex: Int,
+                    matchContentSize: Boolean
+                ): Modifier =
+                    this.then(
+                        TabIndicatorModifier(
+                            tabPositions,
+                            selectedTabIndex,
+                            matchContentSize
+                        )
+                    )
+
+                override fun setTabPositions(positions: List<TabPosition>) {
+                    tabPositions.value = positions
+                }
+            }
+        }
+
+        Layout(
+            modifier = Modifier.fillMaxWidth(),
+            contents = listOf(
+                tabs,
+                divider,
+                { scope.indicator() },
+            )
+        ) { (tabMeasurables, dividerMeasurables, indicatorMeasurables), constraints ->
+            val tabRowWidth = constraints.maxWidth
+            val tabCount = tabMeasurables.size
+            var tabWidth = 0
+            if (tabCount > 0) {
+                tabWidth = (tabRowWidth / tabCount)
+            }
+            val tabRowHeight = tabMeasurables.fastFold(initial = 0) { max, curr ->
+                maxOf(curr.maxIntrinsicHeight(tabWidth), max)
+            }
+
+            scope.setTabPositions(List(tabCount) { index ->
+                var contentWidth =
+                    minOf(
+                        tabMeasurables[index].maxIntrinsicWidth(tabRowHeight),
+                        tabWidth
+                    ).toDp()
+                contentWidth -= HorizontalTextPadding * 2
+                // Enforce minimum touch target of 24.dp
+                val indicatorWidth = maxOf(contentWidth, 24.dp)
+
+                TabPosition(tabWidth.toDp() * index, tabWidth.toDp(), indicatorWidth)
+            })
+
+            val tabPlaceables = tabMeasurables.fastMap {
+                it.measure(
+                    constraints.copy(
+                        minWidth = tabWidth,
+                        maxWidth = tabWidth,
+                        minHeight = tabRowHeight,
+                        maxHeight = tabRowHeight,
+                    )
+                )
+            }
+
+            val dividerPlaceables = dividerMeasurables.fastMap {
+                it.measure(constraints.copy(minHeight = 0))
+            }
+
+            val indicatorPlaceables = indicatorMeasurables.fastMap {
+                it.measure(
+                    constraints.copy(
+                        minWidth = tabWidth,
+                        maxWidth = tabWidth,
+                        maxHeight = tabRowHeight
+                    )
+                )
+            }
+
+            layout(tabRowWidth, tabRowHeight) {
+                tabPlaceables.fastForEachIndexed { index, placeable ->
+                    placeable.placeRelative(index * tabWidth, 0)
+                }
+
+                dividerPlaceables.fastForEach { placeable ->
+                    placeable.placeRelative(0, tabRowHeight - placeable.height)
+                }
+
+                indicatorPlaceables.fastForEach {
+                    it.placeRelative(0, tabRowHeight - it.height)
+                }
+            }
+        }
+    }
+}
+
+internal data class TabIndicatorModifier(
+    val tabPositionsState: State<List<TabPosition>>,
+    val selectedTabIndex: Int,
+    val followContentSize: Boolean,
+) : ModifierNodeElement<TabIndicatorOffsetNode>() {
+
+    override fun create(): TabIndicatorOffsetNode {
+        return TabIndicatorOffsetNode(
+            tabPositionsState = tabPositionsState,
+            selectedTabIndex = selectedTabIndex,
+            followContentSize = followContentSize,
+        )
+    }
+
+    override fun update(node: TabIndicatorOffsetNode) {
+        node.tabPositionsState = tabPositionsState
+        node.selectedTabIndex = selectedTabIndex
+        node.followContentSize = followContentSize
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        // Show nothing in the inspector.
+    }
+}
+
+internal class TabIndicatorOffsetNode(
+    var tabPositionsState: State<List<TabPosition>>,
+    var selectedTabIndex: Int,
+    var followContentSize: Boolean
+) : Modifier.Node(), LayoutModifierNode {
+
+    private var offsetAnimatable: Animatable<Dp, AnimationVector1D>? = null
+    private var widthAnimatable: Animatable<Dp, AnimationVector1D>? = null
+    private var initialOffset: Dp? = null
+    private var initialWidth: Dp? = null
+
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints
+    ): MeasureResult {
+        if (tabPositionsState.value.isEmpty()) {
+            return layout(0, 0) { }
+        }
+
+        val currentTabWidth = tabPositionsState.value[selectedTabIndex].contentWidth
+        if (followContentSize) {
+            if (initialWidth != null) {
+                val widthAnim =
+                    widthAnimatable ?: Animatable(initialWidth!!, Dp.VectorConverter).also {
+                        widthAnimatable = it
+                    }
+
+                if (currentTabWidth != widthAnim.targetValue) {
+                    coroutineScope.launch { widthAnim.animateTo(currentTabWidth) }
+                }
+            } else {
+                initialWidth = currentTabWidth
+            }
+        }
+
+        val indicatorOffset = tabPositionsState.value[selectedTabIndex].left
+
+        if (initialOffset != null) {
+            val offsetAnim =
+                offsetAnimatable ?: Animatable(initialOffset!!, Dp.VectorConverter).also {
+                    offsetAnimatable = it
+                }
+
+            if (indicatorOffset != offsetAnim.targetValue) {
+                coroutineScope.launch { offsetAnim.animateTo(indicatorOffset) }
+            }
+        } else {
+            initialOffset = indicatorOffset
+        }
+
+        val offset = offsetAnimatable?.value ?: indicatorOffset
+
+        val placeable = measurable.measure(
+            if (followContentSize) {
+                val width = widthAnimatable?.value ?: currentTabWidth
+                constraints.copy(minWidth = width.roundToPx(), maxWidth = width.roundToPx())
+            } else {
+                constraints
+            }
+        )
+
+        return layout(placeable.width, constraints.maxHeight) {
+            placeable.place(offset.roundToPx(), constraints.maxHeight - placeable.height)
+        }
+    }
+}
+
+@Composable
+private fun TabRowWithSubcomposeImpl(
+    modifier: Modifier,
+    containerColor: Color,
+    contentColor: Color,
     indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,
     divider: @Composable () -> Unit,
     tabs: @Composable () -> Unit
@@ -819,7 +1087,8 @@
     ) {
         Spacer(
             modifier
-                .requiredSize(width, height)
+                .requiredHeight(height)
+                .requiredWidth(width)
                 .background(color = color, shape = shape)
         )
     }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
index c176e55..1aedbba 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
@@ -58,7 +58,7 @@
     val shape: Shape @Composable get() = FilledTextFieldTokens.ContainerShape.value
 
     /**
-     * The default min width applied to a [TextField].
+     * The default min height applied to a [TextField].
      * Note that you can override it by applying Modifier.heightIn directly on a text field.
      */
     val MinHeight = 56.dp
@@ -1348,7 +1348,7 @@
     val shape: Shape @Composable get() = OutlinedTextFieldTokens.ContainerShape.value
 
     /**
-     * The default min width applied to an [OutlinedTextField].
+     * The default min height applied to an [OutlinedTextField].
      * Note that you can override it by applying Modifier.heightIn directly on a text field.
      */
     val MinHeight = 56.dp
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt
index af153c2..8532acf 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt
@@ -129,13 +129,13 @@
         // Transparent components interfere with Talkback (b/261061240), so if any components below
         // have alpha == 0, we set the component to null instead.
 
+        val placeholderColor = colors.placeholderColor(enabled, isError, interactionSource).value
         val decoratedPlaceholder: @Composable ((Modifier) -> Unit)? =
             if (placeholder != null && transformedText.isEmpty() && placeholderAlphaProgress > 0f) {
                 @Composable { modifier ->
                     Box(modifier.alpha(placeholderAlphaProgress)) {
                         Decoration(
-                            contentColor =
-                                colors.placeholderColor(enabled, isError, interactionSource).value,
+                            contentColor = placeholderColor,
                             typography = MaterialTheme.typography.bodyLarge,
                             content = placeholder
                         )
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt
index 749ba5f..f46c597 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt
@@ -28,7 +28,6 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.CircularIndicatorDiameter
 import androidx.compose.material3.CircularProgressIndicator
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.LocalContentColor
@@ -123,7 +122,7 @@
     CompositionLocalProvider(LocalContentColor provides contentColor) {
         Box(
             modifier = modifier
-                .size(CircularIndicatorDiameter)
+                .size(SpinnerContainerSize)
                 .graphicsLayer {
                     translationY = state.verticalOffset - size.height
                 }
@@ -469,7 +468,7 @@
         size = arcBounds.size,
         style = Stroke(
             width = strokeWidth.toPx(),
-            cap = StrokeCap.Square
+            cap = StrokeCap.Butt
         )
     )
 }
@@ -512,25 +511,23 @@
 ) {
     arrow.reset()
     arrow.moveTo(0f, 0f) // Move to left corner
-    arrow.lineTo(x = ArrowWidth.toPx() * values.scale, y = 0f) // Line to right corner
-
     // Line to tip of arrow
     arrow.lineTo(
         x = ArrowWidth.toPx() * values.scale / 2,
         y = ArrowHeight.toPx() * values.scale
     )
+    arrow.lineTo(x = ArrowWidth.toPx() * values.scale, y = 0f) // Line to right corner
 
     val radius = min(bounds.width, bounds.height) / 2f
     val inset = ArrowWidth.toPx() * values.scale / 2f
     arrow.translate(
         Offset(
             x = radius + bounds.center.x - inset,
-            y = bounds.center.y + strokeWidth.toPx() / 2f
+            y = bounds.center.y - strokeWidth.toPx()
         )
     )
-    arrow.close()
-    rotate(degrees = values.endAngle) {
-        drawPath(path = arrow, color = color, alpha = alpha)
+    rotate(degrees = values.endAngle - strokeWidth.toPx()) {
+        drawPath(path = arrow, color = color, alpha = alpha, style = Stroke(strokeWidth.toPx()))
     }
 }
 
@@ -539,8 +536,9 @@
 
 /** The default stroke width for [Indicator] */
 private val StrokeWidth = 2.5.dp
-private val ArcRadius = 7.5.dp
-private val SpinnerSize = 20.dp // (ArcRadius + PullRefreshIndicatorDefaults.StrokeWidth).times(2)
+private val ArcRadius = 5.5.dp
+internal val SpinnerSize = 16.dp // (ArcRadius + PullRefreshIndicatorDefaults.StrokeWidth).times(2)
+internal val SpinnerContainerSize = 40.dp
 private val Elevation = ElevationTokens.Level2
 private val ArrowWidth = 10.dp
 private val ArrowHeight = 5.dp
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
index 1dffaac..1c36c42 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
@@ -79,6 +79,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -115,6 +116,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -151,6 +153,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -187,6 +190,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -223,6 +227,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -256,37 +261,38 @@
     @Test
     fun testStateDelegate_withInferredType_andInternalSetter_thatCouldBeMutablePrimitiveStateOf() {
         lint().files(
-                primitiveStateStub,
-                Stubs.Composable,
-                Stubs.SnapshotState,
-                kotlin(
-                    """
-                    package androidx.compose.runtime.lint.test
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
+            kotlin(
+                """
+                package androidx.compose.runtime.lint.test
 
-                    import androidx.compose.runtime.*
-                    import $fqType
+                import androidx.compose.runtime.*
+                import $fqType
 
-                    class Test(initialValue: $type = $stateValue) {
-                        var state by mutableStateOf(initialValue)
-                            private set
-                    }
-                """
-                )
-            ).run().expect(
-                """
-src/androidx/compose/runtime/lint/test/Test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
-                        var state by mutableStateOf(initialValue)
-                                     ~~~~~~~~~~~~~~
-0 errors, 0 warnings
-            """
-            ).expectFixDiffs(
-                """
-Fix for src/androidx/compose/runtime/lint/test/Test.kt line 7: Replace with mutable${type}StateOf:
-@@ -8 +8
--                         var state by mutableStateOf(initialValue)
-+                         var state by mutable${type}StateOf(initialValue)
+                class Test(initialValue: $type = $stateValue) {
+                    var state by mutableStateOf(initialValue)
+                        private set
+                }
             """
             )
+        ).run().expect(
+                """
+src/androidx/compose/runtime/lint/test/Test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                    var state by mutableStateOf(initialValue)
+                                 ~~~~~~~~~~~~~~
+0 errors, 0 warnings
+            """
+        ).expectFixDiffs(
+                """
+Fix for src/androidx/compose/runtime/lint/test/Test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                     var state by mutableStateOf(initialValue)
++                     var state by mutable${type}StateOf(initialValue)
+            """
+        )
     }
 
     @Test
@@ -295,6 +301,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -331,6 +338,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -353,6 +361,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -389,6 +398,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -411,6 +421,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -433,6 +444,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
@@ -455,6 +467,7 @@
             primitiveStateStub,
             Stubs.Composable,
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             kotlin(
                 """
                     package androidx.compose.runtime.lint.test
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
index 5bac151..ed6258f 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
@@ -106,7 +106,7 @@
         private val AutoboxingStateValuePropertyStub = bytecodeStub(
             filename = "AutoboxingStateValueProperty.kt",
             filepath = "androidx/compose/runtime/snapshots",
-            checksum = 0x2c564988,
+            checksum = 0xd8b7ebd3,
             source = """
                 package androidx.compose.runtime.snapshots
 
@@ -117,33 +117,33 @@
                 )
             """,
             """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijg0uaSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeIPzkssKM7ILwkuSSxJ9S7h0uFSwqVYLyczr0SvJLW4RIgtBEh6
-                lygxaDEAAJG2tCtzAAAA
+            META-INF/main.kotlin_module:
+            H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uaSSMxLKcrPTKnQS87PLcgvTtUr
+            Ks0rycxNFeIPzkssKM7ILwkuSSxJ9S7h0uFSwqVYLyczr0SvJLW4RIgtBEh6
+            lygxaDEAAHx2CidzAAAA
             """,
             """
-                androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.class:
-                H4sIAAAAAAAA/6VSTXMSQRB9s3ytqGETEyXESBIjiRcXU960yiKKShUJ1O5W
-                qlIcrIEdccOyg7sDwo2b/8Of4cGicvRHWc4EAxyoePDS/ba7X/fr3vn1+8dP
-                AC9wSPCaBm7IPXdotni3xyNmhv1AeF1mRgHtRZ+5iMxSX/AmH3pB2xZUsDPq
-                91k95D0WilEKhMC4oANq+jRom7XmBWuJFGIE+XmUBgGXVI8HZmkGU0gQbPRC
-                9omFIXOvO57SLiNYP3xanfNtEcrpLwm2qx0ufC9Y7GgxwQKFZD4xUOIIDpbU
-                zScvMpLHldOSdU6QW0JxaNhmQlatUN/nX5k7DUQE+zcOmPEydatWL1vO+Ue7
-                7DhlazHy/m9kp7r0UIsiC/8oqXPfa43U/m+qJdtWd1pKmOnaW54v+6wrOzqj
-                HlOnOSk7H2pvCVavlz1hgrpUUJnUuoOYfEREGV0ZEJCOjA899VWUyH1O8Goy
-                NtJaVktrxlZ6MpZuRTr98puWnYyPtCI51teShpbTijErM/WX35PJXFzXjLjq
-                cURQqv7nI5Vypbr8TSXPOoIgbfN+2GLvPF8+oU1rOuPMi7ymz+Y/NypIXYjL
-                jkm1tVSZgi6RhsKVfYID6b8ggVuyJs1wG3dwV8KVBjSGDAxlVrE2zd7DOjYU
-                bIAw3McDZCV1s4FYBbkKtip4iG0J8aiCPHZkVYRd7DWQiPA4wn6E1JXV/wB4
-                ImM31wMAAA==
+            androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.class:
+            H4sIAAAAAAAA/6VSz28SURD+3vKzqLCtrVJqpdZK68XFxpsmhioqCS1kd9Ok
+            4WAe8MQtyz7cfSC9cfP/8M/wYEiP/lHG2WKBA6kHLzPfzsw3883s+/X7x08A
+            L3DA8Jp7bV867ZHRkr2+DIThDzzl9IQReLwffJYqMEoDJZty5HgdS3ElTrk7
+            EHVf9oWvLhJgDPo5H3LD5V7HqDXPRUslEGHIz6Pc8yRRHekZpRlMIMaw0ffF
+            J+H7on3d8YT3BMP6wdPqnG8pn6a/ZNiudqVyHW+xoymU8EJE+dgwFMewv6Ru
+            PnmRET+qnJTMM4bcEorN/Y5QVJXmriu/ivY0EDDs3ThgxsvUzVq9bNpnH62y
+            bZfNxcj7v5Gd6tJDLYos/KOkLl2ndRHu/6ZasqzwTksJM127y/NlV/Soo33R
+            F+Fpjsv2h9pbhtXrZY+F4m2uOCW13jBCj4iFZiU0YGBdio+c8KtIqP2c4dVk
+            rKe0rJbS9K3UZEwuTS55+U3LTsaHWpEdJdfiupbTihEzM/WX3+PxXDSp6dGw
+            xyFDqfqfj5Tkkrr8TSXPuoohZcmB3xLvHJee0KY5nXHqBE7TFfOfGxRIF6LU
+            MR5uTSoTSBLSULiyT7BP/gtiWKGalMAt3MYdgukGNIEM9NCsYm2avYt1bISw
+            ASZwD/eRJepmA5EKchVsVfAA2wTxsII8dqgqwCPsNhAL8DjAXoDElU3+AfvU
+            hgfXAwAA
             """
         )
 
         private val MinimalSnapshotStateStub: TestFile = bytecodeStub(
             filename = "SnapshotState.kt",
             filepath = "androidx/compose/runtime",
-            checksum = 0x575bf828,
+            checksum = 0x992154cd,
             source = """
             package androidx.compose.runtime
 
@@ -179,117 +179,118 @@
             }
             """,
             """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijg0uaSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeIPzkssKM7ILwkuSSxJ9S7h0uFSwqVYLyczr0SvJLW4RIgtBEh6
-                lygxaDEAAJG2tCtzAAAA
+            META-INF/main.kotlin_module:
+            H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uaSSMxLKcrPTKnQS87PLcgvTtUr
+            Ks0rycxNFeIPzkssKM7ILwkuSSxJ9S7h0uFSwqVYLyczr0SvJLW4RIgtBEh6
+            lygxaDEAAHx2CidzAAAA
             """,
             """
-                androidx/compose/runtime/IntState$DefaultImpls.class:
-                H4sIAAAAAAAA/4VTy27TQBQ9E7d1SAxpS1sIhUJpgKSgGiQWSF1FRUiWTFoR
-                lA2rSTJJJ7FnovE4Cn/FEljwAXwU4tpJKVBQFnMfZ+6c+7K///j6DcBLPGM4
-                4qpvtOzP/J6OJzoRvkmVlbHwA2XblltRey0GPI1sEE+ixAVjWB/xKfcjrob+
-                aXcketaFw1AcCtvhUSoYXtXDpbTHjfCShkAxFOaYofn/l4nik+Rc28RvplZ3
-                9UyqYU6VZz0zeiKM/Ugc2xMjBsIY0b8AWzymsopSXVR4EGoz9EfCdg2XKvG5
-                UpqopCa7pW0rjSIi2l/ahYsyQ5k6D35RO/VG4OE6bpThocKwcaVNFxsM7jQL
-                Px0w7NSDf83Cw01slbCJbYbVmj2XSVb28rlSxnCsbSSV/1ZY3ueWE1aIpw7t
-                nGWimAkwsHFm0OoKM5lZzxm835dNm24vZp5TH40tw8qJ7lOXlVAq0UrjrjDv
-                eTciZDPUPR51uJGZvwB3383LC9RUJpKg5uWgGWp/355xQ5uywvwR5gVKCXMS
-                8SQR5JbaOjU98UZmCaoLis4VerxAASuYt3oNq1iDg1r+3VPrpEuHX7DO8Bk7
-                n8gr4BHJtfxmC49JevMo3MJt0k/oVCiK/gAUEyIsEVCn42ZsmeOgkcfTPOnt
-                Q1RxmPMe4CnpPcKrFHPnA5wAuwHuBriHvQD38SDA/k8Blj2alAMAAA==
+            androidx/compose/runtime/IntState$DefaultImpls.class:
+            H4sIAAAAAAAA/4VTy27TQBQ9E7d1mhjSlrYQCoXSAElBNUgskLqKipAsmbQi
+            VTasJskkncSeicbjKPwVS2DBB/BRiGs3pUBBWcx9nLlz7sv+/uPrNwCv8Jzh
+            kKu+0bI/83s6nuhE+CZVVsbCD5RtW25F7Y0Y8DSyQTyJEheMYW3Ep9yPuBr6
+            J92R6FkXDkNxKGyHR6lgeF0PF9IeNcIrGgLFUJgjhub/XyaKT5JzbRO/mVrd
+            1TOphjlVnvXU6Ikw9iNxbE2MGAhjRP8SbPGYyipKdVnhfqjN0B8J2zVcqsTn
+            SmmikprslratNIqIaG9hFy7KDGXqPPhF7dQbgYcbuFmGhwrD+rU2XawzuNMs
+            /GTAsF0P/jULD7ewWcIGthiWa/ZcJlnZi+dKGcOxtpFU/jtheZ9bTlghnjq0
+            c5aJ1UyAgY0zg1ZXmMnMesHg/b5s2nR7PvOc+nBsGZaOdZ+6rIRSiVYad4U5
+            492IkI1Q93jU4UZm/hzceX9RXqCmMpEENa8GzVD7+/aUG9qUFeaPMC9QSpjj
+            iCeJILfU1qnpibcyS1CdU3Su0eMlCljCRaurWMYKHNTy755aJ106+II1hs/Y
+            /kReAY9JruQ3m3hC0ruIwm3cIf2UToWi6A9AMSHCEgF1Om7GljkOGnk8zZPe
+            PkIVBznvPp6R3iW8SjF3P8AJsBPgXoD72A3wAA8D7P0EkuUIJ5QDAAA=
             """,
             """
-                androidx/compose/runtime/IntState.class:
-                H4sIAAAAAAAA/4WS304TQRTGv9n+2xaEpYJCUQRBLTdsJV6YYEyIBrNJraRN
-                kISraTutW7YzzcxsU+94Ch/ACx/CC0O49KGMZ1tQomIvZuacM+f7zZmZ8/3H
-                128AnqHMsMFlW6uwPfJbqj9QRvg6ljbsCz+QtmG5FTkwhjfVHh9yP+Ky679r
-                9kTL7lVvVI5lL64pCCW6Qu+93GPw/gTlkGZY+z8shyyD2xX2iEexYFgqb/8D
-                z7B/c1FG8oH5oKzx92OrmmoUyu6YPUYeajUQ2n4kxtJAi47QWrSvgjXepzPd
-                UF4dv1lVuuv3hG1qHkrjcykVoUJFdk3ZWhxFBJqheoNfmlR5O2BYqJ4qG4XS
-                fyssb3PLKc/pD1P0HSyZ3GQCAzul+ChMvApZ7acMh+dnXsFZdibDcwuOm3U7
-                y+dnu24xXXQqToXVi16qRNbxxZf0xedstpR2016mvuhlk+jz98cXn67iOc9N
-                uLvJZaa2ABW5PuW7KYXKzgwnl92Zitx6LTo8jmzQH0QmhwcMs9cj1CeNyw8b
-                p++cWobV+gQSyGFowmYk9n+/O+kDKYV+FXFjBLn5RtiV3Maayik0VKxb4iCM
-                yFm5pBz9xaAec5Cha+To2R3qShd58jbJm6edAtkzBrO4haRl5yhIBrZoTrbW
-                KWUDK3iUiJHC4/H6EE9oPaB9j9ALJ0gFKAa4HWARS2TiToC7WD4BM6QtnSBv
-                sGpwz+A+HWUwZzBvsGbgGuR/AkgwZTK5AwAA
+            androidx/compose/runtime/IntState.class:
+            H4sIAAAAAAAA/4WS304TQRTGv9n+2xaEpVKFogiCCjcsEi9MMCaNBrNJraRN
+            kISraTvUhe1MMzPb1DuewgfwwofwwpBe+lDGsy1VomIvZuacM+f7zZmZ8/3H
+            128AnmGLYZ3LtlZhe+C3VLenjPB1LG3YFX4gbcNyK3JgDG+qZ7zP/YjLjv+u
+            eSZadr96o3Ike3FNQSjREXr/5T6D9ycohzTD6v9hOWQZ3I6wRzyKBUNpa/sf
+            eIbKzUUZyXvmg7LGr8RWNdUglJ0Re4Q81KontP1IjFJPi1OhtWhPgjXepTPd
+            UE6O36gq3fHPhG1qHkrjcykVoUJFdk3ZWhxFBJqheoNfmtTWdsCwUD1XNgql
+            /1ZY3uaWU57T7afoO1gy5ZMJDOyc4oMw8XbJaj9lOLy88ArOkjMenltw3Kx7
+            unR5secW00Vn19ll9aKXKpN1PPySHn7OZstpN+1l6oteNok+f388/DSJ5zw3
+            4e4ll5naAlTk2pTvphQqO9MfX3ZnKnLztTjlcWSDbi8yOTxgmL0eoT5pXH3Y
+            KH3n3DKs1MeQQPZDEzYjUfn97qQPpBT6VcSNEeTmG2FHchtrKqfQULFuiYMw
+            Imf5inL0F4N6zEGGrpGjZ3eoK13kydsgb552CmTPGMziFpKWnaMgGdikOdla
+            o5R1LONRIkYKj0frQzyh9YD2PUIvnCAVoBjgdoBFlMjEnQB3sXQCZkhbPkHe
+            YMXgnsF9OspgzmDeYNXANcj/BKBShOC5AwAA
             """,
             """
-                androidx/compose/runtime/MutableIntState$DefaultImpls.class:
-                H4sIAAAAAAAA/5VT205TQRRd0wKF9igXBUUEVKq2VXu84BMmpsGYTFIKEdMX
-                n6btUAZOZ5o5cxr8K30TH/wAP8q457RcBE3wYe4ra+21956fv77/ALCOdYbX
-                QnesUZ2jsG16fRPL0CbaqZ4MtxInWpHk2u064WTxndwTSeR4rx/FOTCGmQMx
-                EGEkdDfcbh3ItsshyzDZla4pokQyvC3Vr8q+Ua6fsdGl7Eq7wVD7N0GsRT/e
-                Ny4Oa4kzLXOkdDelSsV3rOlL6z4Tx3zfyj1preycXDZEj6KbVPok0LW6sd3w
-                QLqWFUrHodDaEJUytG8Y10iiiIhKVzWTQ4GhQHngpwrZUpkHuIbrBQSYZpi9
-                5DaHWYbcwMO39xgWSvxvKQlwAzfzmMM8w3jR7auYoXL1LJPr+LQ81f8oDy83
-                yVJ83tIYRdgMsIS73tMyxTMYPjBO/uqHxkVKh1vSiY5wgqQzvUGW2o75adJP
-                IOyh31DbZI6U3z1nCM43GnXZ7qjQaSDVQ0fKm6ZDOtN1pWUj6bWk/eiDZZir
-                m7aImsIqfx5dLn0YeuJ6oGJFV7Wz6jIUL77uCEvt4aT9AxZwraXdjEQcSzrm
-                d01i2/K98gKLI4rmJXq8QAZj3imtUxjHBLJ4mn49sk5rvnKMGYZvWPiSYp7R
-                PJG+LKNKczBE4RZu0xrSmCYU/T6qIxHmfcZo5DybP0xhEXdGGm8ImfGpriwd
-                YyWDrxcUVlKFhSFmpOB3q7hH716rQOuplteZyox0qGTkzUdGlaMoK6T7MuV/
-                glcpN8N9wjz4hCzHGkeR4yEecTxGiaP8GxKjsqaBBAAA
+            androidx/compose/runtime/MutableIntState$DefaultImpls.class:
+            H4sIAAAAAAAA/5VT205TQRRd0wKl7dECCooIqFRtq3K84BMmhmBMJimFiOmL
+            T9N2KAOnM82cOQ3+lb6JD36AH2Xcc1ougib4MLPnsrLWXrP3/Pz1/QeANawx
+            vBa6Y43qHIVt0+ubWIY20U71ZLiVONGKJNdu1wkny+/knkgix3v9KM6BMUwd
+            iIEII6G74XbrQLZdDlmGya50TRElkuFtpX5V9vVq/YyNDmVX2nWGjX8TxFr0
+            433j4nAjcaZljpTuplSp+I41fWndZ+KY7Vu5J62VnZPDhuhRdpNKnyS6Uje2
+            Gx5I17JC6TgUWhuiUobWDeMaSRQRUeWqZnIoMhTpHfipQrZS5QGu4XoRAUoM
+            05fc5jDNkBt4+PYew1yF/+1JAtzAzQJmMMswXnb7KmaoXf2VyXV8Wp7V/ygP
+            rzbJUnze0hhl2AywgLve0yLlMxheME7+6ofGRUqHW9KJjnCCpDO9QZbajvkp
+            7ycQ9tAvqG0yR8qvnjME5xuNumx3VOg0kdVDR8qbpkM6pbrSspH0WtJ+9Mky
+            zNRNW0RNYZXfjw4XPgw9cT1QsaKjjbPqMpQv3u4IS+3hpP0DFnCtpd2MRBxL
+            2hZ2TWLb8r3yAvMjiuYlerxABmPeKcU8xjGBLJ6mX4+sUyzUjjHF8A1zX1LM
+            M5on0ptFrNIcDFG4hdsUQxolQtHvozoSYcG/GI2cZ/ObPOZxZ6TxhpAZipO1
+            hWMsZfD1gsJSqjA3xIwU/GoZ9+jeaxUpnmp5nXxmpEMlI28+M6ocZVkj3Zcp
+            /xO8SrkZ7hPmwSdkOVY4yhwP8YjjMSoc1d+/bB9ggQQAAA==
             """,
             """
-                androidx/compose/runtime/MutableIntState.class:
-                H4sIAAAAAAAA/41T3U4TQRg9sy3d7VJxKaAF/ONPWlS2NpqYYIxEY7JJqaZN
-                gISrKR3qwna27sw2eMdT+ABe+BBeGMKlD2X8trRAVISLmfl+zpzzzcw3P399
-                /wHgGVYZily2otBvHbq7YacbKuFGsdR+R7gbsebNQHhSNzTXwgRj+FTd5z3u
-                Bly23ffNfbGr16qXEgx3/gcy0OjDXl7gpq2iLaK1V2sMzp+SJtIMc1fKmsgw
-                LF1L2oTFYLWF3uRBLBimiqV/FMOwfvlJlORd9THUyl2PddgMD33Z7nP3KT9E
-                YVdE+jNxTHUjsSeiSLSGwRrvkKbly6H8QjWM2u6+0M2I+1K5XMqQqPyQ7Fqo
-                a3EQEJGlzupNF73SJsMoncA7Y0kVSx7F1MXYePUg1IEv3Q2heYtrTjxGp5ei
-                bmDJZCUTGNgBxQ/9xCuT1XrKII+PJm2jYJwPx7INK2vtFY6PKkaZVax8Om+U
-                U2WjXnDSM2Rtn3wbO/mayc2krREnM5+2TMeqLzrZJFfJnK4vtl5vbZ98GeJs
-                Z5RwOcdKVCsMK1f2zlmXJfd2dS8yLF+vHQlJFzHSO72459ctY/Gt2ONxoL1O
-                N1AmlhhyFyPUzo1Bp/ThqweaYbZ+yuXJnq98Ils/f3Da70kpojcBV0qQm234
-                bcl1HFFVdiOMo13xzg/ImR6wbP7FQf/AwAgNE1l60TR9HxujdLoSeTcpniP7
-                hsIYOcnfcjA+SCagYZISeUz0AZMEIAMrNNuUfkgcy5jGI/INpPC4vxbxhNY6
-                5adI/dYOUh5ueyh4hJwhE7Me7uDuDpjCPdzfSVQeKMwpzCsskKJCXmFCYVJh
-                XGFRwVbUz3B+A5uahrjABAAA
+            androidx/compose/runtime/MutableIntState.class:
+            H4sIAAAAAAAA/41T3U4TQRg9sy3d7VJxKaAF/ONPWlS2NpqYYIxEY7JJqaZN
+            gISrKR3qwna27sw2eMdT+ABe+BBeGMKlD2X8trRAVISLmfl+zpzzzcw3P399
+            /wHgGVYZily2otBvHbq7YacbKuFGsdR+R7gbsebNQHhSNzTXwgRj+FTd5z3u
+            Bly23ffNfbGr16qXEgx3/gcy0OjDXl7gpq2iLaK1V2sMzp+SJtIMc1fKmsgw
+            LF1L2oTFYLWF3uRBLBimiqV/FMOwfvlJlORd9THUyl2PddgMD33Z7nP3KT9E
+            YVdE+jNxTHUjsSeiSLSGwRrvkKbly6H8QjWM2u6+0M2I+1K5XMqQqPyQ7Fqo
+            a3EQEJGlzupNF73SJsMoncA7Y0kVSx7F1MXYePUg1IEv3Q2heYtrTjxGp5ei
+            bmDJlE0mMLADih/6iVcmq/WUQR4fTdpGwTgfjmUbVtbaKxwfVYwyq1j5dN4o
+            p8pGveCkZ8jaPvk2dvI1k5tJWyNOZj5tmY5VX3SySa6SOV1fbL3e2j75MsTZ
+            zijhco6VqFYYVq7snbMuS+7t6l5kWL5eOxKSLmKkd3pxz69bxuJbscfjQHud
+            bqBMLDHkLkaonRuDTunDVw80w2z9lMuTPV/5RLZ+/uC035NSRG8CrpQgN9vw
+            25LrOKKq7EYYR7vinR+QMz1g2fyLg/6BgREaJrL0omn6PjZG6XQl8m5SPEf2
+            DYUxcpK/5WB8kExAwyQl8pjoAyYJQAZWaLYp/ZA4ljGNR+QbSOFxfy3iCa11
+            yk+R+q0dpDzc9lDwCDlDJmY93MHdHTCFe7i/k6g8UJhTmFdYIEWFvMKEwqTC
+            uMKigq2on+H8BhJaxEnABAAA
             """,
             """
-                androidx/compose/runtime/MutableState.class:
-                H4sIAAAAAAAA/4VR0WoTURA9c3eT3aQxbmOradRaBTHxwa3FBzGlIKIYSBCa
-                EIQ83SZrvM1mt+TeDX3cb/HBj/BBlj76UeJsKkUM1Zc7c+aeOTOc+fHz23cA
-                L/CQ8FhGk0WsJuf+OJ6fxTrwF0lk1Dzwe4mRJ2HQN9IEDojQOxy86p7KpfRD
-                GU39Dyenwdi0j9ZL3Ws1V2KHg0H7qE3w/m50YBN2/93soEhwp4EZyjAJCFvN
-                1voChEKzxVOYqa+Y2811YmtIKDaZmSeb3VlsQhX5vcDIiTSS+8V8abFVlD9u
-                /oBAM66fqxztczZ5TnibpdWyqItylq6CcAvup3qWPrXdLPXowK3ZNfGe9sVx
-                3bMa4mWWfrz4Wr34Uqw0bNf2Co9st+g5udgB4cn1/v15E96OBoS9/7idm7G8
-                dMDrR/JMf47N6uPZzBBKfTWNpEkW/F3ux8liHLxTIYOd40uRodKKJ76Oopib
-                VBxp9l+gwD44bIDgi7koMdrNEcqMN1C5wjdg/c4sPFjF+9jj+IYZVVa5OYLV
-                gdfBZgc13OIUWx1s4/YIpHEH9RGfEDsaDY27Gvd0DksaGxqVX4ySaL/HAgAA
+            androidx/compose/runtime/MutableState.class:
+            H4sIAAAAAAAA/4VR0WoTURA9c3eT3aQxbmOradRaBTHxwa3FBzGlIKIYSBCa
+            EIQ83SZr3GZzt+TeDX3cb/HBj/BBlj76UeJsKkUM1Zc7c+aeOTOc+fHz23cA
+            L/CQ8FiqySIOJ+f+OJ6fxTrwF4ky4Tzwe4mRJ1HQN9IEDojQOxy86p7KpfQj
+            qab+h5PTYGzaR+ul7rWaK7HDwaB91CZ4fzc6sAm7/252UCS408AMZZQEhK1m
+            a30BQqHZ4inM1FfM7eY6sTUkFJvMzJPN7iw2Uaj8XmDkRBrJ/WK+tNgqyp9S
+            /oBAM66fhzna52zynPA2S6tlURflLF0F4RbcT/UsfWq7WerRgVuza+I97Yvj
+            umc1xMss/XjxtXrxpVhp2K7tFR7ZbtFzcrEDwpPr/fvzJrwdDQh7/3E7N2N5
+            6YDXV/JMf47N6uPZzBBK/XCqpEkW/F3ux8liHLwLIwY7x5ciw1CHPPG1UjE3
+            hbHS7L9AgX1w2ADBF3NRYrSbI5QZb6ByhW/A+p1ZeLCK97HH8Q0zqqxycwSr
+            A6+DzQ5quMUptjrYxu0RSOMO6iM+IXY0Ghp3Ne7pHJY0NjQqvwDJFOU0xwIA
+            AA==
             """,
             """
-                androidx/compose/runtime/SnapshotStateKt.class:
-                H4sIAAAAAAAA/5WSXW/TMBSGX6efC2XLCoO142sbsA4Jsk1IXAwhIQRSRNZK
-                C1RCvXIbU9ymdpQ4VS/7r5BAgl7zoxB2WqmaEBfcvOf4PY+P7ZP8+v3tB4Dn
-                OCJoUREmkoczdyAnsUyZm2RC8QlzA0Hj9ItUgaKKvVcVEAJnRKfUjagYup3+
-                iA20WyDYnmSK9iPmiSXc+UzwtOUd+//sfXF1wznBoS+ToTtiqp9QLlKXCiF1
-                iUudt6VqZ1GkqaP1+R9FmsWxTBQLOzFLcvTtbMBik1RQJSgFKuvvV2ETlF9y
-                wdUrgp2Wv24RqISL4flxt4YartvYwCZBzZCcRl0aZYyAePp9/liqiAv3gika
-                UkX1TazJtKBnSIxUjUCzY5NYujjjJjvRWXhKcLCY1+zF3LZ2rTw41eams5g3
-                rRNyVnYsHQuGPCN48j8j0yc6Vz7Ss7EiKL6Rob73ls8Fa2eTPks+mH0EdV8O
-                zLMSbtYrc+9y2d4TU55ybb1ez53ADmSWDNg7btDGCu3+BeIUFopYDqGBEsp6
-                vZ//YQXtAPZ3bHyqX/uKrZ9mQDjQWs4rFRxqrS0pONjW8eGqWsnZR7k+wGMd
-                X2i3rvvf6KHg4aaHHQ+3cNvDLhoemtjrgaS4g7s9FFOUUtxL4aS4/wetLc8s
-                8QIAAA==
+            androidx/compose/runtime/SnapshotStateKt.class:
+            H4sIAAAAAAAA/5WSXWsTQRSG39l8r7HdRqtN6lc/tKmg2xbBi4ogorC4TaDR
+            QMnVJDvGSTYzy+5syGX+laCgufZHiTObQCjihTfvOfOeZ87MnN1fv7/9APAC
+            RwRNKoJY8mDmDuQkkglz41QoPmFuR9Ao+SJVR1HFPqgSCIEzolPqhlQM3XZ/
+            xAbazRFsTVJF+yHzxBJufyZ41vSO/X/2vri+4ZzgwJfx0B0x1Y8pF4lLhZC6
+            xKXOW1K10jDU1NH6/E8iSaNIxooF7YjFGfpuNmCRSUooExQ6Ku3vlWETFF9x
+            wdVrgu2mv27RUTEXw/PjbhVV3LRRwQZB1ZCchl0apoyAePp9/liqkAv3gika
+            UEX1TazJNKdnSIxUjECzY5NYujjjJjvRWXBKsL+YV+3F3LZ2rCw45caGs5g3
+            rBNyVnQsHXOGPCN4+j8j0yc61z7S87EiyL+Vgb73ps8Fa6WTPos/mn0ENV8O
+            zLNibtYrc/dy2d4TU55wbb1Zz53A7sg0HrD33KD1Fdr9C8QpLOSxHEIdBRT1
+            ei/7w3LaAezvqFzVbnzF5k8zIOxrLWaVEg60VpcUHGzpeLiqljL2caaP8ETH
+            l9qt6f63esh5uO1h28Md3PWwg7qHBnZ7IAnu4X4P+QSFBA8SOAke/gF9don0
+            8QIAAA==
             """,
             """
-                androidx/compose/runtime/State.class:
-                H4sIAAAAAAAA/31Qy0rDQBQ9k6RpjK/4bquIy+rCVHEhvsCNUKgItojQ1diO
-                dWw6KZ1pcZlvceFHuJDg0o8Sb1pXKm7uvefce+7r4/P1DcABNhg2uWoPYtl+
-                Cltxrx9rEQ6GysieCOuGG5EHYyifNI5qj3zEw4irTnh19yha5vjsN8UQ/OTy
-                cBi8jjA3PBoKhuXy9l+6XHm70SC/UOvGJpIqvBSGt7nhxFm9kU3rssx4mQED
-                6xL/JDNUoai9x3CUJnO+VbD8NPGtIDOe7d0X0mTH8dIkYPtWxbpeDOySdZgm
-                t+8vzvuz65YczwlyWYd9hq3a/8+gXViDZeNzo8k1QV3xvn6IzTi/2zUMU3XZ
-                UdwMB5T26/Fw0BIXMiJQvJ70upFa3kXiXKmYRDJW2qX5yGF8GX3LBX0dRUIW
-                PNjfkY3S2BewTv6UKqZI4zdhVzFdxUwVs5ijEPNVBFhogmksYqkJV2NZY0Vj
-                VWNNZzD/Bf5sje8BAgAA
-                """
+            androidx/compose/runtime/State.class:
+            H4sIAAAAAAAA/31Qy0rDQBQ9k6RpGl+pz1pFXLYuTBUX4gvcCIWKYIsIXY3t
+            WMemE+lMi8t8iws/woUEl36UeFNdqbi5955z77mv94+XVwB7WGfY4Ko7jGX3
+            MezEg4dYi3A4UkYORNg03Ig8GEPlqHXQuOdjHkZc9cKLm3vRMYcnvymG4CeX
+            h8Pg9YS54tFIMCxWqn/pcpVqq0W+2OjHJpIqPBeGd7nhxFmDsU3rsswUMgMG
+            1if+UWaoRlF3h+EgTWZ9q2T5aeJbQWY827stpcmW46VJwHatmnU5H9hlaz9N
+            rt+enbcn1y07nhPksg67DJuN/59Bu7AWy8bnxl/XBE3FH/RdbCb57b5hKDRl
+            T3EzGlLab8ajYUecyYjA6uVXryup5U0kTpWKSSRjpV2ajxwml9G3XNDXsUrI
+            ggf7O7JRnvgS1sgfU0WBNH4bdh1TdUzXMYNZCjFXR4BiG0xjHgttuBqLGksa
+            yxorOoP5T7cJbagBAgAA
+            """
         )
     }
 }
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetectorTest.kt
index 52d93a5..a45ff5f 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetectorTest.kt
@@ -44,7 +44,7 @@
     private val coroutineBuildersStub: TestFile = bytecodeStub(
         filename = "Builders.common.kt",
         filepath = "kotlinx/coroutines",
-        checksum = 0xdb1ff08e,
+        checksum = 0x8bc08fcf,
         """
         package kotlinx.coroutines
 
@@ -60,49 +60,50 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlk5iXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbqpeWny/EFpJaXOJdwqXOJZSdX5KTmQdSVpRfWpKZl1osJOhUmpmT
-        klpUHA/Um5uf512ixKDFAADN8kOtaQAAAA==
+        H4sIAAAAAAAA/2XMsQoCMRAE0BXh4LZzm2usLBQsgt+g5bX2Ipc9CCa7R7JB
+        P98IWjkw3ZsBgDUArFp7+Ab3uL2Lzxr8y02aFi3schULid2sSt2Vi42GB6SH
+        WgzyYVmrBeFCm3MN0XMut7ZNKg2ecPiHbo76JPzp0ai/aIw8tesdHOENLed0
+        U5sAAAA=
         """,
         """
         kotlinx/coroutines/Builders_commonKt.class:
-        H4sIAAAAAAAAAK1TXU8TQRQ9M/1aliJlBWyrYpUqX8IW4lsJCRJJGhGNRV54
-        MNPtWrbdzpr9aOCN+FP8BfJGfDAE3/xRxrvbLoKagNF9uHvu3XPPnJm5++37
-        5y8AnkBnKHcc37bkgW44rhP4ljQ9/Wlg2U3T9d4aTrfryOd+Bowh1xY9odtC
-        tvSXjbZpUDXBkBLeoTQYNme3/qC0EcO64bw3qwOK3u519XeBNHzLkZ6+OUAr
-        1bldhk//QWh18RoaMecyRRIIRKhyLqK/kZZfXasubP16AlQMLU9vOW5Lb5t+
-        wxUW+RBSOr7oe9p2/O3AtqsM6VV/3/LWFAwxTF3wb0nfdKWw9Zr0XWq3DC+D
-        YYYJY980OoP+V8IVXZOIDDOzv/u4UKmHIi3ylcUIbqjIYpRuqWE7RkfBGMNw
-        ObRRHlzb9DUOiqF01cXR7mxB2T5Dtq8fp2Nx6wvTF03hC+Lybi9B88fCkGJg
-        nRBwqh9YIaoQai4zHJ8eldTTI5XnuMrzPIL5PuS5OFF4sUpJkVfYPK/wlZlc
-        ojitMC2pUaapmhIhVklpaS2ZZ5V0JXn2Mc2VzNcTdnoUwpxCCkP/JHD2gSfJ
-        SiE0vsJoZ9DibV88o9IVE0eUqZjy7MA3aRYcGQvsHEZXocU/51L/51zq+AzJ
-        DadpMoxukeR20G2Y7o5o2GZowzGEvStcK8wHxaG61ZLCD1zC5dcBrd81a7Jn
-        eRZ9Ph+09Z9DzKDWncA1zE0r7C8Menb7HReIWAZHEuHDUUAKaSQwS9k65Zze
-        I/OaeoLcgqZRPI5ocxTTdGJZKJgnPNkn4ibGI6ERjGGCvi9E7AwehzVOBSUc
-        oSgWqOmvVspeWunW9VfiWIziDJboXaNqnnZZ2EOihmINtyniTg13MVXDPZT2
-        wDzcx4M9qB5SHqY9jHsY81D28DBKH3lIe5j8ASY6o3uSBQAA
+        H4sIAAAAAAAA/61TXU8TQRQ9M/1guxQpKyBUxSpVvoQtxAeTEhIkkmxENIK8
+        8GCm27Vsu501+0HgjX9i4i/QN+ODIT76o4x3tl0ENRGNL3fOvXPumTt37nz9
+        9ukzgAeoMVQ7fuS58si0/cCPI1c6ofkodr2mE4SvbL/b9eWTaACModQWh8L0
+        hGyZzxptx6ZohiEnwmNpM2zObv1GaSOFO7b/xqn3KWb7sGu+jqUdub4Mzc0+
+        WqnP7TG8/w9Cq4uX0Eg5FymSQCyUypmI+VK6UX2tvrD1cwcoqEqe3vKDltl2
+        okYgXKpDSOlHolfTth9tx55XZ8ivRgduuKahwDB1rn5XRk4ghWdaMgoo3bXD
+        AQwyjNkHjt3p5z8Xgeg6RGSYmf21jnORHSXSorqKGMIVHUUM0ys1PN/uaBhh
+        GKyqMqr9Z5u+RKMYKn96OLqdJ8g7YCj29FN3JE196kSiKSJBXN49zND8MWUK
+        yoCBdRTgtHnkKkSjyZvLDG9PTyr66YnOS1znEzyBEz3IS6mj8fJDcsq8xuZ5
+        ja/MlDLlaY0ZWYM8Qze0BLFazsgb2QlWy9eyX97luTagbEmj5MK/5qoyV5i6
+        gZHe9HxbKn8YMqJMpZTHR5FDz+/LVGD3OOm+kf7Hpd5/XOpEDNkNv+kwDG+R
+        5HbcbTjBrmh4jirDt4W3JwJX+f1gYcdtSRHFAeHqi5jO7zqWPHRDl7bPZmv9
+        x9wy6Dt+HNjOpqvyJ/s5e72Mc0QsgyOr3pDWSeSQRwZz5K2Tz2kdmjf0jygt
+        GAbZDwltnmyeOlaEhgXC4z0irmI0ERrCCMZo/37CHsCiinEKaMmoKDtJSX91
+        UvHCSdcufxLHUmJnYdJqUXSCbjm5j4yFsoXrFm7gpoUp3LJQwe19sBB3ML0P
+        PUQuRDXEaIiREHdD3EvcmRD5EOPfAUeuoPKFBQAA
         """,
         """
         kotlinx/coroutines/CoroutineScope.class:
-        H4sIAAAAAAAAAIWSTW/TQBCG390kjusGmpavlPJV2gNwqNuKGxVSG4FkKRiJ
-        VJGqnjbOqmxi7yJ7HfWYEz+Ef1BxqAQSiuDGj0LMmgAHDtjSzLyzs493Zv39
-        x6cvAJ5ii2FzYmyq9HmYmNyUVmlZhN3fYT8x72QTjKE9FlMRpkKfha+HY5nY
-        JmoM3oHSyj5nqD16PGihAS9AHU2Gun2rCoat3n/pzxj8gyStOAG42+xHcf/4
-        MO6+aOEKgiVKXnUok5+FY2mHuVC6CIXWxgqrDMWxsXGZpoRaXXwwfCWtGAkr
-        KMezaY26Zc40GNiEUufKqV2KRnsM2/NZEPAOD3ibovnM//aed+azfb7Ljpo+
-        //rB423uavcZcbB2VKp0JPNiJzFZZvTOxDJsvCm1VZmM9FQVapjKw78HpHl0
-        zUgyrPSo7bjMhjI/FlRDrJ5JRDoQuXJ6kQz6pswT+VI5sb4AD/7BYo9GU3et
-        Yd1NivxdUh75NnlOb6NS90iF5JmbwJNL+BfV8v1FMQjygGzrVwGWCAX4WP6z
-        +RZVu2f5M/jJJVofsXJRJTg2K3sHD6sfim6AAGunqEW4FuE6Wdxw5mZEkM4p
-        WEFnvU3rBYICGwW8n1uFkiGNAgAA
+        H4sIAAAAAAAA/4WSTW/TQBCG390kjuMGGspHE8pXaQ/AoW4rblRIbQSSpRAk
+        UkWqeto4q7KJvYvsddRjTvwQ/kHFoRJIKIIbPwoxawIcOOCVZuadnX3WM/b3
+        H5++AHiKbYbNqbGJ0udhbDJTWKVlHnZ/h4PYvJN1MIbWRMxEmAh9Fr4eTWRs
+        66gweAdKK/ucofLo8bCJGrwAVdQZqvatyhm2ev+lP2PwD+Kk5ATg7rAf9QfH
+        h/3uiyauIGhQ8qpDmewsnEg7yoTSeSi0NlZYZSjuG9svkoRQ15YXhq+kFWNh
+        BeV4OqtQt8yZhjNgYFPKnyundika7zFsL+ZBwNs84C2KFnP/23veXsz3+S47
+        qvv86wePt7ir3WeOsHZUqGQss3wnNmlq9M7UMmy8KbRVqYz0TOVqlMjDv29J
+        Q+masWRY7VHv/SIdyexYUA2xeiYWyVBkyullMhiYIovlS+VEZwke/oPFHs2n
+        WjbVceMif4+UR75FntOqleo+qdC1Tr725BL+Rbn9YFkMgmySbf4qQINQgI+V
+        P4fXqdo9K5/BTy7R/IjVizLB8bC0d7FV/lX0GQiwdopKhOsRbkS4iVsUYj1C
+        G51TsBy3sUH7OYIcd3J4PwGm9PkckgIAAA==
         """
     )
 
     private val flowStub: TestFile = bytecodeStub(
         filename = "Flow.kt",
         filepath = "kotlinx/coroutines/flow",
-        checksum = 0x3416a857,
+        checksum = 0x40e0a7,
         """
         package kotlinx.coroutines.flow
 
@@ -110,29 +111,30 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlk5iXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbqpeWny/EFpJaXOJdwqXOJZSdX5KTmQdSVpRfWpKZl1osJOhUmpmT
-        klpUHA/Um5ufB1RowCWOqVAvLSe/XIgLptq7RIjTOT8nJzUZaLQSgxYDAKm0
-        uUqbAAAA
+        H4sIAAAAAAAA/2XMsQoCMRAE0BXh4LZzm2usLBQsgt+g5bX2Ipc9CCa7R7JB
+        P98IWjkw3ZsBgDUArFp7+Ab3uL2Lzxr8y02aFi3schULid2sSt2Vi42GB6SH
+        WgzyYVmrBeFCm3MN0XMut7ZNKg2ecPiHbo76JPzp0ai/aIw8tesdHOENLed0
+        U5sAAAA=
         """,
         """
         kotlinx/coroutines/flow/Flow.class:
-        H4sIAAAAAAAAAH1Qz08TQRh932y7C0uVBQWLInjEHlggJCZCSNCEpEnVRJpe
-        epq2Kw7dziQ7s8Bx/xb/A04mHsyGI3+U8ZvKSRPn8L7vvXnz/Zj7Xz9+AjjE
-        NmFzalyu9E06NoUpndKZTb/k5jo9Y4hAhJ3j/tvepbySaS71RfppdJmN3dHJ
-        vxIh+VuL0CCEx0ord0IIdl4PWggRxWhigdBwX5UlbPX+NwOXXXkwpB8yJyfS
-        SdbE7CrgHchDk0BTlm6UZ3ucTfYJnbpqxaIt4rqKRcJQV+266oQLdZXQKzoQ
-        e+Jd8+5bKJLAvzjgIn3iioh8292p4wHfm0lGWO7xSB/L2Sgr+nKUs7LaM2OZ
-        D2ShPH8QF8/VhZauLDiPz01ZjLMz5S82PpfaqVk2UFax81Rr46RTRlvsQ/Bf
-        +MPt/dcwbjBL55xX63zH4i0nAs8Zw7nYwAvG1h8DYixxDLA5dwV4OY9tbHF8
-        w54Wex4NEXTxuItlRiQeVrpYxZMhyOIp1oZoWCxZrFs8s4h+Az4tHOgiAgAA
+        H4sIAAAAAAAA/31QwW4TMRSc5012m22g21IghVJ6LDmwbYWEVKpKgFQpUgCJ
+        Rrnk5CRLcbOxpbW39Ljfwh9wQuqhWnHko6o+h5xA4jJvZjx+fs+/b69vALzC
+        LmF7Zlyu9FU6MYUpndKZTb/k5lt6yhCBCHvHg6P+hbyUaS71efppfJFN3JuT
+        fy1C8rcXoUEIj5VW7oQQ7L0YthEiitHECqHhvipL2On/bwZuu74MpB8yJ6fS
+        SfbE/DLgHchDywMINGP/Snm1z2x6QOjWVTsWHRHXVSwShrrq1FU3XKmrhHbp
+        UOyLd81f30ORBP7GITcZkO8V+bdfzhxP+d5MM8Jan+f6WM7HWTGQ45ydjb6Z
+        yHwoC+X10mydqXMtXVkwj89MWUyyU+UPtj6X2ql5NlRWcfKt1sZJp4y2OIDg
+        D1nu4P+H8QmrdKGBZvcnWj+YCDxlDBdmA9uM7T8BxFjlGuDZIhVgZ1G38Jzr
+        a860OXNvhKCH+z2s9ZBgnSk2eniAzRHI4iEejdCwWLV4bNGxiO4ApHDXcycC
+        AAA=
         """
     )
 
     private val flowBuildersStub: TestFile = bytecodeStub(
         filename = "Builders.kt",
         filepath = "kotlinx/coroutines/flow",
-        checksum = 0xb581dd7,
+        checksum = 0xa1c50396,
         """
         package kotlinx.coroutines.flow
 
@@ -142,32 +144,32 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlk5iXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbqpeWny/EFpJaXOJdwqXOJZSdX5KTmQdSVpRfWpKZl1osJOhUmpmT
-        klpUHA/Um5ufB1RowCWOqVAvLSe/XIgLptq7RIjTOT8nJzUZaLQSgxYDAKm0
-        uUqbAAAA
+        H4sIAAAAAAAA/2XMsQoCMRAE0BXh4LZzm2usLBQsgt+g5bX2Ipc9CCa7R7JB
+        P98IWjkw3ZsBgDUArFp7+Ab3uL2Lzxr8y02aFi3schULid2sSt2Vi42GB6SH
+        WgzyYVmrBeFCm3MN0XMut7ZNKg2ecPiHbo76JPzp0ai/aIw8tesdHOENLed0
+        U5sAAAA=
         """,
         """
         kotlinx/coroutines/flow/BuildersKt.class:
-        H4sIAAAAAAAAAIVR32/SUBT+TguFdSgd/trY3JS5hb3Yjfi0ERI1WSQiS1xD
-        Yni6QEculN6kvcU98rf4F/hmookhPvpHGU8RYyLRNe13zvn6ndN7vn7/8fkr
-        gGc4JFTGSgcyvHb7KlKJlqEfu1eBeu++SGQw8KP4tc6BCM5ITIUbiHDoXvRG
-        fp9Zk2Cl0osrQq3a+ltwdtT61+xzhjNCo+6drrY1qp53Q2+dFQ0esN9S0dAd
-        +boXCRnGrghDpYWWivO20u0kCFi1879ROazxGnUZSt0gmNWjTgHrKNiwcYuQ
-        nYog8Qml1WMSNpZndN/4WgyEFswZk6nJ1lIKWQKN08Rg/lqm2TFngxO2az6z
-        bX6MTcM28mZ5z5nPyvlSpmS8Mo6pksnPZ45RsxyzzMS3D5bhZNLOGmH3JlPJ
-        I6z//nlPx5qQeakGvEOxxdp2Mun5kSd6wWIr1RdBR0QyrZfk2qUchkInEefb
-        b5NQy4nfDKcylvz6+R+DCfalSqK+fy7Ttq2ltLMixAkMZJBeLEMWFkzscVVj
-        njjmv8B+9wm3P6ZW4RGjteAtPGYs/NKgCIdjZaHJYX+pyi/qJwvcxQHHU2Y3
-        +CulLswm7jRxlxH3mriPB01sYqsLilHGdhfZOL13YjyMUYxh/QQRN9W+GAMA
-        AA==
+        H4sIAAAAAAAA/4VRXW8SQRQ9dxcW2KJs8aultVXqB31xW+JTS0jUpHEjtokl
+        JIanAbZkYNlJdmexj/wWf4FvJpoY4qM/yniXYkwk2mT33HvPnHtn5syPn1++
+        AXiOp4TqWOlAhpduX0Uq0TL0Y/ciUB/cl4kMBn4Uv9E5EMEZialwAxEO3bPe
+        yO8zaxKsVHp2QajXWn8Ljvdb/5p9wnBMaDbaR6ttzVq7fU1vgxVNHrDXUtHQ
+        Hfm6FwkZxq4IQ6WFlorzU6VPkyBg1fb/RuVQ4Gs0ZCh1k2DW9jtFrKFow8YN
+        QnYqgsQnlFePSVhfntF962sxEFowZ0ymJltLKRRSAIHGaWLw4qVMswPOBofs
+        2Xxm2/wbG4Zt5M3KrjOfVfLlTNl4bRxQNZOfzxyjbjlmhYnvHy3DyaSddcLO
+        dc5Sm7D2+wWfjTUh80oN+CKlFmtPk0nPj9qiFyyupvoi6IhIpvWSLJzLYSh0
+        EnG+9S4JtZz4XjiVseTlF39cJtjnKon6/olM2zaX0s6KEIcwkMGVIZvIwoKJ
+        B1zVmSeO+a+w33/GzU+pVXjIaC14C1XG4pUGJTgc9xaaHB4tVflF/XiBu3jC
+        8YjZdd6l3IXp4ZaH2x7u4K6He9jweP9KFxRjC9tdZOP0ux9jJ0YphvULZwN9
+        KR0DAAA=
         """
     )
 
     private val flowCollectStub: TestFile = bytecodeStub(
         filename = "Collect.kt",
         filepath = "kotlinx/coroutines/flow",
-        checksum = 0x8685bc57,
+        checksum = 0xf321f548,
         """
         package kotlinx.coroutines.flow
 
@@ -180,62 +182,62 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlk5iXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbqpeWny/EFpJaXOJdwqXOJZSdX5KTmQdSVpRfWpKZl1osJOhUmpmT
-        klpUHA/Um5ufB1RowCWOqVAvLSe/XIgLptq7RIjTOT8nJzUZaLQSgxYDAKm0
-        uUqbAAAA
+        H4sIAAAAAAAA/2XMsQoCMRAE0BXh4LZzm2usLBQsgt+g5bX2Ipc9CCa7R7JB
+        P98IWjkw3ZsBgDUArFp7+Ab3uL2Lzxr8y02aFi3schULid2sSt2Vi42GB6SH
+        WgzyYVmrBeFCm3MN0XMut7ZNKg2ecPiHbo76JPzp0ai/aIw8tesdHOENLed0
+        U5sAAAA=
         """,
         """
         kotlinx/coroutines/flow/CollectKt$launchIn$1.class:
-        H4sIAAAAAAAAAK1WbVMTVxR+7iawEBOJVK1vlahUIGCC1lZbUhRDqFtCUAJa
-        S6vdLJewsNlN9yXab3zuT+kn67Tq1Jk204/9TZ1Oz91sEiTR4LSZ2btn7557
-        nvOct81f//z2O4CrqDFM7ViuoZtP0pplW56rm9xJbxrW43TWMgyuuYvuqKF6
-        pralmKOXZTCGX/ONI3tPbNcqad10uW2qRrroOVVubuTVSmlDnWlqC5VNMuTq
-        lumkFwLpSibfxYFsUyxqVpXPdAHMWiYJnipsZC41FdZM3Z2ZnclvqzU1bahm
-        Ob1c2iYStNdiejC3ZYQZzr7ddRn9DP0ZnUBnGS6M93BzZuIew2ovrRaZg2WE
-        mAmzo+NKb/QoBnAogj5EGcLulu4wpN4NjOHQqGZVqgYXJhkSvUAZYrpZs3Z4
-        EFyGi+Od2Zno3Gq79sZ8zfOSV17irrqhuiodYJsMkcDt1I5LGwZdOl1ElJG3
-        rEKX1i75VNtySnBOdeNMsc1bdjm9zd2SreqUf9U0LVdt1ELBMwy1ZHCCv/A2
-        NcsVmqQ10UmKCNl0QNectNISF10ZCYbjZe5ml1eW11aVQu5Rca14J1eYz80z
-        HB3vErQozuNCBOcwytBHfnERACWKixgbhIRxhqEAfoU7nuEKkCTDYXfLth4v
-        mwuqbng2ZzjWLUdUPlO4FMEkUlQGexpOxjTDgFIors4VsjnK+GvdGMUVfDSI
-        y7jKMNK2qlCky6pRpAjx3BONV0WgZHzCkNZUw0i4VmLMJicrfCxR4puWzRNj
-        jUoaSzzW3a1EK4ADuL7P46IIYjko+M8iuAYKvDxq+5wZhrtVW3z/nowb1Nya
-        zclBv207DvVsuN7NsfnuZjPJ2Z6WM/vmoYjDYIQqYL49095wVMYC1U5NNTxi
-        3d+IOMP98f8+pbt3efl/sNwx/7u2xhxuiRDkoxjGe0IqMEjVy6Jxe3sgVK8w
-        XO+Wr4ONs3M9QWSsRqHgS+EbjfQjTVJ7RpxUqYXow83E0ke9vSOEEO0/0YVE
-        fShtEKOx+m40Ut+NSHHJv52Q4vXdU9I0Ox8eqO/GpaQ0Hbr95483hTqxOpRR
-        Tcv8oWJ5Dn3HQHZXu/v7+odBBg3cgeakZJjvmkr/zAItMwcIs2jZLdDIDmet
-        DS5a1aJpcE+1dTFkV8XCMFjUy6bq+pMqRgNE21lSq8G7oTzZKniVEreDndMr
-        HlVKhStmTXd02pprz2Wa7fvf3lFttcLpC/OaWlQxTW5nDdVxOD0O5UzNsBwa
-        MpSbLYu+apGi5dkaX9AF5MnA6L0OQExTbvsowvRHivJFc1kkki7qT3qzQ1Ia
-        IZIAOdk3+QKxn0W6YdB6vLGNwxgCfCmOI/SuQrKECMlU13RYGPHoLgoi9RIf
-        LiV/wcRP/hGcQft3dPIl0s/w8dNXuPZg+NMXyPwhigkmreTM3zgj46YMix5F
-        RYZoM0FX05UEwoErQvocs+RKlZ766X6W7t8LF6mUMELCEdF9pCZ8mw18i76C
-        9GDqBXJ1fPG0xTLReNdiGcVt37SQBF8p4JttgY0EYDEpQG5CUisFkLcCyHhy
-        cuo5luqQiPdzLO+Hjbdg47iDuz5sHCt7YBc7OPqwI74h2orPEWyRZAF7I4CN
-        JSfrWJsins9xfz9mrIUZI8wG1RhhzvqVYvvRZ37qgRNwaA2jjO3AnxBc/36c
-        Ug48JOkoFcYxhzbeXxcnxHJSLKfEctqhIjnj4AN8RcYfrCOk4GsF67TiGwXf
-        4qGCR/hunf4yQUVpHWEHmoMNB9zB3X8BX4LM6zcMAAA=
+        H4sIAAAAAAAA/61WbVMTVxR+7gYIxEQiVetbJWoqEDBBa6stKYoh1C0xWAJY
+        S1t7s1zCwmY33Re03/jcn9JPttOqU2faTD/2R3V67maTIIkGp2Vm757ce+55
+        znPelr//+f0PANfhMUztWK6hm08ymmVbnqubwslsGtbjTM4yDKG5i27S4J6p
+        balm8moYjOG3QuPK/hvbu9WMbrrCNrmRKXlOTZgbBV4tb/CZprZU2SRDrm6Z
+        TmYhkK5lC10cyDXFkmbVxEwXwJxlkuBxaSN7pamwauruzOxMYZvv8ozBzUpm
+        qbxNJGivxfRwbofRx3D+za6HMcAwkNUJdJbh0ngPN2cm1hhWemm1yBwuI8RM
+        mk2Oq73RoxjEkQj6EWXoc7d0hyH9dmAMR5KaVa0ZQppkSPQCZYjp5q61I4Lg
+        Mlwe78zOROdW27XX5mtelL3KPeHyDe5yusA2GSKB2+kdlzYMenR6iCgjb1mV
+        Hq1d8um25bTknO7GmWJbsOxKZlu4ZZvrlH9umpbLG7VQ9AyDlw1B8JfepGa5
+        UpO0JjpJESGbLuiak1Fb4qIbRoLhZEW4uaXlpdUVtZh/VFot3c8X5/PzDMfH
+        uwQtiou4FMEFJBn6yS8hA6BGcRljQ1AwzjAcwC8LxzNcCZJiOOpu2dbjJXOB
+        64ZnC4YT3XJE5TOFKxFMIk1lsK/hwphmGFSLpZW5Yi5PGX+lG6O4hg+GcBXX
+        GUbbVlWKdIUbJYqQyD/RRE0GKoyPGDIaN4yEayXGbHKyKsYSZbFp2SIx1qik
+        scRj3d1KtAI4iJsHPC7JIFaCgv8kghugwIeTts+ZYaRbtQ1otiBX/AbtOO7Z
+        Wr3bYPPtzWZTsz0tZw9MPsl4KEK5vtOeXq+5GgaVUf8uNzxiPdCILcOD8f8+
+        j7v3c+V/sNwx6bs2wS3cliH4PIoRvCOlAoNSuypbtLcHUvUaw81u+Trc4LrQ
+        EySM5Sg+w13p2wrDsSapfcNMqe6G6BPN5DIkF1Ar70ghRIdPdClR2ykbRGus
+        vheN1PciSlzxX6eUeH3vjDLNLvYN1vfiSkqZDt3968fbUp2oHcly0zJ/qFqe
+        Q58taXelu9OvfgfCoPIYbA5Ghvmu+fTvLNAyc4hYyw6tYIu+RjlrQ8jOtKj5
+        17ity5m6IheGoZJeMbnrD6YYzQtt5x6vBWfDBbJV9KplYQc7Z5c9KpeqUM1d
+        3dFpa649hmmUHzy9z21eFfRBeUUtqpqmsHMGdxxBP4fzpmZYDs0UStCWRR+x
+        SMnybE0s6BLydGB0rQMQ05Tgfoow/d9E+aIxTGs/PdSkdLJNUgYhkoBwqn/y
+        OWI/+4neofVkYxtHMSyzT1Icx+jMIFlBhGQqbrosjbiBkfQLvP8g9SsmfvKv
+        4Bzaf8cnXyDzCz58+hI3Ho58/BzZP2UxoUprH5RzYZgkHaWdEDmXoCdJT9OT
+        BOk0PJHSp5glTyz6NUDv8/SuSQ+pkjBKwjHZgaQmXZv1DQLRl1AeTj1Hro78
+        0xbJROOsRTKKBd+0lCRdJaA71wIbDcBiSoDchKR2CiDvBJDx1OTUMyzWoRDt
+        Z7h3EDbego2jiCUfNo77+2DVDo4+7KhviLbicwT7BckS9lYAG0tN1lGaIp7P
+        sHoQM9bCjBFmg2qMMGf9QvmefkVoT/E1TsH2c7MJPfAnBMd/n6SMA9+SdJzq
+        4oRDG++uyxtyOS2XM3I561CNnHPwHtbI+IN1hFR8qeKhiq+wruJrfKOSkUfr
+        9A8SvgNfR5+DsgPNwYaDpX8BZeuV7iUMAAA=
         """,
         """
         kotlinx/coroutines/flow/CollectKt.class:
-        H4sIAAAAAAAAAI1UW08TQRT+ZntlLdBWQECsAlWusm29U2yimMbGisQ2JIYH
-        nW6Xsu121uyl8ti/5JNEE9Nnf5Tx7LYVQQT7cM6Zb+Z855s5Z/vj59fvAO5j
-        k2G+ZTqGLo4U1bRM19GFZisHhvlJ2TYNQ1OdV04EjCHe5B2uGFw0lDe1JuER
-        BBiiBneFelgSDC+Wy/9iKpLJn7e7PQwrqvlRy6/sMXzYqm6Wz9bKFy4m31qr
-        VvOF/y2xWDathtLUnJrFdWErXAjT4Y5uUrxjOjuuYeQZwlvOoW4XohhhSPWJ
-        lWanrejC0SzBDaUkHIvSddWO4ArDpHqoqa1B/i63eFujgwxLy39f5w+k4pE0
-        SFcMoxiTEcM4Q8j2xEaRYFi/tD3pYQ/S2QiuesJ1oTsFuufw0U6/h6DA9a/r
-        V53ElIwJXDt9ywOi7L9IcRDlIphhSJ8j57mrG3XNst+rZrttCm9grpOMviyG
-        4rm9O9OX8sW1faU3kJIxh5sMY2mvN+mT4UtdPHtezy/XwJAYynitObzOHU6Y
-        1O4E6FthngkxsJYXSIQf6V6UoaieZdjsdZNyrytLccl300M3m4r3urNShi0E
-        o71uXFqNJoNJ6aWUCeTC8SBthDyGHKMSYFUGedDYjZbDENw26xrDeJlE7rjt
-        mmZVec0gJFk2VW7scUv31gNwpKI3BHdci+L0W5ca3dZKoqPbOm3/HslnJ+PO
-        ECsJoVnbBrdtjZZyxXQtVSvqHt3MgGKvT/BHHrKQEIT3o2MIIYwAcrTaJVQi
-        P7ealI8RX0smPfsNE+/YF0z3MHuMW5+998M9smHKjmGE/oeAqX4e5rHg884h
-        gUXaf+CfjuAh+VGJgKhf1LMBPCIr02rCT5nGY/9wFk/IPyU8TdJu7yNQwp0S
-        lshiuYQVrJawhvV9MBt3sbGPsE1fHBQbGRsLNhI2Fn8B0lRZliIFAAA=
+        H4sIAAAAAAAA/41UW08TURD+zrb0snJpKyAgVoEqV9lS7xSbKKZxY0ViGxLD
+        g55ul7Lt9qzZS+Wxf8kniSamz/4o4+y2FUEEX2bmzJz55puZs/vj59fvAO4j
+        zzDXtFzTEEeKZtmW5xpCd5QD0/qkbFumqWvuKzcKxpBo8DZXTC7qyptqg/xR
+        hBhiJveEdqgKhhdLpX8hFUnkz4tuD8yyZn3U88t7DB+2Kpuls7XyhYvBt1Yr
+        lXzhf0sslCy7rjR0t2pzQzgKF8JyuWtYZO9Y7o5nmjSXyJZ7aDiFGOIM6R6w
+        0mi3FEO4ui24qajCtSnd0JworjBMaIe61uzn73Kbt3S6yLC49Hc7f3jKPkid
+        eA1jBKMyhjHGMOT4ZGNIMqxdup7MYAeZjSiu+sQNYbgF6nMwtNPzEGR4QbtB
+        1QlMyhjHtdNdHhBkbyLFvpWLYpohcw6d555h1nTbea9ZrZYl/AdznWj0aDEU
+        z93dmb2ULq4dML2BtIxZ3GQYzfi7yZw8vvTFb8/f+eUcGJIDGq91l9e4y8kn
+        tdoh+laYL+K+AANr+oZEwSPDt7Jk1TYYNrudlNztyFJCCtTUQM2kE93OjJRl
+        8+FYt5OQVmKpcEp6KWVDuUgiTIEhHyHHAvAKg9zf7nrTZQhvWzWdYaxETHe8
+        VlW3K7xqkidVsjRu7nHb8M99Z7xs1AV3PZvszFuPtt3SVdE2HIPCv9/ls5M3
+        zzCsCqHb2yZ3HJ2OctnybE0vGj7cdB9irwfwRx42ICGM3kSmMYQIQrhHp13y
+        SqRnV1LyMRKrqZQvv2H8HfuCqS5mjnHrsz8/+gGBsogA4nhA9mQvD3OYD3Bn
+        kcQCxR8Gt6N4RHpEIkcsKOrLEB6TlOk0HqRM4UlwOYdN0k/JnyFqt/cRUnFH
+        xaKKJSyrWMGqijXc3QdzsA5lHxGHPjtkqS0H8w6SDhZ+AcPOvm8nBQAA
         """
     )
 
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetectorTest.kt
index 58661be..b1f1f0a 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetectorTest.kt
@@ -47,7 +47,7 @@
     private val flowStub: TestFile = bytecodeStub(
         filename = "Flow.kt",
         filepath = "kotlinx/coroutines/flow",
-        checksum = 0x8d13620c,
+        checksum = 0xab106046,
         """
         package kotlinx.coroutines.flow
 
@@ -61,59 +61,60 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlk5iXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbqpeWny/EFpJaXOJdwqXIJZ6dX5KTmQdSVpRfWpKZl1qsl5aTXy7E
-        5gYkvUuUGLQYABYJSb1jAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuOSScxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxN1UvLzxdiC0ktLvEu4VLkEs/OL8nJzAMpK8ovLcnMSy3WS8vJLxdi
+        cwOS3iVKDFoMAPfFl7BjAAAA
         """,
         """
         kotlinx/coroutines/flow/Flow.class:
-        H4sIAAAAAAAAAH1QPU8CQRSctwgH59fhJybGaGcsPCRWakxsSEgwJkJsqBZY
-        yMKxm3B7SHm/y8Jc7Y8yvoNOE7eY2ZmdZPa9r++PTwC3OCacTq2LtFmGAzu3
-        idNGxeEosu9hk8EDES4funftiVzIMJJmHL70J2rg7h//WoTgt+dhg1BtrzvC
-        Z+XkUDrJSTFbFPgLlEORQFO2ljpXdb4NbwgXWer7oiZ8ZhFkaXlUy9KrUjlL
-        AzqnhqiLPNggnLX/G4G7qEvcBC+X11NHqHT02EiXzBXB79hkPlBNHbE4eU2M
-        0zP1pmPdj9STMdZJp62JS1yGItangANGwXy44n0crdZJKHHG66HQQrmFCiP8
-        HDZb2MJ2DxRjB7v8HiOIUY2x9wNCSdkgiwEAAA==
+        H4sIAAAAAAAA/31QPUsDQRSct9Fccn5d/Iwgop1YeDFYqQg2gYOIYIJNqk2y
+        CWsue5Ddiynvd1nI1f4o8V3SKbjFzJvZgXm7X98fnwBuUCecTBIXa7MIB8ks
+        SZ02yoajOHkPWwweiHBx371tv8m5DGNpxuFz/00N3N3DX4sQ/PY8rBFq7VVH
+        +KScHEonOSmm8xKvQAVUCwCBJuwvdKEaPA2vCed55vuiLnxmEeRZZVTPs8ty
+        Jc8COqOmaIgi2CSctv97BxdSl4oOr5BXE0eodvTYSJfOFMHvJOlsoFo6ZnH8
+        khqnp+pVW92P1aMxiZNOJ8aWuQzrWJ0SDhgF8+GS93G0/FNCmTNeD6UIlQjV
+        CD42eMRmhC1s90AWOwj43qJmsWux9wOUHf5akAEAAA==
         """,
         """
         kotlinx/coroutines/flow/FlowKt$map$1.class:
-        H4sIAAAAAAAAAI1SXW8SQRQ9s1A+RpQWq4LWihYrReN2iSZGmiZNhYSUqikN
-        LyQmA2zpwDJr2Fnkkb/kk4kPhmd/lPHuFl582LibnPsx5+49c+/+/vPzF4A3
-        KDOUxq52pJqbfXfq+loq2zOvHPeb2SA406WJ+FqykmAMb1sjMROmI9TQ/NQb
-        2X1da0UVH11e1I5rDJv/liURZ9iJKk0iwZA4kkrqY4ZY+aCTQQppjg1whri+
-        lh7DfmT3tXQSsLUimue2FgOhBeWMySxGI2ABbDCwMaXmMogOyRtYDLvLRZov
-        F9zIGxW2XKR4frmopnLxnPFuuThkAatKrEgR1Gg3WmQSBbogKWX4Uo7+1voW
-        o9nEvPJVX0tXeWZj5VVrB9HlGTzCDkMyCF6PNY3x1B3YDNkWET/6k549vRQ9
-        hzK5ltsXTkdMZRCvkpmmUvb01BGeZ9Pws3XVd1xPqiEN9dodMKTbcqiE9qdE
-        5m3Xn/bthgwqt2+CD3bPH9bn2lYeyWUoXPhKy4ndkZ6kDidKuVqEd4IFgzZN
-        WoMN0UurJ3xCkRnGtLLKD9z6To6BImEiTCbxlDBzQyB7Ozx5RsgpZyB4Ctgj
-        jOMhHqMU1sfwPLS72Ccr2ucnn/lqRvwsHCivtItrr8FfFq3i+vx/fkBeaXFr
-        z3plWe/Jr3O8oDYWCbpDIrNdxJrYbGKLELkA7jaxjXtdMA/38aALwwvc/F8g
-        yNK6tAMAAA==
+        H4sIAAAAAAAA/7VSW28SQRT+ZqEFRuwFq7a2tmixtrS6bqOJkaZJU0tCStWU
+        pi8kJgNs6cAya3ZnkUd+kj6Z+GB49kcZzy6QGDUbX3yYb87tO5eZ8/3H128A
+        nuMJQ6Hrakeqgdl0PTfQUtm+eeW4H80ywaku9MSHgpUCY3hR7Yi+MB2h2ubb
+        Rsdu6lI1jnxwcV46LDEs/E5LIcmwFkdNYZZh9kAqqQ8ZEts7l1mkkeGYAWdI
+        6mvpM2zFVp+2Tg0sTgLNM1uLltCCbEavn6AnYCFkQgAD65J9IEPtE0kti2F9
+        NMzw0ZAby0aRjYZpvjwa7qdzyZzxcjR8xsKofYqK7YSqrcd3msI9mpLaZXi/
+        HZ9rOkqn3zOvAtXU0lW+WZ5I+6WdeHoWa7jPkAqVp13NUPw1oVTa9pRwzJob
+        eE37td0I2icDbSufctMYM33hBDaDqJ0dveOTHPw0SsCLtfxUKvPdvJWf+v/l
+        l3ixyq1Na8+yXpF8En7ysduiUvNVIrwJeg3buxANhyy5qtsUzqXwZKhPjNmK
+        UrZ37Ajft2k15k9U03F9qdr05dduiyFTk20ldOBRMB+PV5Yhc+lvszKsnAdK
+        y559KX1JFY6UcrWIHpthdeKrqP4fXlgwaEvpiccrFa4t4SZpZqQDM8UvuPGZ
+        BAMFwtnImMIjwuw4gO6bkW2LkJPNCBcUK3hMmMQq1rEd8RPYie4NFOn+/9+C
+        XSpjUUNz1OR8HYkKFipYrCCHWyRiqYLbuFMH83EXy3UYfiiuYI9oc0TL03kQ
+        uR/+BILNGH6EBAAA
         """,
         """
         kotlinx/coroutines/flow/FlowKt.class:
-        H4sIAAAAAAAAAI1TbW/bVBR+ruM4jpu2jteVJhulbIalLZ3TbrwtWcaoVDWi
-        FNRGBVQJcZO6nVvHRr5O2MeID/wQfgHfmEBCUfmC+Mr/QRw7TsjWkmDJ97zc
-        55zznHvP/fPvX34D8BAfMyxf+KHreM+tlh/4ndDxbGGduv531g4tn4QZMAb9
-        nHe55XLvzPqseW63yJtiSLX5twxfl/YmZagku9Z5t22ddrxW6PiesHYSbauy
-        Ojmc4a9q49HeqwQqB9f4apOpVNcbjUptGqHqBqE2hqCxPNu+R0qHRygCHVCq
-        9Ws4TGmoGgcy3N3zgzPr3A6bAXeoPvc8P+QDLvt+uN9xXUIp1fCZI2oqsqOL
-        ink7XmgHHnetuhcGFO60RAYzDDdbz+zWRRL/OQ942yYgw73SVaZjnsMoyVll
-        9SiHWcxpyGGeIRsG3BOnftBWkWcwJ8+JScNgbmZwIyLteE5YowEpRRlvYlHD
-        Al5juD0pRQYFBtV0zFMznitWJwpm1P7AXp42JyvTJo1BPgl8SvVkysjWp87k
-        N9fO5P+bvynZqzGIQRv0PmCcbvkdL2TID3v81A75CQ85AaV2N0WPmUVLms7t
-        IlIk8j93Iq1M2skmwx/9Xknr9zRpSdIklX5dJZka2ENfJHUC9XtFk2RRNWRD
-        2pXK7I6s9nu6tDZybCl6qiiV5WJTTycwZQQjwXRlDPxAlfVMcUNlxg0jvytd
-        /qjk1Kyhqpohq2ppxtCMYYqcoRjyEivPltXdyx/U31+wfo/gkj53+b0kE8tC
-        1M8W9dlg1DTYAYMxPJXxu14cOkfPYJ9ENAQeSTrSLnc79tjY/MdTp4hMdC/3
-        L+j85W3/hGLm9wi232k37aDBm64dUfBb3D3igRPZiTN76Jx5POwEpN86oAt0
-        2nbd6zrCoe2n/z54elyv7o5IvwTL1T3PDrZdLoRNpnbod4KWveNExQpJiqMr
-        6bEJCTKiT0IBaShkfUjWF2RHI1JYM7QX0NcNg9bU41+x8NXPWOqj+FMc8ohW
-        hY56DhlUSF+hoDnM4BZu0y6F43Usx+kLyOMNQlbjuAweJ5EqyRr9s1JiDNYC
-        pXoz4VKlgCiZOuCy9nJpBVpcenGAwd2koAqTSAwL3rlSMDssCOL8hFaN7IWE
-        60dx0Ad4SvJL8r9FR/P2MVJ13KujRCtW61jDeh3vYOMYTOA+rGPMC6wILAuU
-        BUw6XIG0wJZAXuCBwEOBdwXeE3g/3lL+AdkMm1BrBwAA
+        H4sIAAAAAAAA/41T32/bVBT+rpM6jpu2jteVJhulbIalLZ3TbvxasoxRqapF
+        KaiNCqgScJu6nVvHRr5O2GOf+EP4C3gDMQlFe+SV/wdxruOEbC0JDz6/7nfO
+        +c69x3/+/fsfAB5ii2HpIox9L3hut8Io7MRe4Ar71A9/tLdJfBbnwBiMc97l
+        ts+DM/uL43O3RdEMQ6bNf2D4trI7rkItPbXPu237tBO0Yi8MhL2dWpu1lfHp
+        DH/Vm492XydQ278m1hhPpb7WbNYakwjV1wm1PgCN1NkKAzI6XKIItE+l1q7h
+        MGGgepLIcHc3jM7sczc+jrhH/XkQhDHvc9kL472O7xNKrcfPPNHQkB8+VMLb
+        C2I3CrhvO0EcUbrXEjlMM9xsPXNbF2n+lzzibZeADPcqV5mORA5kkbPaymEB
+        M5jVUcAcQz6OeCBOw6itochgjd8Ti5bB2sjhhiTtBV7coAWpyIo3saBjHm8w
+        3B5XIocSg2Z51qmV7BVziIIlx+/7S5P2ZHnSpjFkT6KQSj2ZsLLOxJ38/tqd
+        /H/7N6F6PQEx6P3Z+4ynWmEniBmKgxk/d2N+wmNOQKXdzdDPzKTISwG6vAtp
+        KHT43JNWlayTDYYXvcuK3rvUlUVFVzT6DI10pu8PYlIbBOpdli3SZc3MmsqO
+        UmV3slrv0lBWh4FN1ciUlWq2/J0xlcLUIYwUM9QR8AMta+TK6xozb5jFHeXl
+        z2pBy5uapptZTatMm7o5KFEwVTO7yKozVW3n5U8aIRVjVo6wSaM1WTLhPoM5
+        uI3RN14YBIfrv0dKPn5Amq6yy/2OO7Iu//GLU0ZOvsf9C7r37FZ4QjlzuwTb
+        67SP3ajJj31XUghb3D/kkSf9NJg/8M4CHncism/t08N5bdcJup7w6Pjpvz86
+        /VSvnw5JvwIrOEHgRls+F8IlVz8IO1HL3fZks1Ja4vBKeWxAQVYuBOkSpqCS
+        94i8r8iXW1FaNfXfYKyZJsnM4xeY/+ZXLPZQ/iVJqZFU6apnkUOd7GVKmsU0
+        buE2nVI63sRSUr6EIt4i5OMkL4dGmqmRfkLfjJI6fVmiUm+nXOqUIItpfS6r
+        r7ZWoSetF/oY3E0barCIxKDhnSsN84OGIM6fkNTJn0+5Pk2SPsanpL+m+Dt0
+        Ne8eIePgnoOKgxWsOljDew7Wcf8ITMBG9QhzAssCS3StApbApsCUwAOBosBD
+        gfcFPhD4UOCj5Ej9ByMF+2JjBwAA
         """
     )
 
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetectorTest.kt
index 6bf3c0a..8c1c95d 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetectorTest.kt
@@ -47,7 +47,7 @@
     private val stateFlowStub: TestFile = bytecodeStub(
         filename = "StateFlow.kt",
         filepath = "kotlinx/coroutines/flow",
-        checksum = 0x5f478927,
+        checksum = 0xd479b246,
         """
         package kotlinx.coroutines.flow
 
@@ -61,42 +61,42 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlk5iXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbqpeWny/EFpJaXOJdosSgxQAAhojekkAAAAA=
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uKSScxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxN1UvLzxfiCkktLnHLyS/3LlFi0GIAAH26nstEAAAA
         """,
         """
         kotlinx/coroutines/flow/Flow.class:
-        H4sIAAAAAAAAAH1QPU8CQRSct8jXiXr4iYkx2hkKD4mVGhMbEhKMiRAbqgUW
-        snDsJtweUt7vsjBX+6OM76DTxC1m9s3Oy+x7X98fnwBucUI4m1kXarMKhnZh
-        Y6eNioJxaN+DFkMRRLh66N11pnIpg1CaSfAymKqhu3/8KxH831oRW4RqZ5MR
-        PCsnR9JJdor5MsdfoAzyBJqxtNJZ1eDb6IZwmSaeJ2rCYxZ+mpTGtTSpF0pp
-        4tMFNUVDZMYm4bzz3wicRT3iJFS6TjqVadczRyh39cRIFy8UwevaeDFULR1y
-        cfoaG6fn6k1HehCqJ2MsN2progInIo/NyeGQUTAfrfkAx+udEgrsKfaRa6PU
-        RpkRXgbbbVSw0wdF2MUev0fwI1Qj7P8AoQI1/5ABAAA=
+        H4sIAAAAAAAA/31QPU8CQRSctygfJ+rhJybGaGcsPCRWakxsSC7BmAixoVpg
+        IQvHXsLuIeX9LgtztT/K+A46Tdxi5r3Z2cy+9/X98QngFnXC6TR2kTbLYBDP
+        48Rpo2wwiuL3oMVQAhEuH7p37YlcyCCSZhy89Cdq4O4f/0oE/7dWwgah1l5n
+        BM/KyaF0kp1itijwFyiHSg4g0JT1pc67BlfDG8JFlnqeqAuPWfhZWh7Vs/Sq
+        WM5Sn86pKRoiNzYJZ+3/5uBA6lKeUe046VSuXU8dodLRYyNdMlcErxMn84Fq
+        6Yibk9fEOD1Tb9rqfqSejIn5oY6NLXIiNrE+BRwyCuajFR/geLVYQpE9pR4K
+        IcohKiE8bHGJaoht7PRAFrvw+d6iZrFnsf8DtOaVdpUBAAA=
         """,
         """
         kotlinx/coroutines/flow/SharedFlow.class:
-        H4sIAAAAAAAAAH1RTU/CQBB9U74rKuAXJMYYYzx4sEg8CSHxQiRiTGzjhdMC
-        Cy6UNmm3yJHf5cFw9kcZp8TERAN7eG9mduZN3u7n1/sHgBtUCGcTX7vKm1t9
-        P/AjrTwZWkPXf7PsVxHIQYvDDIjw0HBuO2MxE5YrvJH11BvLvq43/5c66wRj
-        qYbj1Jt1QuHvWAZJwvGm0QzShOKPuvUotRgILVjLmM4S7IZiSBFowqW5irMq
-        R4NrwsVyYZpG2TCZmbLD8nJxmc4uFwU6pVq2lCwZ91Q14u4a4Xytg98n4bXk
-        EE42muWmvK2FlnFyNdGEnK1GntBRIAmm7UdBX7aUy0nlOfK0msoXFaqeK+88
-        z+dB5XshmzaQAiGD+CRwyGgwH634AOXVTxKy3JXrItGG2cYWI/IxbLexg90u
-        KEQBRb4PUQqxF2L/G+H7nf0GAgAA
+        H4sIAAAAAAAA/31RTUtCQRQ992k+fVmpfWlERESLFj2TVilCG0kygpQ2rkYd
+        bfQ5D94bzaW/q0W47kdF90kQFLq5554795zhzHx+vX8AuMER4WzkG0/pmdv1
+        A39ilJah2/f8N7f5KgLZq3FrgwgPldZtYyimwvWEHrhPnaHsmnL1/6ixyjCy
+        qrRa5WqZkPkrsxEnHK+T2kgQsj/u7qM0oieMYC9rPI1xGopKKiog0IjnMxWx
+        Ine9a8LFYu44Vt5yGBmS/fxifplILuYZOqVSMhfPWfdUtKLtEuF8ZYzfd+G7
+        qUU4WZuYl9JNI4yMyNXIEFJNNdDCTAJJcJr+JOjKmvKYFJ4n2qixfFGh6njy
+        TmufhcrXISe3sMG57CgeYjjkajHml3iAwvI7CUneSrURq8OpY7OONLa4xXYd
+        O8i0QSGyyPF5iN0QeyH2vwGCO5LBCwIAAA==
         """,
         """
         kotlinx/coroutines/flow/StateFlow.class:
-        H4sIAAAAAAAAAI1QTU/bQBB9s3YcJ6WpcWkbApXoxwE4YIp6qBqKxAU1EghB
-        IoSU05Is6RJjS9l1ytG/pYf+iB4qi2N/VNUxpT00QuUyM29235uZ9+Pnt+8A
-        3uI54cU4tbFOrqJBOkkzqxNlovM4/Rx1rbRqj6sqiHC03Xu/fyGnMoplMooO
-        zy7UwLZ3Zlv7d+p9khM1LAW3e732TpsQ/EuuwiW8/L9AFR7BHyl7IuNMERZW
-        12YXIVRW13gSYf52p+hAWTmUVnJPXE4dtoDKUCHQmFtXukSbXA3fEHaLvFEX
-        TVEv8pskfMc/bxb5uucXeUArtOWHbig+0qY4DgOnJd4V+en1V/f6i+e1XN8N
-        KqXQFuHV3Zb8sZgXoh7h9T3MK++a/j577i9/Y2wJta4eJdJmE36qd9NsMlB7
-        OmaweJwlVl+qE230Wax2kyRlok4TwzYKVEColl6w+T5qjFqMBOpwbisHSzd5
-        EcucP/CPB8ya68Pp4GEHDY54VIagg3mEfZDBYyz04Rk8MXhq8MygaeAb1H4B
-        5Dh0XXwCAAA=
+        H4sIAAAAAAAA/41RTU/bQBB9s3YcJ6VgAqUh/VALHIADpqiHilAkLqiRqBAk
+        Qkg5bZIlLDG2lF2nHP1bOPAjeqgsjv1RVceU9lCE2svMvNl9b2fefv/x9RuA
+        93hNeDtKbKTjq7CfjJPU6liZ8CxKvoRtK63a56oMIhztdLYPLuREhpGMh+Fh
+        70L1bXP3YevgUb1zOVaDQnCn02nuNgnB3+QyXMLSvwXK8Aj+UNkTGaWKML+6
+        9nAQQml1jV8izN7PFH5WVg6kldwTlxOHLaAiVIoAAo24f6ULtMnV4B1hL8+m
+        q6Iuqnl2l4Tv+Gf1PFv3/DwL6A1t+TW3Jj7RpjiuBU5DfMiz09sb9/ba8xqu
+        7walQmiLsPy4L7995qmoQ1j5DweL5Sa/dp/6w98YWUKlrYextOmYj6rtJB33
+        1b6OGCwep7HVl+pEG92L1F4cJ0zUSWzYS4ES718uXOAf8FFh9IKRQBXOfeXg
+        5V1u4BXnj3zjCbOmunBaeNrCdAszCLjEbAs1zHVBBvN41oVnsGDw3KBusGjg
+        G1R+AgX9oFiBAgAA
         """
     )
 
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/CompositionLocalNamingDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/CompositionLocalNamingDetectorTest.kt
index fcb8bbf..eaf12b9 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/CompositionLocalNamingDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/CompositionLocalNamingDetectorTest.kt
@@ -42,7 +42,7 @@
     private val compositionLocalStub = bytecodeStub(
         filename = "CompositionLocal.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0x48f5c823,
+        checksum = 0xeda1836e,
         """
             package androidx.compose.runtime
 
@@ -70,96 +70,96 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcclkZiXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbKiTkDBbILMnMz/PJT07M8S7hUuOSwaVeLy0/X4gtJLW4xLtEiUGL
-        AQBypVQ1cAAAAA==
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uOSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFRJyBgtklmTm5/nkJyfmeJdwqXHJ4FKvl5afL8QWklpc4l2ixKDF
+        AAAiXiK7cAAAAA==
         """,
         """
         androidx/compose/runtime/CompositionLocal.class:
-        H4sIAAAAAAAAAJVTXU8TQRQ9s91+sPKxFMWCqCCo/VC2EjUohKgYkiatKDR9
-        4cEMuwsObXfJ7rTBF9P4L3z1H/hE4oNpePRHGe9sixLUVPbhzr13zj33zNzZ
-        7z++fgPwEIsMOe45gS+cI8v2m4d+6FpBy5Oi6VrrUSyk8L2yb/NGEowhu1p9
-        Wj7gbW41uLdvbe4euLZcWfszxWCezyWhMyRWhSfkGsN8tlz3ZUN41kG7ae21
-        PFt1Cq2NvldcydVI3iDUaqFaXVmLsLFsrjaMBIYMxGEw6PKdCBkK5f8+Iqke
-        ddw93mrIDW5LP3jPMDtIJsPWwKOUzgKEJ93A4w3rZa/VOmFl0FL9Kjyou0F0
-        mjcDSS/Kqe5m3ICGtPKSyrvMMLFg/8a+bUZghsWLkTOMnxZUXMkdLjnltGY7
-        Ru+MKRNnYHVKHQkVFclzHjBsdjuThpbRjG7H0Ewyau2HGS31ONPt5PVUt2Oy
-        Ja2ovZhK6WkzpZmxaSOtp7XlbifDivrJ54Rmxk8+MpZQtEvUqcqoLdKnms4O
-        69G/n8PrwG8Lh+823L88jInzucW6pDe27jsuw1hZeO6rVnPXDaqqXvVWmBoP
-        hIr7yaFtse9x2QrIH9mW3K5X+GF/z9j2W4HtbggVTG31JNVEKGj3uef5kkfz
-        1+dobHGoL0YezZHsXYqe0IE1ddH5Y1z6Qo6GLNkEpQEdObKTPQCGMRIRxDGK
-        MdrPR+iUSX8nTIoVXZHodVrHZvQPn2h65XyBHWOiR1yIurPU2Q5R9Xi/eplA
-        as6JfOEYV1QRixTM9rK/FCT6CpQ3iatRVU9NDPei9Q7u0/qMMBnSO7WDWAnT
-        JVwjixllrpdwAzd3wEJin9tBMsRIiFsh5kOMhlgIVeb2T+jXEMfzBAAA
+        H4sIAAAAAAAA/5VTS08TURT+7nT6YOQxFMWCqCCofShTiRoUQlQMSZMiCk03
+        LMxlZsBL2xkyc9vgxjT+C7f+A1YkLkzD0h9lPHdalKCksjmv+51zvjPnzI+f
+        374DeAyLIcc9J/CFc2jZfuPAD10raHpSNFxrNfKFFL5X9m1eT4IxZJcrz8v7
+        vMWtOvf2rI2dfdeWSyt/hxjM87EkdIbEsvCEXGGYzZZrvqwLz9pvNazdpmer
+        TqG11rOKS7kq0euHWi5UKksrETaWzVUHkcCAgTgMBl1+ECFDofzfIxLrYcfd
+        5c26XOO29IOPDNP9aDJs9h2ldBYgPOkGHq9br7utVgkrg6bqt86DmhtE07zr
+        W/SyNdW3GTWgIa2spLKuMozN2X+w7xsRmGH+csUZRk8T1l3JHS45xbRGK0Z3
+        xpQYUAIMrEbxQ6G8IlnOI4aNTnvc0DKa0WkbmklC6Z6b0VJPM512Xk912iZb
+        0Iraq4mUnjZTmhmbNNJ6WlvstDOsqJ98TWhm/OQzYwlVdoE6VZhqmD4ldnZj
+        Ty6+ibeB3xIO36m7/7iOsfOx+ZqkQ1v1HZdhpCw8902zseMGFZWveitMlQdC
+        +b3gwJbY87hsBmQPbUlu19b5Qe/N2PKbge2uCeVMbHYpVUUo6PWl5/mSR0eg
+        z9Du4uqDIkYWLZNklrxnNLBGOp4/xpUjMjTkSCYoDOjIkxzvAjCIoahAHMMY
+        ofdChE6Z9IvCJF+VK1J5nfTIlP7pC+KsnC+wY4x1Cz+IurPU2Q5R9mgve5FA
+        as+JfOEY146i9SsG093obwaJHgNljeN6lNVlE8PDSN/HPOkXhMkQ34ltxEqY
+        LOFGCVO4SSZulXAb09tgIWZwZxvJEEMhZkPMhRgOcTdUkXu/AG89zFz4BAAA
         """,
         """
         androidx/compose/runtime/CompositionLocalKt.class:
-        H4sIAAAAAAAAAJ1UW08TQRg9s72yFChFoRQvCFW5KFtuGmklMRhiQ7lEGozh
-        abq7kOlll+xuG3gx/A3/hW8aTUyf/VHGb7YlarHUdJOd+WbmzDlnv/lmf/z8
-        +h3AGp4zLHLLcGxhnGu6XTuzXVNz6pYnaqa25Y+FJ2yrYOu8uuNFwBjiZd7g
-        WpVbp9p+qWzqNBtgSOgd6P0ThndzhYrtVYWllRs17aRu6XLZ1bbbUSY7X+gq
-        f+DYDWHwUtXsNJJlOM8VNwqdRrKbvfRyi8VidrM/1Zy/lWG2YDunWtn0Sg4X
-        RM4ty/Z4S2jP9vbqVWkwfROKIFKBYBtdjby+sHhN6N39RKAyhHPCEt4mueqd
-        6qMYYhhSMYhhhtU+MhBBnGHYME94veptc92znQuG6V7CDKnrxZFu0zCUezrP
-        Xz/p/uomhhDCKhSMMyRdeRx6J0aW7Yuu3If+npsyNKkiJfM73Y3+6sNjSLa8
-        3GUYvcrArulxg3uccqbUGgG6o0w2IQZWkYFC8+dCRhmKjGUGo3kZV5uXqpJU
-        VCWq+H3zMpWOUxNNBBPKGyXDZoJRgikr8agSD6TU1nSSZYKEC/0HTGqtMKz3
-        eVlZkf4PV5/4Z12MdYKXKlQQwS3bMBlGCsIy9+q1kukUJbHkkJgj7gg5bk8O
-        HIpTi3t1h+Kpty07eashXEHLr37fOrqSnasH3OE10zOdv2BDdMh6ZZeftQXU
-        Q7vu6Oa2kIPJNsfRNX4s01kGIZ8gJmWhUb9Eo2cIgFEf+4bB9wufMdLE6Cd5
-        ltCoDftrt5CRiBYOCYxRv+xjIlhpo6LUr9IboYRiAIgP0LbbFLdEFMiyGJoK
-        fvhI9bKz8AUTLZU1aslB1Jcb9lEJIhwjwgQZTf7LaEoanfqH0WR/Ru/caPRe
-        V6PjRDhBhOO0vO6DnhID8JLY7lOOp48RyONBHjPUYjaPNB7m8QiPj8FczGH+
-        GGEXIRcLLhZdJFw8cZH8BUMfUaX/BgAA
+        H4sIAAAAAAAA/51UW08TQRT+ZntfCpSiUIoXhKpclC0gqLSSGAyxoVwiDcbw
+        NN0uZHrZJbvbBl4Mf8N/4ZtGE9Nnf5TxzLZELZSavpw5M+eb73x7zpn9+evb
+        DwDP8IJhgZsl2xKlM023aqeWY2h23XRFzdA2vb1whWXmLZ1Xt90QGEOszBtc
+        q3LzRNsrlg2dTn0Mcb0DvXfM8H42X7HcqjC1cqOmHddNXYYdbavtpTNz+a7p
+        922rIUq8WDU6hWQYzrKF9XynkMxGr3zZhUIhs9Ff1qx3lWEmb9knWtlwizYX
+        RM5N03J5K9Gu5e7Wq1Jg6iYUQWQGgq13FfLm3OQ1oXfXE4LKEMwKU7gbpKp3
+        qQ+jiGJQxQCGGFb6qEAIMYahknHM61V3i+uuZZ8zTPVKzJC8OhypNg1Duafy
+        3NVO9zc3UQQQVKFgjCHhyHbonRg5ti+7ch94d26q0ISKpKzvVDf6yw+PItHS
+        cpdh5LICO4bLS9zlVDOl1vDRG2XSRKQBA6tIR6HgmZBemrzSEkOpeRFTmxeq
+        klBUJax4a/MimYqRCcf9ceWtkmbT/jDBlOVYWIn5kmrrOMHSfsIF/gMmcy0z
+        rPb5YlmBfhKX3/n3cIx2ghcrNBX+TatkMAznhWns1mtFwy5IYskhMYfcFnLf
+        PowciBOTu3Wb/Ml3LTk5syEcQeHXf54evcvO6D63ec1wDfsf2CB1Wq/s8NN2
+        AvXAqtu6sSXkZqLNcXiFH0vUUL9sFtkJOW20arRbg4/6B0S/Y+DD/BcMNzHy
+        WfYSabJBL3aLbhOihUMco7Que5gQVtqosPfbBkJUUESAWISu3Sa/lUSBHIvB
+        Sf/HTwiw7fmvGG9lWSVLCsJeuiEPFSfCUSKMk9DEdUKTUujkNUIT/Qm9c6PQ
+        e12FjhHhOBGOUXjNAy3iOa2viO0+1XjqCL4cHuQwncMMUjk8xKMcHmP2CMzB
+        HOaPEHQQcLDg4ImDuIOnDhK/AezqFjcEBwAA
         """,
         """
         androidx/compose/runtime/DynamicProvidableCompositionLocal.class:
-        H4sIAAAAAAAAAJ1SXU8TQRQ9s/1khVKKaMEvlJoIJG5BTQytTRRDaFKwkYYX
-        nqa7A07ZnTW7sw289bf4D3wy8cE0PvqjjHfaEtGEkLAP9+PsuWfuvTO/fn//
-        AeAlnjJsceVFofTOHDcMPoexcKJEaRkI5/254oF021HYlx7v+mJ7RJBahqoV
-        utzPgTG0652tVo/3ueNzdeJ86PaEq2uN1pWyV+vVO51ao8bw4ga1OaQZsnWp
-        pG4wrDxrnYbal8rp9QPnOFGuIcbOziSq1lYPGVavY9XXRx0ZbqUVRidOT+hu
-        xCVxuFKh5mP+fuL7pqfaNLLI2cjAZkjrTzJmqF+9iGv3S6soeOKYJ77e4a4O
-        o3OG5esGY5i7oOwJzT2uOWFW0E/RjTNjMgzslKAzabIqRd4Gw+5wULKtsmUP
-        B/+6/HBQHg7W0uSLbDNfSpesXVa13i2UCsXUkm3y10Rh1fTPL1mrmDF6m3RE
-        h+HVTV4BdVu6mODyWPP/E5+falrzdugJhtmWVGI/Cboi6hhRo2E4hzySJp+A
-        UwfyRHGdRBRXPo5baaq+jCX9bvOIB0KL6O3fu2WwD8IkcsWONPWLk5rDccUl
-        IjZg0cWbj2Y37wApPKSsQbhFPru2/g23vlJk4RFZe4ROm8eCZYrujFmEzIxU
-        sihglpQejyryeEI+Z6SnKEhN4BRWRv4BKuTf0N8iCc4dIdVEqYl5srhtzEKT
-        Drh7BBajjMUjZGPMxFiKcS9GIcb9GLk/6rXJ3BUEAAA=
+        H4sIAAAAAAAA/51SXU8TQRQ9sy0tXaGUIljwAxQ0AolbUBNDaxPFEJpUJNLw
+        wtN0d6jT7s6a3dkG3vpb/Ac+mfhgGh/9UcY7bYloQkh4mXvumXPP3Lkzv35/
+        /wHgBZ4w7HDlRaH0zhw3DD6HsXCiRGkZCOfdueKBdA+jsCc93vLF7lAgtQxV
+        I3S5nwVjOKw2dxod3uOOz1Xb+dDqCFdXao0rba/2qzablVqF4fkNarNIM2Sq
+        UkldY1h92uiG2pfK6fQC5zRRrhHGzt4YlSvrxwzr16mqm8OOjHatEUZtpyN0
+        K+KSNFypUPOR/iDxfdNTZQoZZG1MwGZI608yZqhePYhr50ujyHvilCe+3uOu
+        DqNzhpXrLsYweyF5LzT3uObEWUEvRS/OzJIzCxhYl/gzabIyIW+LYX/QL9pW
+        ybIH/X/D5KBfGvQ30hQLbHuymC5a+6xsvZ0v5gupJdvkr0jCyumfXzJWYcL4
+        bdMRTYaXN/kK1HLx4hqX7zb3v/BZV9Osd0NPMMw0pBIHSdASUdOYGg+jOeaR
+        NPmYzB3JtuI6iQivfRy1Ulc9GUvaPuQRD4QW0Zu/D8xgH4VJ5Io9aeoXxzXH
+        o4pLQmzBotcfj9d8BqSwTFmNeItiZmPzG259JWRhhVZ7yE6ZH4OHhBZGKmKm
+        hy4Z5DFDTo+GFZNYpZg11jkCqTGdwtowPsBjiq9pt0CGsydI1VGsY66O25gn
+        iIU67qB0AhZjEUsnyMSYjnE3xr0Y+Rj3Y2T/AJbWL04aBAAA
         """,
         """
         androidx/compose/runtime/ProvidableCompositionLocal.class:
-        H4sIAAAAAAAAAI1S308TQRD+9lracmIpRaHgLxAkAolXURNjK0YxDTUFURpe
-        eNr2Ftz2umf29hp869/if+CTiQ+m8dE/yjjblogkBO5hZvabb76Z29nff378
-        BPAUKwxPuPJ1KP0Trxl2PoeR8HSsjOwIb0+HXenzRiC2BhlpZKhqYZMHaTCG
-        Srn+otbiXe4FXB177xst0TSlzdqFeudVyvV6abPEsHrlijSSDKmyVNJsMiw9
-        rLVDE0jltbod7yhWTUuMvMooKpZWD0j9MlZ5fTCH5S7XQn3stYRpaC6Jw5UK
-        DR/yd+MgsHdBA3+4tPHZvFRGaMUD76044nFgtohqdNw0od7hui00tZ5ACq6L
-        MVxjSJpPMmJ4dvFFXrwYGi7rD9tUuO3whWHhsmEZpk4pO8JwnxtOmNPpJuiN
-        MGvGGFiboBNpT0WK/McM7/q9vOsUHLff+99lVgr93loy0+/l2EYmn8w726zo
-        vJklIJ/NJeZdCz3v9wqsmPz1NeXkxqziBjWpM6xf/QHRlPnTyc/+zvR54qO2
-        oXvdCn3BMFmTSuzGnYbQdXuFVsNyDriW9jwCx/flseIm1hQvfxwOUFVdGUlK
-        73HNO4LW+vrfA2Fw98NYN0VF2vq5Uc3BsOIMMbkIhzZtP/pjWnwaCdyj0yvy
-        Dvn02jr7jolvFDpYIOsO4AxRU1ikaGZIw3VkBzJpTCJHUvcHFRksWcxqj1OQ
-        GMEJLA/8XTwg/5KyUzRF/hCJKqaruEEWN62ZqWIWhUOwCHOYP0QqQjbCrQi3
-        I0xGuBMh/Rejxn6KQAQAAA==
+        H4sIAAAAAAAA/41SXU9TQRA9e1vacsVSikLBLxBEgcRbURNjK0YxjTUFURpe
+        eNr2Lrjt7V6zd2+Db/0t/gOfTHwwjY/+KONsWyKSEHjZmT1z5szszP7+8+Mn
+        gCe4z/CYK1+H0j/2mmHncxgJT8fKyI7wdnXYlT5vBGJrEJFGhqoWNnmQBmOo
+        lOvPay3e5V7A1ZH3vtESTVParJ2rd1alXK+XNksMq5fOSCPJkCpLJc0mw9KD
+        Wjs0gVReq9vxDmPVtMTIq4y8Yml1n9QvYpXXB31Y7nIt1EdeS5iG5pI4XKnQ
+        8CF/Jw4COwtq+MOFhU/HpTJCKx54b8QhjwOzRVSj46YJ9TbXbaGp9ARScF2M
+        4QpD0nySEcPT8wd5/mKouaw/LFPhtsIXhoWLmmWYOqFsC8N9bjhhTqeboD/C
+        7DFuDzCwNuHH0t6K5PmPGN71e3nXKThuv/e/yawU+r21ZKbfy7GNTD6Zd96y
+        ovN6loB8NpeYdy30rN8rsGLy19eUkxuzihtUpM6wfvlfRK3mT9o//abps8SH
+        bUPD3Qp9wTBZk0rsxJ2G0HU7R6thOftcS3sfgeN78khxE2vylz8OG6iqrowk
+        hXe55h1Bu33175cwuHthrJuiIm3+3Chnf5hxiphchEPrHo2Vtp9GAgt0e0nW
+        IZteW2ffMfGNXAeLdLoDOEPUFO6SNzOk4SqyA5k0JpEjqaVBRgbLFrPa4+Qk
+        RnAC9wb2DlbIvqDoFHWRP0CiiukqrlVxHTPkYraKAuYOwCLM48YBUhGyEW5G
+        uBVhMsLtCOm/jQDw8EUEAAA=
         """,
         """
         androidx/compose/runtime/StaticProvidableCompositionLocal.class:
-        H4sIAAAAAAAAAJ1SXW8SQRQ9s3x2bSmlVmn9qhYT2yYurZqoIIk2aUpCKxHC
-        C0/D7hQHll2zO0vqG7/Ff+CTiQ+G+OiPMt4BGqsJIek+3I8z55699878+v39
-        B4DneMzwintO4EvnwrL9wSc/FFYQeUoOhNVQXEm7HvhD6fCOK44m51JJ36v5
-        NndTYAz1cvN1rceH3HK517Xed3rCVqVKba7qfL1ys1mqlBieXaM2hThDsiw9
-        qSoMO09qfV+50rN6w4F1Hnm2JobW8SwqlnZbDLuLWOX9SUeaW6j5QdfqCdUJ
-        uCQO9zxfr0fzzyLX1T2VlpFEykQCJkNcfZQhQ2n+IhatlzaRccQ5j1x1zG3l
-        B58ZthfNxbB2STkVijtcccKMwTBG9820STCwPkEXUmdFipwDhpPxKGcaecMc
-        j/516fEoPx7txcln2WE6F88ZJ6xovNvIZbKxLVPnL4nCivGfX5JGNqH1DukX
-        TYYX13kE1G3ucoKrY63/T3zaV7TlI98RDKs16YmzaNARQVOLag3NafFA6nwG
-        LjVk1+MqCigufJi2UvWGMpR0XOcBHwglgrd/r5bBbPhRYItjqes3ZzWtacUV
-        Ig5g0L3rj2bXzwAx3KesQrhBPrm3/w03vlJk4AFZc4JmqSaDbYpuTVlYxspE
-        JUn4Kik9nFSk8Yh8SksvURCbwTHsTPw9FMi/oVMtuNZGrIpcFetkcVObjSr9
-        4HYbLEQem20kQ6yE2ApxJ0QmxN0QqT/sQJiNEwQAAA==
+        H4sIAAAAAAAA/51SXW8SQRQ9s1A+1pZSaiutH60WjW0Tl1ZNVJBEmzQlwUqE
+        8MLTsDvFgWXX7M6S+sZv8R/4ZOKDIT76o4x3gMZqQpr0Ze65Z849c+fO/Pr9
+        /QeAZ3jE8JJ7TuBL59yy/cEnPxRWEHlKDoTVUFxJux74Q+nwjiuOJvtSSd+r
+        +TZ3k2AM9XLzVa3Hh9xyude13nd6wlalSm2u63y/crNZqpQYnl6jNok4Q6Is
+        PakqDDuPa31fudKzesOBdRZ5thaG1vEMFUu7LYbdq1Tl/UlHWluo+UHX6gnV
+        CbgkDfc8X49H608j19U9lRaRQNLEAkyGuPooQ4bS/EFcNV6aRMYRZzxy1TG3
+        lR98Zti+6l4MKxeSd0JxhytOnDEYxui9mV7SegED6xN/LnVWJOQcMJyMRznT
+        yBvmePRvSI1H+fFoL04xyw5TuXjOOGFF4+1aLpONbZo6f0ESVoz//JIwsgva
+        75COaDI8v85PoJZzF9e4fLfV/4VP+opGfeQ7gmG5Jj1xGg06ImhqU+2hNS0e
+        SJ3PyHRDdj2uooBw4cO0lao3lKGk7ToP+EAoEbz5+74MZsOPAlscS12/Matp
+        TSsuCXEAgx5/Nl79FxDDFmUV4g2Kib39b7jxlZCBbVrNCZulmgzuE1qfqrCI
+        pYlLgvhlcnowqUhhh2JSW6cJxGZ0DIVJvIeHFF/TrjZcaSNWRa6K1SpuYo0g
+        1qu4hXwbLMQGNttIhFgKcTvEnRCZEHdDJP8AhWEFiBgEAAA=
         """
     )
 
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetectorTest.kt
index 114fae4..594cabd 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetectorTest.kt
@@ -46,7 +46,7 @@
     private val KotlinMutableCollectionExtensions = kotlinAndBytecodeStub(
         filename = "MutableCollectionExtensions.kt",
         filepath = "stubs",
-        checksum = 0x90938fc8,
+        checksum = 0xb32e2e72,
         """
             package stubs
 
@@ -72,389 +72,389 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3Apc0lkZiXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbKsQfnJdYUJyRXxJckliS6l3CpcbFWlxSmlQsJOtbWpKYlJPqnJ+T
-        k5pckpmf51pRkppXDGQUA9XxcbGUpBaXCLGFAEnvEiUGLQYASQTUpX0AAAA=
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uaSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFeIPzkssKM7ILwkuSSxJ9S7hUuNiLS4pTSoWkvUtLUlMykl1zs/J
+        SU0uyczPc60oSc0rBjKKger4uFhKUotLhNhCgKR3iRKDFgMAINgad30AAAA=
         """,
         """
         stubs/MutableCollectionExtensionsKt.class:
-        H4sIAAAAAAAAAJ2Wa2/bVBjH/yc3O26aOEkva7q1LL2v7ZyNXSgNZaVsLCzp
-        YEWTUF85rRXcJg7KOanGu34WPgHQF0ggoYiXfAW+C+Kxa9nOWYI2pNjnnOfy
-        P7/H56L89c9vfwB4gFcMS1z0m9xo9IXZbFsH3XbbOhF213n6RlgOpw5/IRQw
-        Bv3MvDCNtum0jJfNMwpSEGeY6Fwn1m0uGArrG3UvrC/stuHadhnW3jJW66FW
-        zRFWy+rt7lHkUr3baxlnlmj2TNvhhuk4XWG6NNw47IrDfrtNUcVQbL/XM39w
-        FRWkGVJV27HFHkN8feN1BhPIaNAwyZAdnl5BjmwtSzSi7BNDI12uI4MCimnE
-        MMWg+UUfWRSZHyqPTIS4KtvGVTwbncU5t06fm/w7ilcwp6Hksk8O6Si4SaYQ
-        3SPQooOcBJPBIj5wuW+H3A3ze5mbTISzI9tGcb9PKSShYFXDmlSKZ98YKsWD
-        0qKDnMSXwRa23VLuEn1H3rAMN4boQw/BbY9xjVuXqVHBCj4kT0gcnTs/wjYz
-        miaDR3jslvERg1o9afubduUdD8nyu+2sx/97ITff60vl6+ddQTUYDUuYp6Yw
-        yRbrXMTpfmHuK8nAzt1OjOxvbLdXod7pPYa/B5er2uBSi+mL9KhaTI1Te9tv
-        V/x2idpUKaPnS2ohUYhVYhVGo0IwSpUKerGUvR75No0ipoKIbHlWH1yG6X/+
-        mFJp3lJCjesJ8iVDrdCl6Gr5lp6WhcOACT1DuZPhLKErp+tuifcZfQMs/MfV
-        evecTmz6yG45puj3LIb5V31H2B2r5lzY3Kas/fAKZEgcdE8t91zYjnXY7zSt
-        3jeuMh2bo26/d2I9s93BnK/x+i0F3KNdl6AVSNDdQtcZjeruymAXDWpTRKtS
-        W3KvjMBXlXx0BgPfJ5KPNnbg2xvypTGHJI3iOKTRBvnp42Ayvvs7tG9/RXYA
-        /Sd3y+AlvTVyu5AZeq7FlCGxOeQDqZueEEX/gulQIeVZk2OyZzA7CqREIPMD
-        3JJB0gSS9qVuSFILgVQEpCyDaGOyl7A8CmSNQNYHuCODZAkk60utSFKbgVQE
-        xJBBcmOyK7Q1rrO3fBA9ujQDPJBZiqRV9NXuS2oPA7UIy47MMjUyW8XHVCXz
-        soXP8iTKcoXp6GJdoRz9ZFcwJPAr7PwczFz25kjSDEni1zBPzwL17tCzTURV
-        emL4yuN6ga+pPaPMTyn6yTHiNezX8Bm9cVDD53hawzN8cQzG8Ry1Y0xzPOL4
-        0vs9pMPGUfD6eY4Ux5bX3+RY5lj0+gscsxwVjiSnv2GY+RfzLRDjlwkAAA==
+        H4sIAAAAAAAA/52W224aRxjH/wMLCwuGBWM7Jond4HOcZMk5rl23rps0NOA0
+        cRSp8tVir+jasETMYqV3fpY+QVtfVGqlCvWyr9B3qfrNerXLjqFKiszOzHf4
+        z+/bOZi//vntDwAPsM+wwN1+kxuNvms229Zut922Dl276zx971oOpw5/4apg
+        DPqxeWoabdNpGS+bxxSkIs6Q6Vwk1m3uMhRX1+peWN+124awbTKsXDJu1UOt
+        muNaLau3uU2RC/Vur2UcW26zZ9oON0zH6bqmoOHGXtfd67fbFDUZiu30euYP
+        QlFFmiG5ZTu2u80QX117m0UGWQ0aJhhy0elV5MnWstzGMHsmMtLlOrIoYjKN
+        GEoMml/0vkWRhUh5ZCLEZdk2ruKZ4VmcE+voucm/p3gVsxrKgn0ioqPiGplC
+        dI9AGx7kJZgs5vGJ4L4RcjfMdzI3mQhnQ7aN4v6YUkhCxbKGFakUz74WKcWD
+        0oYHeYkvi1u4LUq5Q/QdecMyXInQhx6Cuz3GNW5dSqOCVdwnT0g8PHdhhG16
+        NE0Wj/BYlPGEIbV12PY37dIHHpLFD9tZj//3Qq5/1Jsq1E+6LtVgNCzXPDJd
+        k2yxzmmc7hcmHmnxAAM7EZ0YOd/bolel3tFdhr8HZ8va4EyL6fP0TWmxVJza
+        G3675LcL1CbLWb1QThWVYqwaqzIaFYNRslzUJ8u5i5Fv0yiiFETkKjP64CxM
+        //PHZIrmLSupuK6QLxFqhS5VT1Wu62lZOAzI6FnKnQhnCV15XRcl3mOi+rn/
+        uF/vnNCxTe/bLcd0+z2L4errvuPaHavmnNrcpqyd8B5kUHa7R5Y4HLZj7fU7
+        Tav3RijT2dnv9nuH1jNbDGZ9jbeXFHCXtp5CK6DQBUN3Go0aYmWwiT1qk0Sb
+        orYs7o3AtyX56CAGvs8kH+3uwLcd8aUxiwSN4nhJoxXyi0/md2jf/YrcAPpP
+        3lb5lp6a51SoVXwpNSI1i0IgdI1s4qP8gqlQIelZE2OypzFzGaNMGFcHuC5j
+        pKlN+0JXJKG5QGgIoyJjaGOyF7B4GWOFMFYHuClj5KjN+UJLktB6IDSEYcgY
+        +THZVdoUF9k3fYxcuCgDPJBJJjFB3wute5LWw0BriGRDJimNzE7hU2SpL7Lb
+        PsmTkOQcU+EinaMSvqpzGBHgc2z8HMxY8bQTxJ4gbo0WTPxvzdMby9NrL9Hv
+        oBLN9crjqeM1tceU+TlFf3GAeA07NXxZwy6+quEpntXwNZ4fgHHU8M0Bpjge
+        cbzw/h7S4eIoev0CR5Ljltdf51jkmPf6cxwzHFWOBKffXpj+F3+GwS2MCQAA
         """,
         """
         stubs/MutableCollectionObject.class:
-        H4sIAAAAAAAAAKVWW1cTVxT+zoSQIRlhEg03r62oIWkJalU0FEWKJQpBAalC
-        WzuEMQ4kEzszoWpv9Gbvtxcf+thnH+pqi1rX6qL2rT+qq/vMDBMIg9LlWsm5
-        7H32t69nn/nn3z/+BPASfmTYaVqVGTM9UrGUmaI6UC4W1byllfXRmTlahMAY
-        SsNzyoKSLip6Ie2QMw6lYmnFdFWkd9W5rG6pBdXI9GWG58tWUdPTcwultEZU
-        Q1eK6ZJizKuGmT63Tm+GQa5VF0IdwzY/lSHUM3T9Pw0hiAz1vZquWX0MgUTn
-        pIQwImEEITFsrarpNwzl5rBmkv7GMJo4t7HKdRhRBqmjY1YtqgXFUq90k/XD
-        a89kJGzFtgYIiDPUWdc0k2H38BOjTjEIKLOzdDyR7ZxiiK6LawjbGUILSrGi
-        jl5laKZzPsGXsBO7wtiB3QzxxPosdk5JaMNzEcTwPMGREyVVtxhYlgJEBvQX
-        iwxtCd9kZ7hhaX9eb8q3ErjE3uGyUUjPqdaMoWi6mVZ0vWwpXMhM58pWrlIs
-        kveia4opIsmwyy+/BGsQgJY3Q3iB3MtfU/PzLsJ5xVBKKh1kOODj9irKOAcp
-        ZHgJdCEdxovolrAfB3hIDlFc/V1nCOaLqmJIOIIIP3qUTM6XdYu7JKHHCelx
-        hsgK0Y5k1yai5ZrYZ+cm4xjyMuVGMwdL162bdr0S5yROcU4/6dXIT8UqG7wK
-        OlcpyLp0sjbly/C/rhIG8ArHPkM1YKil8oLKkX3O8nR2PCmdlAle3QQ55ETk
-        HF0vHyCGBkcRRUlCznF61Kby4NnUCw51jEJRUK1x7ZZqh4IKtc6kjYRJXOQH
-        XlvTPnKV0gy/LJd5nHRrkt8XCdO4GMYUXufF3x6mi/kmQ2x9DngibbbCHcjy
-        VV7CBBcWQOpDVtnuEAyJxLTP5fKhMezpnTjhk+7E9MQESdBAtaVwVBFzDPv8
-        Kr9aOROOASFQcfVtcE03aZmEAvQwSihTjnwtjyf8PUpt1B820GJyLdRkxN58
-        0e7BPJzUWsVsbnyiPzcwKOEGWnm/pMjuq2mm/jVLHXLllRmhkplVLIVoQmkh
-        QK8c40OQmto8kW5ofEddWpg9yNix5cWusNAqhAV5N/3FsCAGaY7QHKB5V3h5
-        kSZii3U0d/JZ/Pu20Lq8eEiM1cWEbqGbnQ6JwuOf6wU5cDYqh9qFbvFQvdxA
-        szD0+A472yKHbZokR9pXZCSb0yBvIU6jvY7KTTWSAZKUN5SMco69bpJjHner
-        Ldcsb6u1wrYvTojNGyC2yC3+nLGYXMdRLj2+EySU+vY6MSjX8/BRdwS15nUv
-        2OANS6W2TA2ga56yvH2soltaSc3qC5qp0cn+aoegGz6uFXTFqhh0neoGyrM0
-        NQ1ruurc2wmOzK9mOa8UJxVD43uX2FGL6/X8NQq2jFtKfn5Eue6KhcfLFSOv
-        ntH4ps3FmFxnGQ5S+QXpHwIvxDZekeTtF1Q79TR3AnKMv+q0/pJoAt6lncC/
-        IojyFVEGEKA9EE/ex5ZkoPcRmi7fh7yM2O9ovmeLfE1j2DmEKP2/oZVE4nzf
-        Qup4eKk/uYBH6SQ/25j8Dc3bH2DPQ+wVcNc+xSWbHa4ryVcd2Ec8xl8zMoZj
-        HHcxoqlY6gEOcqTUQxxeDxP1YKJI0mfiipcJfEtziDkhoPGI53DC1kUecdSH
-        OMZwzwN1vAp7XvU8yasTm/Mq8xSv+jbvVW+tV/S4+nt1mq0CrfWKnk3Xohqp
-        Vxl+2UDKMWBwdWHRSI8NUTnSYde3iOvV8HqvIp5XEQrOCPE8b87aR3NPidT5
-        Z4jUhadgjz8DNj20/lm4tGEW5H7+OetKnXItkpKpZUwt4Y0lXLnr3bx696ZV
-        DZM8wyQK5Fu2dz0e2piLFk/9hR0/IRi4W4Wd4bABfGePrGED/LiHH/fwhzz8
-        URc/tgZ/xxJmNwUe88BjHvikF8C0G8BgcglX/WPgxDHoVXMB19waPOZa1pSK
-        zfPMLiNEGb5eLWnHgibPgibM4W0vr5oNZriW7HctETnMA1RqL4booohY8FpL
-        i41P9f0IAjXRd37FrXs2IeCqCOB7e/4cP9Bskth75Mn70whk8UEWH9KIRT58
-        lMXH+GQazMSn+GwarSb/3bZ/EROTJiZMXDTRZlM6TOw3kbTXR+yxx0TGxEkT
-        A/Z2yETWRM7Ehf8A1Au5SlEPAAA=
+        H4sIAAAAAAAA/6VWW1cTVxT+zoQkQzLKEAzXilpRA2kJotUWkIKINRpACaUq
+        tnYIIw5MJnZmQtXe6M3erw8+9LHPPtTVFrGu1UXtW39UV/eZGRIIA9J2rWTO
+        mb3P/vZ9n/nr799+B3AU3zPstuzitJUaKdrKtK4OFXRdzdlawRibnqNNGIwh
+        n5lTFpSUrhizKZfc61KKtqanyiJ9a86lDVudVc3e/t7MfMHWNSM1t5BPaUQ1
+        DUVP5RVzXjWt1LkNensZ5Ep1YVQx7PJTGUaIofPfaQhDZAj1aYZm9zMEEu2T
+        EiKIRhCExFBXVjNomsqtjGaR/p0R1HDuzjLXZdQySG1tM6quziq2erWLrM+s
+        P9MroQ67qiEgzlBlX9cshj2ZLaNOMQjPqnZWu606BqZJ0KIXCS1ojiKGp4is
+        zMwQOZFuv8xQuyHwYewlkAVFL6pj1xjq6ZxPdiQ8jf0R7EMbQzyxMc3tlyW0
+        4iBXeYjgyMu8atgMjCwKkQGDus7QlPCthl5uWMqf15f0LRUusT9TMGdTc6o9
+        bSqaYaUUwyjYCheyUqMFe7So6xQe0TPFEpFiaPUrAII1CUDLWWEcJvdy19Xc
+        vIdwXjGVvEoHGQ75uL2GkuUgs728Ro7gaATdeE5CEs/wkBynuPq7zhDM6api
+        SuhBlB/lJucKhs1dknDCDSlVX3SV6ESycxvR8kzsd3Iz4BpyknKjWcP5G/Yt
+        p16IcwrDnHOa9Grkp2IXTF4F7WsUpD062Zb0Zfj3s4QzSHPsc1QDppovLKgc
+        2ecsT2fbVumkTPDyJ8gRNyLnqf98gBiqXUUUJQlZ1+kJh8qD51AnXeorEprQ
+        HKFuu7RukIwW89O8K6Z4QAx7kjeGhFf50St4jVf5Hi70OkNsY7B5xhx2jls6
+        ynfkc9guOBOCIZGY8ukdHxrD3r6JHp9sJqYmJkiCHlQ6CkcVMcdwwK+wy4Ux
+        4RoQBtVO/yZduE3LJMzCiCCPAqXA1/J4wt+j5Gbtv4kWi2uhGSL25XRnBvNw
+        0mgV06PZicHRoWEJN9HI5yVF9kDFMPUvSRqAq7fMCFXEjGIrRBPyCwG65Rh/
+        VPMHaHDNE/2mxt9oVAszhxk7vrLYGREahYgg76G/GBHEIK1RWgO0tkZWFmkh
+        tlhFaztfxT/vCI0ri91irComdAld7GRYFB7/GBLkwNlaOdwsdIndIbmaVuHM
+        47vsbIMccWiSHG1elZEcTrW8gzg7nX2tXFMhGSBJeVPJWs5x9jVyrMStc+Tq
+        5V2VVjj2xQmxfhPEBrnBnzMek6s4ysXHd4OEEmquEoNyiIevm/Ggtm64xoZv
+        2iqNXmryznlKdct40bC1vJo2FjRLo5OD5SlAXZzVZg3FLprUU1VDhRlaajKa
+        obotO8GReVcWcoo+qZgaf/eIbZW4pbm+TsGOrK3k5keUG55YJFsomjn1tMZf
+        mjyMyQ2W4TDVYJD+YfBqbOJlSd5+RrUTorUTkGP8aqf950QT8Ba9CfxTgihf
+        EGUQAdoBdR0PsKPjEWouPYC8gtivqL/vCHxJT179QJw+L+L4inaSK4IGUsaD
+        S9PMg0vw+uUSHb+g/iF2M9xzTpSlIiUpGmee1DHC5xp2cqmWZRx4iISwRrLe
+        5XqSfNeODkcT3XLkAMd4wcOoTca6lnGMIyUf4vmNMLUlmFqkSGw1Ms/ia1rD
+        zA0bPXtKQarwqo/h/qZendjKqxe359XAE7wa2r5Xg5Ve0aXr79VLW+WKrlPP
+        ogqpDMNPm0i5BpxdW4z0pLuJqBzpiOdb1PPqwkavoiWvohScceKVvBlzjmaf
+        EKmX/0ekJp+AffE/Y1/g38heFlJePIMdS7h8r9RyIYe4tt2CLrY8yL92PeEB
+        zzCpI7mCK0u4ugTFH8O1TyrZJ1E8p4l/gX/oeWjjHlo8+Qf2/YBg4F4ZdobD
+        BvCN82TVm+DHS/jxEv5ICX/Mw4+tw9+3hGvbAo+VwGMeOKOr+rpXTcc98Jpk
+        bJ7naAXh5DJulIvTBakpgdRgDm+UMqQ5YKZn6UEvKSKHWUaxssRFD0XEQmlI
+        NDj4VKmPINAQffNn3L7vEAKeigC+ddZP8R2tFom9TUl9ZwqBNN5N4700FvE+
+        bfFBGh/ioykwCx/jzhQaLf77xPlFLbRYaLLQbKHVobRbSFpIOfse53nCwoCF
+        UxbOOK8jFkYtZC1M/gPQMrgUVA8AAA==
         """,
         """
         stubs/MutableCollectionSubclass.class:
-        H4sIAAAAAAAAAKVWW3PTVhD+ju+RBZYNzg3KpQRw7DZOoEDAaSCk0BicBJKQ
-        QtKWKo4wSmSZSnIK9Jbe6PWZhz72mYcy0wZoZzopj/1Rne6RFSWxZZIOM/Y5
-        0u7Z7+y3u2eP/vn3j78AvIGfGPabVnXOzI5WLXlOU4YrmqYULbWiT1bnipps
-        mmEwhnJhQV6Ss5qsl7Ljcwu0IleTVC1Vy64bDWxYl9ctpaQYucFcYbFiaaqe
-        XVgqZ1WSGrqsZcuysagYZvZyw845Bql+uzACDLu9tgwjxNDz/3YII8IQGlB1
-        1Rpk8Ke6p0UIiAoIQmTYtb7NkGHI9wqqSfvvFBDj2p3r2poiziB2dc0rmlKS
-        LeVmL3lf2LwmJ2IXdrfAhyRDwLqtmgwHC1vEnaLgl+fnySCV755hiDdENow9
-        DOElWasq47cYWmmdR/hFvIJ9AvZiP0My1ZjH7hkRHTgYRQKvEhzRKCu6xcDy
-        FCJyYEjTGDpSnunOccey3rqBjGctcItDhYpRyi4o1pwhq7qZlXW9YsncyMyO
-        VayxqqYR+4jjihlBmmGfV4YJ1iAAtUhV+hrRK95WiosOwhXZkMsKLWQ46kF7
-        g2SSg5RyvAh6kBXwOnpFHMFRHpJjFFdv6gzBoqbIhogTiPKlJ8nlYkW3OCUR
-        /bWQnmaIrgntSPZsI1qOi4N2bnI1R96k3KjmhfId655dsaQ5i3NcM0T7qsRT
-        tioGr4LuDRvkHTl5m/FUeB9YEcN4i2NfpBowlHJlSeHIHmt5OrtelE7KBK9v
-        ghypReQyHTAPIIaW2kYUJRFjNdLjtpQHz5ZerUknKBQlxZpU7yt2KKhQAya9
-        iJjGNb7gnU0NZKxanuOH5QaPk25N8/MiYhbXBMzgXV78nQIdzfcZEo054Im0
-        1TInkOdPRRFT3NgH2j5sVewewZBKzXocLg8Zw4GBqTMe6U7NTk2RBQ1UWzJH
-        jWCB4bBX5a9XzlTNgTCouAabHNNteiaiBF1AGRXKkafnyZQ3o0yz/tBkF5Pv
-        Qk3mcF2n9C5Han5rV8goVcO8bMkk85WX/HSJMT4EqV8tkuiuyt+oBfvm+xjr
-        W13uEXztPsEn7ad/RPBFgjRHafbTvE9YXaaJ1JEAzd18bl9dPhZJBBK+Xl8v
-        Ox98/kvIJ/kvxaVwp683ciwktdDsG3n+kF1qkwRbJkrRzjUL0da0SDtIs9N+
-        jkuxOks/WUpNLeNcYz/HpISr3WXbtUq7672w/UsSYmsTxDapzVszkZACHOX6
-        84ecZagzEAlKIR44anmgfttwMV24aynUa+lU9yxS6lom1ZIuW1WDTkFguDJP
-        U6yg6krtuE1xW36iKkVZm5YNlb87wq6Jqm6pZSWvL6mmSiK3VQ+tdw6GPfXL
-        Nml3TFpycXFUvuOACpOVqlFULqr8pcMxnW4wRB+d2yD9w2gBkxL8Yia2X1HV
-        +LBEvYPxDwEavybJMPwkBZLpJ9iR9g/8idiNJ5BWkfgdrY9tk29oFOxFrYjT
-        /wE9iWRORmhDO69P3mAcwJO0kq/dmf4NrXue4sAzHPLhkb3qgY1hax1L/tSF
-        w6Rj/DoiZzjGaQcjnklknqKPI2We4XgjTNyFiSNN33prLFP4luYwR+22TU64
-        hFP2XsSIoz7DKYbHLmiNleCy6n8RqzPbY5XbgtXg9lkN1LOi29Gb1Xm2AbSe
-        Fd17jkd1Vm8z/NrEqubABXxHc8jdn24LknKk4w63qMOq0Mgq6rKKUnBGSeey
-        uWQvHdsiUldeIlJXt8CefAlsuim9s3C9aRakIf496lidczwS05lVzKzgvRXc
-        fOSevJBt17rBMdF1TKRAfmCz63fRJhy0ZOZv7P0ZQf+jddg5DuvH9/bIWprg
-        J138pIs/4uKPO/iJTfh7VzC/LfCEC55wwafdAGadAAbTK7jlHYNaHINuNZdw
-        26nBU45nsUxikWd2FWHK8J31kq55EHM9iGEBH7p5VW0ww/HkiONJhMM8RbX+
-        YEQcFL9j7ccP9vwlfqTZpDUfkZN3Z+HP414e92nEx3z4JI9P8dksmInPsTyL
-        dpP/vrB/URPTJqZMXDPRYUu6TBwxkbafT9hjv4mcibMmhu3XERN5E2Mmrv4H
-        PrD+CPEOAAA=
+        H4sIAAAAAAAA/6VWW1cTVxT+TkLuI5kECbcWpaIG0hJAqy0gBW81GkAJpSq2
+        dghjHJhM7MyEqr3R+/3Vhz722Ye6VovYrtVFfeyP6uo+k2ECyURou1Yy58ze
+        Z3/7vs/89fdvfwA4jh8YDhhmedFIT5VNaVGVz5RUVc6bSknLlRfzqmQYATCG
+        YnZZWpXSqqQV0jOLy3RitEIpm4qargqNbTuX0Uy5IOuj46PZlZKpKlp6ebWY
+        Voiqa5KaLkr6iqwb6Ut1mkcZxFp1ATQx7HdTGYCfYeDfaQggyOAfUzTFHGfw
+        JvvmBYQRCcMHgaGlqmZS16V7WcUg/c1hRDm3ucqtMGIMQm/vkqzKBcmUbw6S
+        9dmdZ0YFtGB/CB60MjSZtxWDoSe7S9wpCoGCbOaU+7JlYoZEDXoR0IXOCOJ4
+        jsjS0hKRk5m+6wyxutAHcJBAViW1LM/cYkjQOZf8CHgBh8LoQS9Da7I+0X3X
+        BXTjCFd5lODIz6KsmQyMLPKTAZOqytCRdK2HUW5Y2p03lnItFi5xKFvSC+ll
+        2VzUJUUz0pKmlUyJCxnp6ZI5XVZVCk/QNsUIIs3Q7VYCBKsTgJKnMh4i9/K3
+        5fyKjXBZ0qWiTAcZjrq4vY2S4yCFUV4lx3A8jGG8LCCFF3lITlJc3V1n8OVV
+        WdIFjCDCj3KT8yXN5C4JOFUJKdVfZItoRXJgD9GyTRy3cjNRMeQ05UYxzhXv
+        mPeseiHOWZzjnPOkVyE/JbOk8yro26YgY9PJtpQrw72jBVxAhmNfohrQ5WJp
+        VebILmd5OnuflU7KBG8AgpyqROQydaALEEOoooiiJCBXcXrOovLgWdT5CvVN
+        AR3oDFO/XdsxSqbLxUXeFQs8IJo5zxtDwFv86A28zav8ABd6hyFeH2yeMYud
+        55ZO8x35HDBL1oxgSCYXXHrHhcZwcGxuxCWbyYW5OZKgB5WOxFGDWGY47FbY
+        1cKYqxgQANXOeIMu3KNlAgrQwiiiRClwtbw16e5RqlH7N9BicC00Qw7XTEr3
+        aqPZtnWFTFGylyRTIpqnuOqlS4zxR4g/QDNpheh3Ff5Gc9izNMTY0ObaQNjT
+        7gl7xAP0D4Y9QR+tEVq9tHaHN9doIXawidY+vrZvrg0H401xz6BnkJ32Pf3J
+        7xG9F2NioNMzGBz2iyFaPReePmAX28SwRRPESOeWhGBxQuI+4jRb+5gYrZH0
+        kqTYUDLGOdY+KsYdbosllxD311ph2ddKiIkGiG1imztnNi42cZSrTx9wL/2d
+        TUGf6OeBG2Y8nN11t9O5u6ZM85Q6d2CF8hfKKQVNMss6tULTmdISLdGsosmV
+        TpvjsryZSnlJnZd0hb/bxN7ZsmYqRTmjrSqGQiRnHE9WpwNDV+2xHdx9OVPK
+        r0xJd2zQcK5U1vPyeYW/dNii83WCGKLm9dE/gBCYGOe3M3n7OVWNB6s0QBj/
+        GqDnF0SZhJd2QEv/Y+zr/x3Ra48hbiL+KxKPLIEv6cmnAZCgL4QEvqKdUBFB
+        G9qtuqRxZMMleZVyif5fkHiC5xkeWieqUmFHiuaRLXWC8LmGZi7VtYHDT5D0
+        bJNMVLi2JN/1od/SRNcUOcAxXrUxYqn44AZOcKTUE7xSDxNzYGJIk9hWZF7C
+        17QGOOqAJTLiBKnGqzGGRw29OvUsr17bm1cTu3h1Zu9eTdZ6Rbemu1evPytX
+        dB/aFtVIZRl+biBVMeAivqHV7+iny4WoHOmY7VvE9upKvVcRx6sIBWeWeI43
+        M9bR3C6ReuN/RGp+F+yr/xn7Cv/ItbOQtuPp61/H9YdOy/kt4vZ281WwxUn+
+        uWoLT9iGCf2pTdxYx811SO4YFfsExz6B4rlI/Cv8S81Gm7XRWlN/oudH+LwP
+        q7BLHNaLb60nCzXAb3XwWx38KQd/xsaP78DvWcetPYHHHfC4Dc7orr1tV9NJ
+        Gzyaiq/wHG0ikNrAnWpxVkCiDkgUy3jXyZBigem2pUfspAQ5zAbKtSUetFG8
+        trQX31nrZ/ieVoPOvEf5ursAbwb3Mrifwfv4gLb4MIOP8PECmIE1fLKAdoP/
+        PrV+EQNdBjoMdBrotih9BlIG0tZ+xHqeMjBh4KyBC9brlIFpAzkD8/8AHPTg
+        +vQOAAA=
         """,
         """
         stubs/MutableListObject.class:
-        H4sIAAAAAAAAAKVYi38TxxH+7mRLsnTGZ4FtbBPzMkG2ADkkJQl2IIZAIjAm
-        YNcluG16lg5zth5Ud3JJ2iQmbZK+36UtfSZN37SFJjE4tKlD+kzbf6m/zuyt
-        z5J8MvqRH+ZutTvzzTezs7Mjvf+/t98B8AD+q6DDdkpTdvJEyTGmsuaIZTsn
-        p2bMtBOCosAYmTHmjGTWyE8n3elBd6bkWNkkCw+VSaTyjjltFgcPDI7MFpys
-        lU/OzOWSFs0W80Y2mTOKs2bRTh4vszWoQK82EUKDgnWVZkIIKojXixpCWEFw
-        yMpbzgEFgXjfhIYIohE0QlOwfgV6uFg0nnE11kXQwqtab2/GzJrThmM+PUDs
-        qvwd1NCKWBNUrFfQ4Jy3bAWdIzViSN4FjEyGBOOpvrMKWlfFKoROBaE5I1sy
-        T55T0E5yPgHV0I1NEXThHgVt8dV70ndWQwc2RxHCFoIj+jkz7yhQUgoa46lU
-        34SA9lGcYMUdrHgviVr5jHmRIkech7NZcixe5v3hQjZLOlYhP8i+JP3XhhK+
-        CcEa20cKxenkjOlMFQ0rbyeNfL7gGKxkJ0cLzmgpm6WAhSV7O4zdCnr8tpxg
-        iwRgpe0QkhSR9HkzPSsRnjSKRs4kQQU7fSJVNjPGINMiBPdhbwQDuF9DH/o5
-        GB+iePm7rqBrOZB+URmosVgzLGzyITa5n+KfzppGUcMQojzzCAUjXcg7HCwN
-        B939fVRBdHlS7NGeOvZBOu/aO+S6+Bjl5rTpcEJV5JyU1XAUj7PcE5RQIi84
-        PzmPUzVyMKXhGEZY5QSr2EdyF5xnxOkjoyfxJK+cIpcs2hzDKRQ5JfvKuKfk
-        PIU44bvgX2o0jGGcsSnHo1nDdlIuWQ1nXDZP0ZnO0pFMeXa7KuBHytYGOa9r
-        LdayP4mPsp2PK+j2QumHPFB7tTb0Jxh6is5k0cwV5kwOmo8sp17vWseLTgaX
-        JoLMuHk0TXXQB0hBk2uIckvDjJsqs7RrctZhAJEXeSHKeShEL7iin6QNtzmr
-        Orjs+BrY6VuI/DLQRokx5yid7NIUx0vBhhXclZqsoM9nulZQL+IZhv00OXCu
-        WMil3KIXcgrLIzoWY9azpshdyvYGmz5ouIR5Vnux4sYaLeWmuIp/jhM770xw
-        IdfwMuYjeAmvcHHdGKG74gsKYn4edqCXl7/Mx1sIfpXP3SYefZ2P03EefZNT
-        WYy+zdE3eXRZQ86V+x7fC6/wghD5AYfN4dGPNLzAPFT8RHgn7jq6ROOTPuH3
-        mVOwZWh8v08ViU+Oj5MGPahkGYwaxuu0M35lKIRfKNjhV8RXZMZdaiH8SsGB
-        GjdOnZw1vIrfRPBr/JbS29entri/r4laV10NK39gK9do14fSWdFncKCpfQin
-        RsfGh0cPH9HwJtq5T3iLAlBXZlJ/sNw3naCDlTEcg+bU3FyAejWFH410pdNh
-        VC9a/Im6EzVzn6Kmlub3RdSNakTVt9L/cEQNN9I7GlmapxdNhwP07qE3Lel9
-        9GbRBL0j4fdeVjcuze8Nxxpi6oA6oBwKhdXbrwVVPXCsVQ91qQPhvUG9id7q
-        E7cvK8c6xVyE5qI8V7G2WdekvLum6c1dy7jrhESHlFi90qS3MK4Yt+p6ld0A
-        abbW0GzXY5JJdFla8F9POBtWcWzS2xhHjFv0dg+rQ1hp1Teu0mjROz2pLulF
-        2UyZXebSXR0xwWUT6dxTk39PFX9F8u/QN9fQ6dG3lOuUR0robqW92ObpKLS+
-        Xcr1Lts4HdMbeHzm9uVG0gl2NYQb9SAn1F6Fkg09spddOQlHLjom9Vx0m+yZ
-        pTrcfbqUd6ycmcrPWbZFksMr1w0V1jFrOm84pSIV0YbDhQy9WkasvOmWy3FG
-        5opYSBvZCaNo8Wc52VuN6zV0FQaaxxwjPXvCuCDVImOFUjFtHrX4Q6fEmFjF
-        jDo9lb4EqFTH+Wh28hklb/9KpylI712AHuP+nsZ/ozkVN9BLT/ruQDN/p5nD
-        CNBnoK3/Bpr7A0O30PLUDehLCL2FDdeFyj/oGRFCQYIK4p800kidlOhfO59l
-        vhYk4D6SZNl1/W9iQ/dN9Cxiq4qrQoo1291VqcmjbdhOa4zRKzGGiRQXhBaB
-        sUmA7AzgugeyxV32QFoQFyA8YjiVxtT5khTDPSwptSZie27iAQZNLGLfalat
-        HmArduNBL2gJ/IveIcWNqMB+SGI/JqnGdnnY3bsWMRgoA3fZxjzwmMc2Jsyo
-        0szDwkyTKhRdQ0PeRsVFjGgn2MQi6GvgSjjc3Yh4u3Fwrd0Yrm83Dt0hfEfq
-        D9/h6vBRR0DTq/ktIqViCV3X1uDnhq4swelJfUVtf0fr85caev9In1bK9Ksj
-        Ta26jFKV1kcUXKuh5Qblw1U+nFnLh7P1+UCNuz+bp+/E5mNVbKhPl0j3SzZR
-        uUNpFdXbE/WoROX2uKBGFSi1enLbK0Apmc6v9q8cdBssWvOS6JwQnblDgmY/
-        QILmaiZo4a4S9MIduBY/AFfqjiVXrxaVlc1PBSr5rlWL3MpZyZy+W0jmByS6
-        5qIv4jMBVONqHq6G5ySuhucFrkv/2Sp86uj9j91nax47fZh/G5Jaj8p4av2J
-        Jby0gM8v4ItXsXxtBYVesCys5Qy34UtQBNoOiXZc+tjc371rGe4r133hXIeb
-        PbhmL5DNAljFKf6JQwKfljTbEu+i6woaA1dX+H6N+QbwvngqTTWIt3mW2jzi
-        R/G4xN8v8YP93Qv4xrU1AhD0cIKS8Sn+maMGT7WM57fujifhn6kL/zt3jZ/x
-        4nxS4scq4ty1gO/WBV5+LlbAlwvzIxK8iYP8/QVcWSvRmjyoJjfOtF8Zb78q
-        oH5IJ3WtLfODslFaI2d/7A9XT85e8g5kUh7Ixv4F/NTfVfdcNnrX4at4Tdai
-        B6WDLYnYz7nOLeGXiZu4Wl04y1u41/E7r8r9TID9XjK5VzIJM8xNXK++y8IS
-        JYw/ev1Sh8Cn2+MWVOpo33gDC9fFRECaCODf4v0e/kPvK6R2kzxZnEQghbdT
-        uEVP/Ikff07hHfxlEopNpfTdSeyw0W7jtviL2rhk4wUb8zY6xMw28Yzb6LOx
-        W4yHbBy0ccjGURubbByzcdLGmFg6Y2NSDDI2TBszNnI2LtiwqajbuGjjORvP
-        /x8chhqA3RgAAA==
+        H4sIAAAAAAAA/6VYiXsT1xH/7cqWZGmN1wLfxIZg4kMEGZKSBjs0DhAiMCZg
+        1yW4NFnLi1lbB9WuXJM2LU3apOl90pbeaXrTFprE4NCmDumZHn9Sv868fV5L
+        8q7xR77P3n2aN/Ob38ybN+9J7/7vzbcAPIj/KmixndKUnTpecoyprDli2c6J
+        qVkz40SgKDBGZo15I5U18jMpVzzoSkqOlU2x8lCZRjrvmDNmcfDA4Mhcwcla
+        +dTsfC5lkbSYN7KpnFGcM4t26liZr0EFerWLCGoUbKp0E0FYQe9GUSOIKggP
+        WXnLOaAg1Ns3oSGGeAy10BRsXoUeLhaNi67FphgaeFbr7p42s+aM4ZhPDxC7
+        qngHNTQiUQcVmxXUOOctW0HbSEAOKbrIjOmMWc+agkaaTGz6oKENrXFE0E5i
+        Y3qaxL3pvjMKGtckM4JOApk3siXzxDkFzaTnk3EN27A9hi7cq6Cpd+2i9Z3R
+        sBXd7HInwVF8OTPvKFCIUW1vOt03IaB9DCfYsJ8Nk6Rq5afNBUotcR7OZhW0
+        r9iI/BwsZLNkZBXygxzMQMDkUNK3Zthkx0ihOJOaNZ2pomHl7ZSRzxccg43s
+        1GjBGS1ls5TTqORvR7FXQadfVRBskQCsjB3Bg5STzHkzMycRnjSKRs4kRQU9
+        Prkqk4wxyIxIwj48FMP78H4Nu5HidOynjPnHTgXRG5yVlP9cYFLY4SPs8AOU
+        /0zWNIoahhFnyWOUikwh73CqNBxy1/ewgviKUKzR7g04lKG7/o64/qg0QlS8
+        XFAVNSd1NRzDCOsdp4ISdcH1yXWcDqjBtIYTOMkmp9jEPpy74FwU+4KcjuOD
+        PEN1GLVoaQynUOSS7CvjnpZySnDSd8K/F2k4jacYe5IykzVsJ+2S1XDWZfMR
+        2vRZ2rNpz297BfxI2dwgL2DQZJD/Z2Cwn4yCDi+VfsgDwbPB0CZDz9CeLJq5
+        wrzJSfPR5crrXm9z0b7g3kWQlltHVDmbfYAU1LmOqLY0FNxSuUCrJqUOA4i6
+        sIUq16FQLbmq87TgNldVC7cdXwc9vo3IrwIX8CxjfpzKyS5Ncb4UbFnFXW3a
+        Cvp8xEFJfQ6fZNhLFMC5YiGXdptexCmIkYYWtMboAPhMxdk1WspNcbt+kSs4
+        70xwx9bwOVZ9CS9zF72Hjb6gIOEXylb08fSXeR8Lxa/yBtvOo6/zvnmSR9/k
+        mhWjy5zmWR59R0PR1bvCB8DLPCFUfsD5ucijHwny4qyjQ7R30ie7PjIF24bG
+        9/s0id7J8XGyoAd1JINRo3iVEu/XZSL4uYKdfh16VWfcpRbBLxUcCOicG+Ss
+        4Sf4dQy/wm+oen1jaur1jzUZ1LIDvPyevVyjtR7KZMU9gxNN14doenRsfHj0
+        4GENr6OZ7wlvUAI2VHh0/K/cm47Tvpk2HINkam4+RHc1hR91/AAd23MkX7D4
+        E11R1Ok9ippevrQvpraqMVXfTv/RmBqtpXc8tnyJXiSOhujdSW+a0vvozapJ
+        esei77yoti5f2htN1CTUAXVAeSwSVW+/Elb10NFGPdKuDkT3hvU6eqtP3L6s
+        HG0TshjJ4iyrmOvSNanvzml6ffsK7iah0SI11s7U6Q2MK8aNul7lN0SWjQGW
+        zXpCMomvaAv+mwlnyxqOdXoT44hxg97sYbUIL4166xqLBr3N02qXUZRJyvwy
+        l47qjAkuW8nmnkD+nVX8Fcm/Re8KsOnUt5XblGdK2G6ntbjXs1FofofU617x
+        cSqh1/D49O3LtWQTbq+J1uphLii6VlGZdcoL7ep2OLzgmHSrohNj9xz12o5T
+        pbxj5cx0ft6yLdIcXj1SqHmOWTN5wykV6VCqOViYplfDiJU33U45zsjcDAsZ
+        IzthFC3+LIXd1bjela3CQf2YY2TmjhsXpFlsrFAqZszHLf7QJjEm1jDDHtqV
+        tfQfAe/PNt6oFO1faTeF6b0H0BN8yafx30im4ga66UlfIEjyd5IMI0QjYHP/
+        DdT330LDUzegLyPyBrZcFwb/oCf3AwZsoP9/0khzTdBEzji5dIhIuF7e0WzR
+        /zq2LKFDwVWhsWoV86zoFJFW+wifPWxiq46b2LGE+9Qyy2Z3VlryqEd6oqOm
+        LBBuIg0CY6sA2RXCdQ9kmzvtgTTgfgHCI4ZTaUz3YdJiuEMSLrEr8cBNPCxA
+        dy1hMFRGy0VMeIgJDzGBvRgiRDfnA3iXG54qDPeIJ92DpaOHZeyNSc9RcgmP
+        rg2/0fPTKNBXVvSAQI8oHvawt7hVq3FQKUtH9WocWm81Ht/Yahy5Q1RHNx7V
+        E9VR0QWCxGv5LWFUxTK6rq3Dz12Wsk1BT7qGBMc7trF46aLvn+kPrVf3dIWX
+        Waqy+rCCawFWblLOVMVwdr0Ynt5YDHSh92czfSc2U1Vs6P4ukR6QbOJyhc6r
+        qF6euEclLpfHBT1XBUo3Q7nsFaBUTLm18ZWD9iBPc14RzQnVwh0K9KPvoUCL
+        gQXq3FWBlu7A9WPvgStdpiVXr8+Vtc1PhCr5rtfn3M5ZyZy+c0jmByS65qIv
+        4dMhVONqHq6G5yWuhhcErkv/UxX4J/kHJ1n2KVmytf2L+OxVrJxXYSEsP6tq
+        XSf6MP90JI0flWnV+pPLeGkRn1/EF/0x3OyWE+3Bl6AItH6JdkyGWt/fsWsF
+        7ivXfeHcuOs9uHovn/UCWKUYD3k0T0maTcm30XUFtaGrq3y/xnxD+Jd4KnUB
+        xJs8T00e8WMYkfj7JX64v2MR37i2TgLCHk5YMj7Jv4IE8FTLeH7r7ngS9tkN
+        4X/7rvEtL88nJH6iIs9di/juhsDLt8cq+Ep/fkSC13GSv7eI769XaHUeVJ2b
+        Z1ovy1uvCqgf0oZdb8n8oBbw7Do1+2N/uDvXrELfJF+RXeUhybEhmfgZd6xl
+        /CJ5E1erW2D5ZexV/NbrVz8VYL+TLO+TmzzKMDdxvfpUikqUKP7g3XxaBD6d
+        A7eg0o32tdeweF0IQtJFCP8W77/gP/S+QmY3qUksTSKUxptp3Erjj/gTDfFW
+        Gn/G8iQUG2/j9iR22mi28Y74i9tos9Fio9XGViHpEc/7bey2sVeMh20csnHE
+        xjEb222csDFu47SYOmvjGTGwbMzaKNgo2ijZWLBx0cZzNp638cL/AWVqBCvg
+        GAAA
         """,
         """
         stubs/MutableListSubclass.class:
-        H4sIAAAAAAAAAKVYi1sU1xX/zSzsc5BhFRAw+MK4sOoSk5pGiAaNJquoUSg1
-        0jYddkcc2AfdmaWaNgm2TdMmfT9sa59J07dttU1QkjYl9vn1j+rXc+5cht1l
-        FvczHzBz995zfud3Hvfcy/73f++8B+AR/EdBl+2Up+zUqbJjTOXMUct2xspT
-        mZxh2yEoCozRGWPeSOWMwnTqzNSMmXGG3JmyY+VSLD5cIZEuOOa0WRo6NDQ6
-        W3RyViE1M59PWTRbKhi5VN4ozZolO3WywtqQAr3WRAhNCjZUmwkhqCDRKGoI
-        YQXBYatgOYcUBBL9ExqiiEXRDE3BxlXokVLJuOJqbIiilVe1vr6smTOnDcd8
-        bpDY1fg7pKEN8QhUbFTQ5FyybAU9o3WjSP4FjGyWRBPp/gsK2tZEK4QuBaF5
-        I1c2z1xU0EFyPiHV0IMtUXTjAQXtibVZ6b+goRNbYwhhG8GRA3mz4ChQ0gqa
-        E+l0/4SA9lGcYMVdrPggiVqFrHmZYkecR3I5qo9Ehf9Hi7kc6VjFwhD7kvJf
-        G076lgRr7BwtlqZTM6YzVTKsgp0yCoWiY7CSnTpddE6XczkKWFiyt8PYq6DX
-        L+kEWyIAK0NlmqKIZC6ZmVmJ8IxRMvImCSrY7ROpipkxBpkWIXgI+6MYxMMa
-        +jHAwfgQxcvfdQXdK4H0i8pgncW6YWGTH2aTByn+mZxplDQMI8Yzj1MwMsWC
-        w8HScNjN7xMKYiuTIkf7GsiDdN61d8R18UmqzWnT4YKqqjkpq+E4nmK5p6mg
-        RF1wfXIdp+vUYFrDCYyyyilWsY/l55wrYv+R0TN4hlfOkksWJcdwiiUuyf4K
-        7mk5TyFO+i74NxsNYxhnbKrxGG06J+2S1XDeZfMs7eocbcq0Z7e7Cn60Ym2I
-        67reYj37k/gY2/kEtQIvlH7Ig/VX60N/kqGnaE+WzHxx3uSg+chy6fWtt71o
-        Z3BzIsisW0fT1Al9gBREXENUWxpm3FKZpazJWYcBRF0UhCjXoRCdc0U/RQm3
-        uao6ue34Gtjt24j8KtBGmTHnqZzs8hTHS8GmVdzVrqyg32e6XlAv4wrDfoYc
-        uFgq5tNu0ws5xZURbYsx63lT1C5Ve5NNHzRcxQKrfa7qzDpdzk9xF/8CF3bB
-        meBGruGLWIjiZbzCzXVzlE6LLyuI+3nYiT5e/gpvbyH4Nd53W3j0Dd5OJ3n0
-        LS5lMfoOR9/k0TUNeVfu+3wuvMILQuSHHDaHRz/W8BLzUPFT4Z047egYTUz6
-        hN9nTsG24fGDPl0kMTk+Thr0oJZlMGoYb1Jm/NpQCL9UsMuvia/KjLvUQvi1
-        gkN1TpwGOWt4Hb+N4jf4HZW3r0/tCX9fk/WOujpW/shWbpJvDRUdHf0rl6JT
-        tGeyhmPQnJqfD9BVTOFHM53WtM/UyxZ/oquHmn1IUY8uLxyIqpvVqKpvp79w
-        VA030zsWXV6gF02HA/TupTct6f30ZtEkvaOblxf2h+NNcXVQHVSONN99I6jq
-        gRNteqhbHQzvD+oReqtP372mnOgSc1Gai/Fc1dpWXZPy7pqmt3SvoG4QEp1S
-        Yu1KRG9lXDFu0/UauwHSbKuj2aHHJZPYirTgv5FwNq3hGNHbGUeMW/UOD6tT
-        WGnTN6/RaNW7PKlu6UXFTIVd5tJTGzHBZQvpPFCXf28Nf0Xy79S31tHp1bdV
-        6lRGSuhup1zs8HQUWt8p5fpWbJyL6008Pn/3Guc72N0UbtaDXEr7FSoz9Mor
-        6mp5H7vsmHSRoiNi3yw118iYNV0wnHKJel/T0WKWXq2jVsF0u9w463IjK2aM
-        3IRRsviznOw7Vy44Vt5MF+Yt26Ip7x42snoM0QFZK1a12jLmGJnZU8acBI2O
-        FculjHnc4g9dUnVijSJd31S626vUnCNQ9Dhf0cnbv9E+UvEn7KQxXf/puUwz
-        RxGgWaB94DZaBgLD76L12dvQlxF6G5tuCZX36RkVQiGCCuEujTRSJyX66eAd
-        y31dAh4gSZbdMPAWNvXcQe8Stqu4IaRYs8NdlZo82iEoMUafxBghUrztWwXG
-        FgGyO4BbHsg2d9kDaUVCgPCI4VQa09WVpBjuMUmpLRnfdwePMGhyCQfWsmrz
-        ANuwF496QUvi7+w9k9wjVOiOKrGflFTjezzsnj1LGApUgLts4x543GMbF2ZU
-        aeYxYSaiCkXX0LCXqISIEWWCTSyB/pNbDYebjaiXjcPrZWOksWwcuUf4jjUe
-        vqO14aMjnabX8ltCmqe7b67Dzw3dP2gc9PDoYlDf39ON+Us3cv9In1Mq9Gsj
-        TXdtGaUarY8quFlHyw3KR2p8OL+eDxca84Fu3v5snrsXm4/XsKGLtkR6WLKJ
-        yQxlVNSmJ+ZRicn0uKBGDSjd1WTaq0CpmC6t9a8SdAcsWvOK6KIQnblHgeY+
-        QIHm6xZo8b4KdO4eXEsfgCtdbyVXrxdVtM1PB6r5rteL3M5ZzZz+OZDMD0l0
-        zUVfwmcDqMXVPFwNL0hcDS8KXJf+8zX4dCX333afr7vt9BH+ckdqPSHjqQ0k
-        l/HyIr60iFdvYOXYCgq9UEVYKxnuwGt0PjLaLol2UvrYMtCzZwXuq7d84VyH
-        Wzy4Fi+QLQJYxVn+jkICn5M025Pvo/s6mgM3Vvl+nfkG8E/xVCJ1iLd7lto9
-        4sfxlMQ/KPGDAz2L+ObNdQIQ9HCCkvFZ/p6iDk+1gue3748n4Z9vCP+7942f
-        9eJ8RuLHq+LcvYjvNQReuS9WwVca8+MSPMJB/sEirq9XaBEPKuLGmfKV9fJV
-        BfUj2qnrpcwPykZ5nZr9iT9cIzV71duQKbkhmwcW8TN/V9192ewdh6/jDdmL
-        HpUOtibjv+A+t4xfJe/gRm3jrLzCvYnfe13u5wLsD5LJg5JJmGHu4FbtWRaW
-        KAGpHcC/xPs9/Jve10nmz0TyrUkE0ng7jUV64jY/7qSxhHcmodh4F3+ZxC4b
-        HTb+Kn5jNq7aeMnGgo1OMbNDPBM2+m3sFeNhG4dtHLFx3MYWGydsnLExJpbO
-        25gUg6wN08aMjbyNORs29Wsbl228YOPF/wOZ1FsqfRgAAA==
+        H4sIAAAAAAAA/6VYi3sTxxH/nWTrecZnGb+JDcHEDxFkSEoaTGgcIETYQMCu
+        S3BpcpYPc7YeVHtyDW1amrRN0/eTtvSdpm/aQpsYnLSpQ9/9o/p1Zm99luST
+        8Ue+z75bzc785jezs7Mr/fd/b70D4FH8R0OHcErTInWi5JjTWWvMFs54aTqT
+        NYUIQ9Ngjs2ZC2Yqa+ZnU6em56yMM+xKSo6dTbH6wTKNdN6xZq3i8KHhsfmC
+        k7XzqbmFXMomaTFvZlM5szhvFUVqtMzbsAaj2kUYdRq2VLoJI6Shf7OoYUQ0
+        hA7aeds5pCHYPzCpI4Z4DPXQNTSvQY8Ui+Zl12JLDI08q/f2zlhZa9Z0rOeH
+        iF1VvMM6mpCIIoBmDXXORVto6BqrmUWKLzxrOeP2FUsSSZORoA86OtAeRxid
+        JDZnZkjcnx44p6FpXTrD6CaQBTNbsk5d0NBKej4517EdO2LowYMaWvrXL9vA
+        OR3b0MsudxEcRZiz8o4GjRjV96fTA5MS2sdwkg0H2TBJqnZ+xlqk5BLnkWxW
+        Q+eqjczQ4UI2S0Z2IT/MwQzVmDyY9K0aNtk5VijOpuYsZ7po2nmRMvP5gmOy
+        kUidLDgnS9ks5TSi+IsI9mno9qsLgi0SgJ2hSn6UcpK5aGXmFcKzZtHMWaSo
+        oc8nV2WScQaZlUnYj8dieB/er2MPUpyOA5Qx/9hpX/XXzkrKf65mUtjhE+zw
+        A5T/TNYyizpGEGfJU5SKTCHvcKp0HHHX96iG+KpQrtGeTThUobv+jrn+qDSC
+        VLxcUBU1p3R1jGKM9U5QQcm64PrkOk7XqMG0jlM4zSZn2EQczV1yLst9QU4n
+        8EGeoTqM2LQ0plMockkOlHFPKzklOOk74d+NdJzFc4w9RZmhXemkXbI6zrts
+        PkLbPku7Nu357ayAHyubG+YFrDVZy/8LMNlPhnqFl0o/5KHas7WhLYaepT1Z
+        tHKFBYuT5qPLlde70eaifcHdiyBtt46ocpp9gDREXUdUWzoKbqlcolVTUocB
+        ZF0Iqcp1KFVLruoCLbjgqmrjtuProM+3EflV4CKuMObHqZxEaZrzpWHrGu5a
+        29Yw4COuldQX8UmGvUoBXCgWcmm36YWdghzpaEN7jI6Az1ScXidLuWlu15/j
+        Cs47k9yxdXyeVV/Bq9xFH2CjL2pI+IWyDQM8/RXex1Lxa7zBdvDoG7xvnuXR
+        t7hm5egap3mOR9/VUXT1rvMB8CpPSJUfcn4u8+jHkrw87egY7Z/yya6PTMP2
+        gxMHfJpE/9TEBFnQgzqSyagRvE6J9+syYfxCwy6/Dr2mM+FSC+NXGg7V6Jyb
+        5Kzjp/hNDL/Gb6l6fWNq6fePNVmrZdfw8gf2cpNi21RN0cm+eik6QVtixnRM
+        kgVyC0G6imn8iPIDdCLPk3zR5k90/wjM7NUCh1eu7o8F2gOxgLGD/iOxQKSe
+        3vHYylV6kTgSpHc3vWnKGKA3qybpHWtfubovkqhLBIYCQ9pT9XdfCwWM4PEm
+        I9wZGIrsCxlRegeeuXtNO94hZTGSxVlWMddj6ErfndONhs5V1C1So01prJ+J
+        Go2MK8dNhlHlN0iWTTUsW42EYhJf1Zb8mwln6zqOUaOFceS40Wj1sNqklyaj
+        fZ1Fo9HhaXWqKMokZX6ZS1d1xiSXbWTzQE3+3VX8NcW/zeipYdNtbC+3Kc+U
+        tN1Ba/GgZ6PR/E6l17vq40zCqOPx2bvXeL1DnXWReiPEpUR3JSqwbnVPXavx
+        o4uORVclOgb2zFMDjY7bs3nTKRXpLKk7XJihV+OYnbfcBjfBttzDChkzO2kW
+        bf6shL1nSnnHzlnp/IItbBJ5N62RtaOGDsFqtYrZhnHHzMyfMC8p0Nh4oVTM
+        WE/b/KFDmU6uM8ReanT19B9GFJqR4Hs6RbtC+yiAP2Injek7AD3fJckIgjQC
+        mgdvo2HwbTQ+dxvGCsJvYustaXCXntw5QXCN9P83GumuCVrQKncqnQIKrp/3
+        LVsMvoGty+jScENqrFnFPCs6BpTVfsJnD1vYqusOdi7joUCZZas7qyx51Kc8
+        0VlRFgi3ikaJsU2C7A7ilgey3Z32QBrxsAThEcMFaEwXWtJiuCMKLrE78cgd
+        PC5Bdy9jOFhGy0VMeIgJDzGBfThIiG7Oh/B3bmsBabhXPukiqxw9rmJvSnqO
+        kst4cn34TZ6fJom+uqKHJHpY87BHvMWtWo3DWlk6qlfjyEar8fTmVuPYPaI6
+        vvmonqmOim4AJF7PbxknOc89Nzfg5y7LP2gc8vDoHlE73vHNxUs3df9Mf2ij
+        uqc7uMpSldWHNdysYeUm5VxVDOc3iuH5zcVAN3J/NjP3YjNdxYYu4ArpEcUm
+        rlboYgDVyxP3qMTV8rigF6pA6Wqnlr0ClIoptz6+ctA+5GnOK6J5qVq4R4F+
+        9D0UaLFmgTr3VaCle3D92HvgSrdhxdXrc2Vt8xPBSr4b9Tm3c1Yypy8Nivkh
+        ha676Mv4dBDVuLqHq+MlhavjZYnr0v9UBf5p/sVIlX1KlWz94BI+ewOr51VI
+        CsvPqnrXiTHCv/0o4ydVWvXB5ApeWcIXlvAlfww3u+VE+/BlOloZbVChjapQ
+        Gwa7dq/CffWWL5wbd4MH1+Dls0ECByjGIx7NM4pmS/Jd9FxHffDGGt+vM98g
+        /imfWrQG8RbPU4tHfBRjCv+Awg8Ndi3hmzc3SEDIwwkpxqf5Z4waPANlPL99
+        fzwJ+/ym8L9z3/i2l+dTCj9RkeeeJXxvU+Dl22MNfLU/P6HAo5zk7y/hBxsV
+        WtSDirp5pvWyvfWqgPoRbdiNlswPahFXNqjZn/jD3btmNfoq+JrqKo8pjo3J
+        xM+5Y63gl8k7uFHdAssvY6/jd16/+pkE+71i+ZDa5BGGuYNb1adSRKEElXUQ
+        /5Lvv+Lf9L5OOn+i/f/GFIJpvJnGUhq3cYeGWE7jLbw9BU3gz/jLFHYJtAq8
+        I//iAh0CbQLtAtukpE8+HxbYI7BPjkcEjggcExgV2CFwSmBC4KycOi/wghzY
+        AnMCBYGiQElgUeCywIsCLwm8/H/95bQCgBgAAA==
         """,
         """
         stubs/MutableMapObject.class:
-        H4sIAAAAAAAAAJ1X63cT1xH/3dXT6wXW8hPxMAkmtqUkMpQkEBs3xnWMbGP8
-        ICbBeXQtL2atlUR0Vw7kSfNOkzbP0jYf+5kPcNqSkJyT49Jv/aN6MrO7liV5
-        cRyO0d65c2d+M3fuzNzL//7/w08AjuNbgQ7pVJZk5mzFMZZs86xx5dzSqplz
-        YhAC5alVY83I2EZxJeOxBz1OxbHsDMkO1Qhki465YpYHA1jDg1P5kmNbxczq
-        WiFjEbdcNOxMwSjnzbLMTG4aHxTQG23GEBbYVWc3hqhA7w4xY4gLRIesouUM
-        C4T6+hc0qGhWEYEm0LkJPGUV8+byGUNedrV2q9jDElpPz7JpmyuGY74yILCn
-        PgSDGlqQaIKCVoGwc9mSAl1TwUGl3UVytmmUNXSiuRkxdAk050pFx7CKctK8
-        Rgh92f6LAi1bghjDfoHYmmFXzHOX6NhILiDSGg6iW8UBHBJo79t6fP0XNSTx
-        MJs+TLHIs0mRpfBuOLHABjT0ejJ95LBrkmRXTEegZ6pUXsmsms5SmaUzRrFY
-        cgzHKhE9XbFt3i7t8pEg01tZGtJ4jO08Tluz5FjhinPNPSHycgBHeeUYza9U
-        yHJnXzZwxwInAozt0PxxPMlGnqL8ICMjti2Q6Gs43/4FgaEG5lA6wJMg3rCr
-        fni7qJUcDhztI3ypXCrEcUrgYFBmE2SZlK2cjOG3dLq5y2Yu72vPGGWjYJIg
-        VcX20ZhnkJVBroERnFbxDEY1nMTTHIYxCkPZLJTWKAHGvYM5I6DSwY+xbZMy
-        u6WvvyYS8yan9Ewjb6g+WD2sfW3HrWKYIOMmqxCUhrOYZEemKUPIEaoRyekV
-        bLEBibZDCe6izHko8x7KvPW66eYZZX5Y0kTDBSywwPMCTSTgVgEXcp2h0ZJt
-        Uzjp2Aj6sfss3dcVt46khpewyJZerut005XCEtf472nvdOJ+FS5hQYWBHNfs
-        PpVaDHmdCMrjXm/5cvDxBzeKNDcKBXmmVpkqcD08wVSJz99dfZUpd5U8n8Ak
-        UxUNMx71mobn2EUF1zRcxCJTb9AOhnK22215Tg00np2ePz8yPTqm4R10cKu8
-        LvDUA94klIMbl8lZ0zGWDccgnlJYC9GNJvgToZaWJ9ZVi2fUsZXlo0J8tX79
-        hKp0KaqiH6FfXFXiTB+mXy/RNNe7aQzRqKjr12lopqlKYw9N4//9UOlav35s
-        dyKcUAYU7zsgTsfiyr1/RBU9NNGkJ5LKQOuZezfERIveRnT7sajeQaPi8zp9
-        XleV16XvTYa7xIBSIxly8ZKEt4/lXblD+v56uVoUV/7ARLd+kO0fa9O7k3oi
-        Ghc1fh7yrT20xZqnnZzr0cPJtoSeqN9fdCDy/L0bEZKJJsPxmB6f69KbknF/
-        tXZNpbWE3syoNVxN30Uau6sae2rWdL2FT4b6O6gozY0GE867FX7Qvzo362rs
-        qmNS96OW+XieroN9c5WiYxXMbHHNkhZJjmz2VKrheWulaDiVMhVMeLS0bPK1
-        bRVNr8zOMzJXUiln2AtG2eK5z+xpxK221joDu+YdI5envPXV1PlSpZwzn7V4
-        stfHWNjiGY5S8kfoFwOXwV6uB9r+l5SnURqHAD3BzwmivyKegndJRuHXCnG+
-        Js4oQjQH2lPfYVcqNPQj9rzwHfR1xP6Nttuuyjf0VV0hnaB0/IUojdRJif46
-        uEr49eED9tHIa2rqX2i7i70Ct12JTS21qkVNyNd6kvDZwm7W2vc9HrqLHgU3
-        q5od3qqvydQRPOJa6t0Oo397jJSPQZ2L1hjjpI/RsomRUbCOA7caYFqqMC2+
-        Kxsxf9SVpNdGcEB+I2pcagwItUvfkXE6l5B7Lr4j+11nToTqnTnkCVWdafed
-        YYp3pzS4RRczadTtNJ0Y/h6/YzPpu3hWqTmurTs9VZNJg7hBY0x4aUbf8e2i
-        mH2gKNIF4bvbEMVzAptY9VH0vJuqrQH6ztwP6fwvIc02INEFFXyyL2x3snSZ
-        Bdt/5Zfsv1hnf5Zf2779OT/M7en/4MC3iIRuptLrMO5g+Q4usSsh/NX9iia3
-        iKMuul4T//rEWaH1WX6p7wDf+tX4KR+fHgf3wRe3NvHtWw/kvz7C/wPw8Z/2
-        8aOp9B0Ub2GjmW3FiVZxolUcesr7OLN+LbZuuPfohpdXgkG9qmytgrb6wWWK
-        w8BJNb6jMJQfOAzjwWFwflUYyE96LvtVnfETN5K6g7VgGC9/Iw2VOMuv5QCQ
-        qzsHmaW/C9XCqwV5/eYOQGb5kRzgwZs79+BFxPFW9ZbrdOMFNP8Ihe7Lt/+J
-        P9x2GSFfPIS/ueMX+DuNX5LaewT4PjWBLD7I4kP64iP+fJzFJ/jjIoTEp/hs
-        EQ9LdEj8yf3XLPHnDXpCYlLic4kZiQsSz0ksSLzkLl2UWJTodOmk+z0i0SuR
-        kkhLdEsMSByXeELipMQpV2D8Z8BtlfOyEQAA
+        H4sIAAAAAAAA/7VW61cb1xH/3ZWQhFjsRbxk2QEnlmMBiYWp6ziF0gIhtgzG
+        Brk0sUvTRazxotXK1V1RO325r/SRPvJo3Tb91s/+gE9bJ27O6aHut/5RPZ3Z
+        XYQkFqJyTs+R9s6dO/ObuTN35t5//+fv/wBwHn8S6JNOdVVmr1YdfdUyrup3
+        r61uGAUnCiFQmd/QN/WspdvrWY897nGqjmllSXaiTiBnO8a6URkPYE2OzxfL
+        jmXa2Y3NUtYkbsXWrWxJrxSNiszO7RofF9CabUYRFuhssBtFROBMi5hRxAQi
+        E6ZtOpMCoczQsoo4OuJogyrQvws8b9pFY+2yLu+4WkfiOMoSajq9ZljGuu4Y
+        b40KHG0MwbiKLiTaoaBbIOzcMaVAcj44qLS7+LrhzNpOxTRIriszVAeWN1jg
+        ejNvotFemrXvtxz4SYI8NV+urGc3DGe1opu2zOq2XXZ0xywTvVB2FqqWRVIx
+        g4HJoIrjSHYgihMCUXJ3zrhPvr64j19N9ijSRcNDOemhPO+h5M23DTf6OQqT
+        pImK00izwIsC7SSwrFtVDkqywdBM2bIocuQrQb+8z9K+rmy6mCpGMMSWXhJo
+        K1iGXlFxFh3MyQp0FMq2w3GhfZJrmdzQTcrMHsAoPkcbcQGv3aayIbkAqyo+
+        jwtxqqxXBHoze8tn6KaKc3iVTX+BolFkk4Ii0rnjhBsFFZOezJfIYdckyVKI
+        BNIHpZLyyMdtnJMVYHovS8U0XmM7s7Q1U86W7jr33RyRl5dwmVfIt9DdKlnu
+        z+QCdyxwMcBYi+bncJWNLFCqyMiUZQkkMk31NbQsMNHEnBgJ8CSIN+mqh29X
+        yqUY8gIDQT0jx/VoS7Mgo/gK5a1wxygU/cK4rlf0kkGC1G8O3meeQdbHubt8
+        FW/EsYw3VVzHIm/wFm2wYpTKm5TaFS/kX1fRj2Sc+sY3VAx41KqKU0gztaYi
+        gyGmbjd0xIVqaZXP4h2qV/LfPy0brGSiyGdrjJVKFMegeE96y3c58ReY2mdb
+        wUd7DvOsU+U9uNrfIi8mCpbbWXlOzTKWW8jfmFqYmVXxbfRxW/yOwCuHvDWo
+        DncujquGo6/pjk48pbQZottL8KedP6AaKhL/nskzatHK2jkhPth+cDGuJJW4
+        op2mfyyuxJg+Rf8zRNNcG6QxRKMS335AQwdN4zSmaRr71ztKcvvB2JFEOKGM
+        Kt53VExHY8qzP0cULXSlXUuklNHuy88eiitdWg/RvWMRrY9Gxef1+7xkjZfU
+        jqXCSTGq1EmGXLwU4R1neVfupHaiUa4exZV/7sqgNsD2x3q0wZSWiMREnZ8n
+        fWvP77HmaaeW0lo41ZPQEo37i4y2vfHsYRvJRFLhWFSLLSW19lTMX61fi9Na
+        Qutg1DquqnWSxpGaxtG6NU3r4syMCc5X1Ni5A8NF93rpDrjkovgV9T+XpMr1
+        L9Pdrj97zzGoaqn1nS1Sgzq+VLUds2Tk7E1TmiQ5tdsb6YbJm+u27lQr1ErD
+        M+U1gy9y0za8grrByFwz5YJuLesVk+c+M92MW2sJDQY6845eKJLvvpqas22j
+        MmPpUvI24/lytVIwXjd57ZgPubzHUSpghd4lCjUIrp1jXEQUrvfpXEdoTAFa
+        gt8bRH9APAXfIxmFnzPE+ZA4UwgRBXQPf4zO4U9x9M2PoW0j+jf0PHYVfktf
+        rlVCoueNht8RpXoq6CVjnB1qTATDcBmuLdYY/it6nuI5gS1XYlcr7mt57hyr
+        d5W+A/shvfBZSINNSNQY/S02IZ0ReLQPkuAmGmz/5c+yP9xk/2wtxE1I1G8e
+        72uf+rGvdYEwOepHWOv4J7j4FONKned93qqvydQEvuhamjwI48sHY0z5GNOu
+        LmO86mN07WK8rmAb57eaYLpqMF2+KzsBmXEl6YEQHJArByWE7hDfkUuUGO7X
+        vTuOnHCduRZqdOakJ1Rzptd3hinendLkFt24fsZrOx1J3PgEN9nMyFN8TalL
+        196d5utqawkPaYyK2hlYOSiKbx0iiov81PYhs34U24afQN+q1WrEZdbXaVtT
+        xS3ySzsApNA6yCCBnK4VWD2I8agFkEV+YAd4sN66B8MEQg9j34MlP7y9I//E
+        +Y/QFno0PLIN8wmsJ7DZoxB+735F+x50L+6NB6ZM64v8qG4B/5v/M/4U42uL
+        /JjeB19s7eLLrcP6Pw3n/4evTfFr3Mdf9Guzewf2pR30zeCUelXaXQPt9p1m
+        isOjUHhWWgrPvUOHZ6Wl8BwWP4b7tRug35UBOj6FQvfr23/Bdx+7jDD+AO52
+        Ar+mG/w3kXb/dIfwR3d8Dx/R+D6tf5/O/4NbCOXwgxx+mMOP8GMi8ZMc3sFP
+        b0FI/Aw/v4UXJPokfuH+OiTe3aH7JZISv5QYkDgtcUoiLTHiLmUkhiTOuvQ5
+        9zshMSkxJTEtcUHiksScxLzEdYm8K7DyXx6SSY0REgAA
         """,
         """
         stubs/MutableMapSubclass.class:
-        H4sIAAAAAAAAAJ1WWXcTRxb+qrW63UBL3oRYTIKJbYlEhpAEYuMJMMTINuAl
-        MYvJ0pYb01ZLIqqWA1mZ7MlkliQzeZjHeeaBnDNDQnLOHA+P+VE5ube7LUty
-        23E4sqtuV9373Vt3q/r5lx//B+AY/imQkk5tQebO1xxjwTbPGzdnawsF25Ay
-        BiFQnVw2VoycbZSXchcXls2CM+yt1BzLzhH3SANDvuyYS2Z1OGBpdHiyWHFs
-        q5xbXinlLFqtlg07VzKqRbMqcxPr6ocF9FadMYQFdjTpjSEq0L9NzBjiAtER
-        q2w5owKhgcE5DSraVUSgCfSsA09a5aK5eM6QN1ypnSp2MYfW17do2uaS4Ziv
-        DQnsanbBsIYEkm1Q0CEQdm5YUiA9uZlb6XyRgm0aVQ09aG9HDCmB9kKl7BhW
-        WU6YtwljID94VSCxwY0x7BWIrRh2zbx4XaCb+AJ8rWE/elXswwGBroGNARy8
-        qiGNx1n1QfJGkVWKPDl4zYg5VqCh3+MZIINdlcS7ZDoCfZOV6lJu2XQWqsyd
-        M8rlimM4VoXoCzXb5gPTKZ8IUr1xSUMWT7Kep+holjxbuuncdmNEVg7hCO8c
-        pe+bNdLcM5APPLHA8QBl21R/DM+ykucoQ0jJKdsWSA60RHhwTmCkZXEkG2BJ
-        0NqoK35wK69VHHYcnSN8vVopxXFSYH9QbhNklYStAlXnHyi6hRtmoehLTxlV
-        o2QSI9XF1t6YZZClYa6CUzit4gWc0XACz7MbzpIbqmapskIJMOYF5pyASoE/
-        y7pNyu3EwGCDJ2ZNh+yeal0baXZWH0vf3nazGCXIuMkiBKXhPCbYkAuUIWQI
-        1Yjk9ArW2IJEx6EEd1FmPJRZD2XWest084wyPyzpQ8MlzDHDZYE2YnCrgBSl
-        mhSdqdg2uZPCRtBPbrK1qSluHUkNr2CeNb3a1Osu1EoLXOOv09kp4n4VLmBO
-        hYEC1+welZoMWZ0MyuN+b/tGcPiDG0WWG4WCIlPLTJW4Hp5hqsLxd3ffYMrd
-        JcvHMcFUTcOUR72p4WU2UcFtDVcxz9TbAs894jVB6bV2U5w3HWPRcAxaU0or
-        IbqwBA8R6lZFWrpl8Re1Y2XxiBBfrt45riopRVX0Q/QfV5U40wfpv59o+tZ7
-        aQ7RrKird2hqp0+V5j76TK3eObozGU4qQ4o3DonTkYf/jip6aLxNT6aVoY5z
-        D78V4wm9k+iuo1G9m2bFX+vx11L1tZS+Ox1OiSGlgTPk4qUJbw/zu3wH9L3N
-        fI0oLv++8V59P+s/2qn3pvVkNC4arDzga3tsgzZPOj3Tp4fTnUk92Xy66FDk
-        8sNv+YTRdDge0+MzKb0tHfd3G/dU2kvq7YzasKrpO0hiZ11iV8Oeric4JtS0
-        QZVmrnWNcNEt2/3+jbheLGdvOSa1NOqDTxWpx7fNWktlw6lVKc/DZyqLJt+3
-        Vtn0quMlluUCqBQMe86oWvztL+6ZqZUdq2TmyyuWtGjp1HqLpVurdbfeL5vY
-        dsw6RqFIGeuDqrOVWrVgvmjxx24fY24DPo5Q2kfoP4Y2CD3JLwI6/peUoQre
-        RYpoenDQ+BdaOYMQrQJdme+xIxMa+Qm7rnwPfRWx/6LzO1fkrzSqLlPC/f2N
-        KI3ESYh+3VwL/HzwAQdo5j018x90PsBuge9cjnUptS5FXcSXepbwWcNOltrz
-        Ax57gD4Fd+uS3d6uL8nUITzhaurfCmNwa4yMj0Gth/YY44SPkVjHyClYxb57
-        LTCJOkzCN+XvREdpPuxy0nMh2CFPiwaTWh1C/c43ZIziEnLj4huy1zXmeKjZ
-        mAMeU92YLt8Ypvh0SotZdLOSRNNJs8nRH/BHVpN9gBeVhnBtPOnJhkwaxlc0
-        x/hwI67I2FZezD+SF6nD++a2ePGiwDpWsxc96ybrSJ5xU5shvfRbSNMtSHTD
-        BEf2ylaRpdsoWP9rv6X/WpP+aX4u+/pnfDd3Zf+Pff9CJHQ3k12FcR+L93Gd
-        TQnha3cUbW4RR130RIP/mxNnifan+am9DXzrd+NnfHy63TfBF/fW8e17j2S/
-        foqf8D7+8z5+NJO9j/I9rDWzjTjROk60jkNvcR9n2q/FjjXzDq9ZeTMY1KvK
-        jjpoh+9cptgNnFRj23JD9ZHdMBbsBud3uYHspPeuX9U5P3EjmftYCYbx8jfS
-        UonT/NwNALm1fZBp+l2qF14jyFt3twEyza/cAAve2b4F1ygAHhXCN+78Z/yD
-        5q+I9z3ifZ/qO487efyJRnzAw4d5fISP5yEkPsGn83hcolviM/evXeLzNXpc
-        YkLiC4kpiUsSL0vMSbzibl2VmJfocem0Ox6S6JfISGQleiWGJI5JPCNxQuKk
-        yzD2KyjpAQxSEQAA
+        H4sIAAAAAAAA/7VW63Mb1RX/3ZWsl9fxWn4pSrADUYhsQ+S4aQjYGOw0JIqd
+        hy1qIMHAWt44a61WQXflJpSW8OgDSh9Amw/92M/5YGbaQGCGMfnIH8X0nN21
+        LMmSUT3TGenes+ee8zuPe8+594cfv/kOwCncE0hIp7IiM5cqjr5iGZf0W7nK
+        St7SpQxDCJTn1/UNPWPp9lrmysq6kXcmPU7FMa0MSU/VCGRtx1gzypNNWNOT
+        84WSY5l2Zn2jmDGJW7Z1K1PUywWjLDNzO+YnBbRGm2EEBbrq7IYREjjeJmYY
+        EYHQlGmbzrRAID2ypCKGzhg6oAoM7gDPm3bBWL2gy5uu1oEYullCTaVWDctY
+        0x3jzXGB7voUTKroQTwKBb0CQeemKQWS863SSvHF1gznnO2UTYMke9IjNXA5
+        wyGBq428qXqLKda+03bqpwny6HypvJZZN5yVsm7aMqPbdsnRHbNE9OWSc7li
+        WSQVMRiYDKo4hEQnwjgsECZ354w75OuTLfxqsEe5LhgeyhEP5XEPJWe+Y7j5
+        z1KiJH2oOIYUCzwpECWBJd2qcFISdYbOliyLTgH5StBPt1hq6cqGi6liDCNs
+        6SmBjrxl6GUVJ9DJnIxAZ75kO5wXipNcS2dHrtHO7AIM42cUiAt45YbAAMk1
+        sari5zgdo+p6RqA/vbuARq6pOIln2fRzlI0CmxSUka5tJ9wsqJj2ZF4gh12T
+        JEspEkjttZW0j3zgJnmzmpjezVIxi1+wnXMUminPFW85d9w9Ii/P4wKvkG+B
+        WxWyPJjONo1Y4EwTY22an8MlNnKZtoqMzFiWQDzdUGEjSwJTDcypsSaeNONN
+        u+rBG+VSMYKcwFCzrpHlerSlmae+90vat/xNI1/wC+OqXtaLBglSx9k7zhyD
+        rE1yf3kFr8awhNdUXMUCB3idAiwbxdIGbe2yl/I3VAwiEaPO8ZaKIY9aUXEU
+        KaZWVaQxwtSNup54uVJc4bN4k+qV/PdPyzormSjw2ZpgpSLlsVm+p73lW7zx
+        p5lqEVbzoz2HedapcAyu9q8EntnnlUAltn0rXDIcfVV3dOIpxY0AXU6ChygP
+        oPIoEP+2yV/Uf5XVk0J8unX3TExJKDFFO0b/SEyJMH2U/seJpm9tmOYAzUps
+        6y5NnfQZozlFn4mtuxMH4sG4Mq5447iY7Xj0r5CiBS5GtXhSGe+98OieuNij
+        9RHdPxHSBmhWfN6gz0tUeQntYDKYEONKjWTAxUsS3iGWd+WOaIfr5WpRXPnH
+        Lg5rQ2x/ok8bTmrxUETUeHnEt/b4LmuednIxpQWTfXEtXh9daLzj1Uf3OMJQ
+        MhgJa5HFhBZNRvzV2rUYrcW1Tkat4apaF2kcqGp016xpWg/vyYTgnQob2xdb
+        sODeGb1Nbq4w/khNzSWpHP07cqeVn7vtGFSK1M9OFKjrRHPmmq07lTJ1wODZ
+        0qrBN7BpG14dvMy6fNRLed1a0ssmf/vMQ4sV2zGLRtbeMKVJrJmdVkl9tHG1
+        Wud1Yl05R88XyHcfVM3atlE+y3c5hxnLlSrlvPGSyWsHfcilXeaoKhV6bihU
+        9VEILc5PBkrXp3SiFdxBgmh6kdD4Z+LMIEAU0Dv6FbpGv0X3a19B20L4P+j7
+        0lX4C41cfCCYbvr/lSjVU0E/Btyaoc5CMAyX5gpijdF/o+8hHhPYdCV2tGK+
+        lufOQfyN5hCtJF25oVZIT/wU0nADEnU2P8QGpOMC91sgCe6Cze0//VP2Rxvs
+        n6imuAGJusqXLe1TQ/W1ThMmZ/0Aax36GmceYlKp8XzAW/U1mZrC866l6b0w
+        XtwbY8bHmHV1GeNZH6NnB+MlBVs4tdkA01OF6fFd2U7IWVeSbvjmCbm414bQ
+        JeA7cp42hrty/7Yjh11nrgTqnTniCVWd6fedYYqjUxrcoivT3/FqpGPxl7/G
+        NTYz9hCvKzXbtTvSXE1tLeIzmsOiegaW98rim/vI4gK/lX3IjJ/FjtEH0Der
+        tRpymbV12tFQcQv8VG4Ckm8fZJhAjlULrBbEuN8GyAK/kJt4sNa+B6MEQi9b
+        34NFP739Y9/j1D/REbg/OrYF8wGsB7DZowA+d0cR3YXu5b3+wJRofYFfxW3g
+        v/0/488wvrbAr+EW+GJzB19u7tf/WTj/P3xthp/TPv6CX5u927BPbaNvNN9S
+        r0p7q6C9vtNMcXoUSs9yW+m5ve/0LLeVnv3iB/EFuJEJfEwX8SehqH9wA/i7
+        O/8J/6D5M1p/h472r68jkMW7Wfwmi9/iPSJxN4v38cF1CIkP8dF1PCExIPE7
+        99cp8fttelAiIfEHiSGJYxJHJVISY+5SWmJE4oRLn3THKYlpiRmJWYnTEucl
+        5iTmJa5K5FyB5f8CUiecwrERAAA=
         """,
         """
         stubs/MutableSetObject.class:
-        H4sIAAAAAAAAAKVXW1cTVxT+ziQhQzKYSbhjS62iBtISBItFkIoUNBpASUpV
-        2tohjDAkmdiZCVV7ozd7v7340Mc++1BXW8S6Vhe1b/1RXd1nMg4QBmUtF+Sc
-        mX35zv723uec5N///vwLwFH8xNBkWuU5MzlRtpS5gppRram5JTVnBcEYrqSX
-        lGUlWVD0hWRFPFiRlC2tkCTboU0GKd1SF1RjcHgwnS9ZBU1PLi0XkxpJDV0p
-        JIuKkVcNM3luY6VBBrl6gSD8DHVbFgmihuHwLjGDEBlqhjRds4YZfPHOGQkh
-        hEMIQGJo3gBOa3penT+jmIu2154QItxC6uiYVwvqgmKpV3oYIlv5DkqIIlYL
-        AfUMfmtRMxla0t4ZJHY+ZX6e7OKpzssM0W2pCqKVIbisFMrq1FWqBNl55FPC
-        XjwTQhueZWiMb69I52UJzXgujCD2ERwFX1R1i4GlKBEUwEihwNAa30RktFQo
-        kKdW0gd5YElv3VDCs7jc40C6ZCwkl1RrzlA03Uwqul6yFO5kJidL1mS5UCD2
-        ohOKKSLO0O5VQII1CEDLmUF0Eb3coprLOwjnFUMpqmRIxfegvUmS4SALg7zU
-        L+DFEBLoltCBgzwlVMMmb+oMgVxBVQwJfQhz06MUcq6kW5yShP5KSo8xhB8J
-        7Ux27yJbTojDdm0GKoHQekHNHCtes27YfUmaExjmmldoXY14KlbJ4F3QuWmB
-        lCMn74SnwnsHShjBKY79KvWAoRZLyypH9rDl5ex4XDmpErytCXK8khFqq3oP
-        IIbaykKUJQnpCukJW8qTZ0unKtLzlIoF1cpoN1U7FYToN+lFQhYZbvDaloNh
-        slyc45vldZ4n3Zrh+0XCJWRCuAi7+VtCtCPfYIhtrwEvpK2+wgmc5k+KhGnu
-        LCBHgVilEcNQqCbx+KzH5vKQMewbyh73KHd8NpslDxqotxSOKmKRocGrX4JY
-        YjjotSc2bLKV0IKgthveYQPvMmYJKvQQiihR9Tw5Nca9uSZ2Ojl2WMXkq9Dx
-        Iw7lCvYpzBNNB6uYmsxkRyZHxyRcRxM/Qm/wztvFdUJH56MbZYJ6aV6xFJIJ
-        xWUf3WGMDwE67fIkuq7xN9rywvwRxo6tr3SHhBYhJMgH6COGBDFAc5hmH83t
-        ofUVmkgt+mnu5LP4zy2hZX2lV4z5Y0KP0MNOBUXh4S81guw7G5WDbUKP2Fsj
-        19IsnHl4m51tlkO2TJLDbY98JFtTK9eRZo/9HJUjVZ4+8pR39Ixyjf0ckWOu
-        tt72a5IbqqOw42skxKYdEJvlZm/NdEz2c5SLD28HCKWmzS8G5Bqevl5GqUW7
-        c6dtlH3suqXSeU0nQ3eeirx3uqxbWlFN6cuaqZHlyMbRQVs/oy3oilU2aJv7
-        R0vzKr9PNV2tbOgsR+Z7tpRTCjOKofF3R9hRjeteBlsWqMtYSi4/oVxz3EKZ
-        UtnIqeMaf2l1MGa2RYYj1H0B+gTB+7CVNySx/ZJ6p4bmw4Ac4/c8PX9FMgHv
-        oZ5G+hpBkq9JMgofvQONXfdQ1+UbeoDIpXuQ1xH8Aw13bZdvaAzZRmGCCuNb
-        epLInZzor4l3Lj+4HMB+suS2e7p+R8PeNbTfx/MC7thW3LOponU8+dN+HCAd
-        49ccBcMxBhyMaCLWuYYkR0rcx5HtMFEXJoo4el2Wh/AdzUFWSQGNfS7huL0W
-        MeKo9/ESw10XtMIq5LLqfxyrl3fHauAJrIZ2z+p4NSu6db1ZnWSbQKtZ0X3q
-        RFTlNcbw6w5elQBGNzcWjXQLkZQj9Tncwg6rs9tZhV1WYUrOOdK5bM7Ypukn
-        ZGryKTI19QTsC0+BTTewdxVmdqyCPMK/5zpeJ52IpK7EOi6uYnYVb95xd16N
-        7RfeFJjkBiZRIt8i/QX+Fc9Bm3bQGhN/o+1nBHx3NmDf5rA+fG+PrHYH/EYX
-        v9HFH3fxpxz82Bb8tlXM7Qo85oLHXPCsm8Ckk8BA1yrmvXNQyWPA7WYVV50e
-        POZEFknENF7ZdeQTa7i20dKVCCJuBBEs4h23rgs2mOFEcsiJROQwayhXbwzR
-        QRGx7B4tzTY+BfoAAh2i7/6Gm3dtgc9Zwocf7PkL/EizSW7vE5MPZuFL4cMU
-        PqIRK3z4OIVP8OksmInP8PksWkz6cYtb9n/YRNbEtImMiWZbst9Eh4m4/dxn
-        j/0mBkycMDFiv46bOG0ibWLqfxuJKgUvDwAA
+        H4sIAAAAAAAA/6VX61cTRxT/zQaSJVnMEt5o0VbUQCpBtL5CqUixRl5CUqrQ
+        1i7JGhaSjd3dULUv+rLv5wc/9GM/+6Getoj1nB5qv/WP6umd3XV5LcppzyEz
+        s3fm/ube371zZ/j7n9//AHAMPzA0mVZl1kyOVixltqhmVGt8dl7NWSEwhisj
+        88qikiwqeiHpiFOOpGJpxSSt7Vu3IK1bakE1Uv2pkYWyVdT05PxiKamR1NCV
+        YrKkGAuqYSaH13ZKMcibNwihiqF2wyYhBBkO7RAzBJEh2KfpmtXPEIh3TkkI
+        IxJGNSSG5jXgEU1fUPPnFXPO1toVRpSvkDo68mpRLSiWeqWHIbrR35SEOsRq
+        IKCeocqa00yGlhF/Bsm7UEG1MtpN1TYkTRomfUhoRUsEIbSRWMnnSRxPd04z
+        1G3hMoR2AllUihV1/CqFitb5EC5hH54OYy+eYWiMbw1Z57SEPejgWx4gOPKu
+        pOoWAyOLgmTAQLHI0Bpf5+lguVgkTa2sp7hhSf+5voRv9LnG/pGyUUjOq9as
+        oWi6mVR0vWwpXMlMjpWtsUqxSPSIrimmiMMM7X4RJliDALScGUKS3MvNqbkF
+        F+GiYigllRZSdvi4vU6S4SCFFM+FI+gNowdHJXSii1PyHPHq7zpDda6oKoaE
+        k4jwpafI5FxZt7hLElIOpX0MkUdCm8nuHbDlmthvx6bfMeQMxUYzh0rXrBt2
+        vtDMWQzymRdpX438VKyywbOgc90GaVdO1iZ8J/yPqIRzeIlj8xww1FJ5UeXI
+        Pmt5ODseF06KBM97ghx2GBljqPcBYqhxNiKWJEw4Tk/aUk6eLc060pclNKMl
+        TMfslQ0lYqxSmuWn4jInRLem+MGQMMOXTuNVnuVPcaXXGWJbyeYRs6cVbukI
+        H+WIcqs8YBgKUR6Pz/icHR8Zw76+7GmfaMZnslnSoIZSR+GoIuYYGvzSIYR5
+        hgN+Kb+2JuuYFgJlVf8253OHNktQoYdRQpmC4+tTY9zf18R2hWGbXUy+C1UX
+        sS9XtKswJ5oKq5gey2QHxgaHJFxHEy+hN3hi7eA6ocr46EYZpVTJK5ZCMqG0
+        GKA7jPGmhjegirZA8usa/6LaLeSPMHZidak7LLQIYUHeTz8xLIjV1EeoD1Df
+        Hl5doo6mxSrqO3kv/nVLaFld6hVjVTGhR+hhZ0Oi8PCnoCAHLtTJoTahR+wN
+        yjXUC+cf3mYXmuWwLZPkSNsjHcmeqZFraWaXPa6To5s0A6Qpb6tZx2fscVSO
+        ebP1tl6T3LDZCtu+RkJs2gaxWW72n5mMyVUc5dLD29WEEmyrEqvlIKevl3FS
+        292LbS32Q9ctlWoynf7uBYr07smKbmklNa0vaqZGKwfWygMd74xW0BWrYlCB
+        qRos51V+qWq66pzlLEfmx7WcU4pTiqHxb1fYsRnXK/gbNqjNWEpuYVS55qqF
+        M+WKkVPPafyj1cWY2mIZ3QQCPQoEKjc8GVt5VpK3n1PuBKl/FpBj/LKn8Rck
+        E/A26qmltwRJviTJAAI0Auq77qG26wGil+9BXkXoNzTctRW+opYnP0glSr+v
+        aSQ5KmikzTi5VOZcuDjPX67R9Ssa7mM3wx17xZpW2NOiOudqHSd8vsMurrV7
+        Bfvv46CwTrPJmXU1+eiQuxNdf+QAxzjlYtQlYt0rOMaREvdxfCtMnQdTh8M4
+        4TGTwDfUh5hDG7UnPZI2eXWa4e62XqUe59XzO/Oq/wleDezcqxc2e0W3sb9X
+        Q4+LFd2zrkWbtC4w/LyNlmPA+fXJSC1dWiTlSEdd3yKuV+NbvYp4XkWInIs0
+        53kzai+deAJTmf/BVPYJ2FP/GXuCP57dKCRdPqu7lnHpjnfkgrZw/XGrdrDl
+        Af4MdpXPuIZJXYlVTC/jtWVc8cdw7JM8+yTi8w2bwJSHNumiNSb+xN4fUR24
+        swY7y2ED+NZuWc02+I0efqOHP+zhj7v4sQ34e5eR3xF4zAOPueCMbuqrbjad
+        cMGjiZjGY7SKhcQKrq0lpwMS9UCimMObXoQKNpjhWnrQDYrIYVZQ2Zzioosi
+        YtErEs02Ppn8AAIV0bd+wc27tiDgbhHAd3b/Gb6n3iS1dyio784gkMZ7abyf
+        xhI+oCE+TOMjfDwDZuIT3KKHoUn/3+JT+y9iotVEs8mFe2zJIROdJg7b45N2
+        mzLRb+KsiXP257CJERMTJrL/AgVNgdYyDwAA
         """,
         """
         stubs/MutableSetSubclass.class:
-        H4sIAAAAAAAAAKVXW1cTVxT+Tu5MBjOJ3MTWWkUNpCVcLBahVKSi0QBKUqrS
-        1g7JGIZMJnZmQtXe6P367EMf++xDXatFbNfqoj72R3V1n8k4QJgoa7kg58zs
-        y3f2t/c+5yT//vfn3wBO4meGLtOqLZnpmZolL2lKTrFytaWCJptmGIzhRnZF
-        XpXTmqyX0nNLK0rBGqtLapaqpcl6fJtBRreUkmKMTYxly1VLU/X0ymolrZLU
-        0GUtXZGNsmKY6Utba40xSI0LhBFgaN2xSBghhhN7xAwjwhAaV3XVmmDwJ3sX
-        RAiICghCZOjcAs6qelkpXpDNZdtrn4AYtxB7eoqKppRkS7kxwBDbyXdMRByJ
-        FviwnyFgLasmQ3e2WQ6Jn18uFskymem9zhDflawwDjCEV2WtpszdZOggO4+M
-        ijiIFwR040WG9uTumvReF9GJl6II4zDBUfgVRbcYWIZSQQFMahrDgeQ2KlNV
-        TSNPtaqP8cDS3rrxlGd5ucfRbNUopVcUa8mQVd1My7petWTuZKZnq9ZsTdOI
-        fcQJxYwgyXDIq4QEaxCAWqCO6yN6hWWlUHYQLsuGXFHIkMrvQXubJMdBSmO8
-        2K/gVQEp9IvowTGeEqpihzd1hmBBU2RDxDCi3PQkhVyo6hanJGKkntJTDNEn
-        QjuT/XvIlhPihF2b0XogtF5YNc9Vbll37M4kzRuY4Jo3aV2VeMpW1eBd0Ltt
-        gYwjJ++Up8J7D4qYxFmO/Rb1gKFUqqsKR/aw5eXseVo5qRK8sQlyup4Raqv9
-        HkAMLfWFKEsisnXSM7aUJ8+WztWllykVJdoo6l3FTgUhBkx6EZFHjhu8veNo
-        mK1VlvhmeYfnSbcW+H4RcQ05AVdhN3+XQHvyXYbE7hrwQtrqG5zAef4ki5jn
-        zj4UKBCrOmkYMtUkmVz02FweMobD4/nTHuVOLubz5EED9ZbMUSNYZmjz6pcw
-        VhiOee2JLZt8PbQwqO0mmmzgPcYsQoEuoIIqVc+TU3vSm2uq2cnRZBWTr2Lx
-        ptrDXUGn4pPrYobapChbMsl8lVU/XVGMD0E6yMokuq3yN9rNvuIgY4Oba/2C
-        r8sn+KSj9IkIvkiQ5ijNfpoPCZtrNJE6EqC5l89dm2tDkUQg4RvwDbCzwce/
-        hnyS/2JcCnf7BiJDIamFZt+Fx/fYxU5JsGWiFO1+4iHamhaplTT77Oe4FGvw
-        9JOn1NQzzjX2c0xKuNr9tl+H1NYYhR1fOyF2NEHslDq9NfMJKcBRrj6+x1mG
-        ugORoBTiiRtilFQccq6qrVqeu20pdAjTdu8vU+VacmpJl62aQbszMFUtKvwi
-        VHWlvg/z3JdvtWpB1hZkQ+XvjrBnvqZbakXJ6KuqqZLIPcMnt44UhoONZju0
-        rTlLLpRn5FsOqJCr1oyCMq3ylwOO68IuRwzShg7SJ4wWMCnBr2pi+xV1jQ+r
-        9jN9E6Dxa5JMwU9SoL3vIVr7/ON/IXbtIaRNhP9A2wPb5RsaBduI3/oivrWf
-        GHeivw7en/zkcQBHyJLb7uv7HW0HN3DoEV724b5txT076lrHkz8dwVHSMX5P
-        UTAcY9TBiKcSvRtIc6TUIwzuhom7MHEkMeSyPI7vaA5z1BO2y7BLOGmvRYw4
-        6iO8xvDABa2zElxWI09j9freWI0+g9X43lmdbmRF16Y3qzNsG2gjK7oQnYga
-        vM4x/NbEqx7AFL6nOeSuT9cISTnSsMMt6rC6uJtV1GUVpeRcIp3L5oJtmn1G
-        pmafI1Nzz8C+8hzYdIV6V2GhaRWkSf5F1fE640Qk9qU2cXUdi+t4776780K2
-        n7gtMNENTKREvk/6K/w7moM276C1p/5B9y8I+u9vwX7AYf34wR5ZSxP8dhe/
-        3cWfdvHnHPzEDvzudSztCTzhgidc8LybwLSTwGDfOoreOajnMeh2s4KbTg+e
-        ciKLpRIqr+wmyqkN3Npq6XoEMTeCGJbxoVvXkg1mOJEcdyKJcJgN1Bo3RsRB
-        8Tvefvxoz1/iJ5pNsvmIgry9CH8GdzK4SyM+5sMnGXyKzxbBTHyOtUX65YkO
-        E1/Y/1ETeRPzJnImOm3JERM9JpL287A9jpgYNfGGiUn7ddrEeRNZE3P/Axpj
-        kXLPDgAA
+        H4sIAAAAAAAA/6VWW3PTRhT+Vo7vCpGde6CBlgBOXOIQKDenKYFCMbmRxE1p
+        0pYqtnAUyzKV5BToLb3fX3noY595KDNtCO1MJ+WxP6rTs7IiJ44MmXbG1q7O
+        2e/bc9uz+vuf3/8EcAo/MnSZVmXJTE1WLHlJU+YUa66ylNNk0wyCMdycWJFX
+        5ZQm64XU9NKKkrPSVUnFUrUUrR7ZtiCjW0pBMdKj6Yli2dJUPbWyWkqpJDV0
+        WUuVZKOoGGZqvLZXmkGq3yCIJobmHZsEEWA4tkfOIEIMgRFVV61RBl+if15E
+        BNEI/BAZOmvEE6peVPJXZXPZRu2LoIWvEPv68oqmFGRLuTnE0LLT37SIGOJh
+        CGhlaLKWVZOhZ6JRDMm/YIFe1XuKbUqGMCa9iOhGVxRB9JBYzudJnMj0LzDE
+        dkUziF4iWZW1ijJ9i6GD1nmEXMQhPB/BQbzA0J7YnbT+BREH0Me3PEJ05F9J
+        0S0GRhYFyIAxTWPoTmzz9VJZ0wiplvU0NyzlrRtJeuafIw5PlI1CakWxlgxZ
+        1c2UrOtlS+YgMzVVtqYqmkbhCTmmmCEcZ+j1yjHRGkSg5qgkU+ReblnJFR2G
+        67IhlxRaSPXh4fY2yRwnKaR5NZzAcARDOCmiHwM8JC9RXL1dZ/DnNEU2RJxF
+        lC89RybnyrrFXRKRroZ0hCG6JbQjObiHaDkmjtq5Ga0acoFyo5qXS7etu3a9
+        kOYiLnHNq7SvSn7KVtngVdC/bYOMIydrk54K70Mq4gpe49y8BgylVF5VOLPH
+        Wp7OvqelkzLBK58ox6sRmWJo9SBiCFc3oiiJmKk6PWtLefBsabYqfV1EJ7oi
+        dNDe2NEkpiqlJX4q3uQB0a15fjBELPKlC3iLV/lzHPQOQ3x3sHnGbLXMLZ3g
+        sxyF3CqPGYZMIU8kFj3OjoeM4dBI9rxHNhOL2Swh6EGlI3PWEJYZ2rzKIYgV
+        hiNeJV9bk62aFgRV1WiD87lHm0Uo0CMooUzJ8fSpPeHta7JRY2iwi8l3sXjN
+        7OGuoKa3dV1MUhXkZUsmmVBa9dEVxfgjzB+gZlUk+R2Vv1FjFvInGDuxuTYY
+        EbqEiCAdpn8oIoT8NEZp9NHYG9lco4HUoSYa+/nYtbk2HIo3xYUhYYhd9D/5
+        OSBIvmsxKdgjDIWGA1KYRuHqk/vsWqcUsWWiFO3ZQoi2Jiw1k2afPY9JLXVI
+        HyGlhsgY19jzFinualttXIfUVm+FbV87MXY0YOyUOr01s3GpibPceHKfexno
+        aQr5pQAP3DDj4ex17qtaQi/fsRRqtHSkB4uUvvCcWtBlq2JQX2i6VM4r/DZU
+        daV6BLMcy09ZOSdr87Kh8ndH2Ddb0S21pGT0VdVUSeT26bFa22DYX79sh7Z5
+        zpJzxUn5tkMamStXjJxyReUv3Q50fheQ2rtAd71APSQMJsX5fU3efkFVI2DV
+        ntPnAD2/JMkYfDQDWgceoXngD7S8+QjSJoK/oe2hDfiKnrxNACL/PMDX9syG
+        oB0ddl1Sn3LoErxKOWLgV7Q9xn6GB/aKGirioqhROajTxM932MdR+zdw+DGO
+        CtuQHVWtg+SzY85OdH+RA5zjnMMRS8YHN3CKMyUf4/RumphLE8NxnHEjk8Q3
+        NAY564s25KwbpDqvzjM8bOhV+mlevbw3r0af4dXY3r16pd4ruk69vbr8tFzR
+        RelYVIe6xvBLA1TVgKv4lsaAuz/dOiTlTCcd36KOV9O7vYq6XkUpONdJ53oz
+        aS+deUak5v5HpLLP4J7/z9wz/OvXyULKiad/YB03HrhHLmALtx83f5VbGuPf
+        sQ74gmOYOJDcxMI63l7HTW+ODucIb9knUjzftQOYdtlmHbb25F84+BP8vgc1
+        2iVO68N39pOFG/C3u/ztLv+4yz/t8Md38B9cR35P5HGXPO6QM7pqbznVdMYh
+        b0nGVZ6jTRSTG7hdK84qSYtL0oJlvOdmqGCTGY6lR52khDjNBir1JR5yWHwO
+        2ofv7fFz/ECjSWvep3zdWYQvg7sZ3MvgA3xIU3yUwcf4ZBHMxBo+pY82Ex0m
+        PrN/URPdJjpNLjxgS46Z6Ddx3J6ftZ9pE6MmLpq4Yr+Om5gwMWMi+y/NlFaM
+        0g4AAA==
         """
     )
 
@@ -465,7 +465,7 @@
     private val KotlinImmutableCollectionExtensions = kotlinAndBytecodeStub(
         filename = "ImmutableCollectionExtensions.kt",
         filepath = "stubs",
-        checksum = 0xf50711c2,
+        checksum = 0x366b10e3,
         """
             package stubs
 
@@ -491,400 +491,388 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAC2KMQrCQBBFRzQWUyhsZSdYiYFcQiwkZbzAJhlwYXcnZP5C
-        ju8WFv+9V3wi2hPRrq75m7jli8/zqmHeuknToibdWjJCEncesl/sqxjgIT34
-        zo2hjOau75QK/BjlqTHKhKD5tUGy1bD6PPEBYnDHT2WPGz3oB8hyC49/AAAA
+        H4sIAAAAAAAA/y2KuwrCQBBFR3yAUyhsZSdYSYT8hFhIyvgDm2TAhd2dkLkL
+        +Xy38MI5nOIS0ZaINpUj/ccPvvg8LRqmtR01zWrSLiUjJHHnPvvZvooeHtKB
+        77w3lMHc9Z1SgR+iPDVGGRE0v1ZIthpWnyfeQQzu8KnucKOGfhfuUbR/AAAA
         """,
         """
         stubs/CollectionObject.class:
-        H4sIAAAAAAAAAK1W21MTVxj/nQ1JlmWVEI0IXhoraiDFIFpvpFSkWINcVJCq
-        tLVLssLCZjfd3VDs1d7svX3zodOnPvtQp61inWmpfesf1el3dtdNhMVxHGfg
-        nLPfOd/v+323c/Lvf3/8CeAQfmDYYjvVGTs3aOq6WnQ00xifmadFHIxhbmRe
-        WVRyumLM5jxxnyepOppep5KvO1cwHHVWtfr6+0YWTEfXjNz8YjmnkdQyFD1X
-        VqwF1bJzZ0aVSkUtjbqffQyJ1ZbiaGDYHGYtjhhD5xODxyEyxPKaoTn9DJFM
-        55QMCU0SopAZ0j5OMYCvj4V9hnhsZGhUyxXn2ohmOwzJTGddELisT0YCLRKa
-        kWSQOzpKqq7OKo56pYf8Wnt2M1KNELCFocGZ02yGrSPhOaCwiEXTcBTNoFMN
-        mULnZYaWNaGOYztDfFHRq+r4VUoonQvJh4ydeE7CDqQZNj7KKY7nGVKZtcnu
-        vCyjHR1N2I09ZILcKqsGhYAVGJoeMhvQdYa2TGhh9HHG+8P38tm1Bvtdhd0j
-        pjWbm1edGYsbyCmGYTqKl5sx0xmr6joPjU/HFtHNsDOsHsh3iwC0oh1Hjlws
-        zqnFBR/hrGIpZZUOMuwLcb1OMsFBZvt43RxAr4QeHJTRiS4elhcp3uGeU7w0
-        e4iXjVt0FMmjOMZVjhN1jewqjmnxbNVXU8GXk3Y2dCO802Tk8RLHfpmszqrO
-        hPau6lqlPDXY9CFjECf5gVdIrJRK5HMN54JhVysV03LU0niFmyH6Q0tFteI1
-        26sMBwN5WrPTlIx0oJG+alppS1VK3aahX0vX2khEYVVR1cVRwhkJpzFCjUls
-        3ArKPUGV1DzmZRIt6qpCIYxZatlcJIeTa9NIrevtujZEb12gLtlVb+5q1XCN
-        5c5aakkrUuu6Bo48/ky+e11qQoVaf+fjLbjUeAe51Oruv7FqeYZ39WVeKIYz
-        xRtbxus4KWEab/CO3CbR/XFFxgCXCVBknPJkRcq/Yw5YlkJVl8lMh7R0iIxu
-        wfzk8ZBuzExPTpIGDRRthaOKmGPYE9ZrtZRNegTimGfoX+deeEJmMlToEhZQ
-        ZtgUyjyVCfcou96FtI6Vt7kVKiYxX9Tdp4KHk94HsTA2MTkwNjgkYxFt/N5+
-        hwKw6lIP70q6qx8+gaOU6JLiKCQTyosRensZH6J0lS6QaEnjX1QyQukAw08r
-        17dLwlZBEhI76V+UBDFKc5M/Z8R/bghbV673ismGpNAj9LCTcVF48HNMSESG
-        WxLxdqFH7I0lGmkWTj+4GRluTUiuTE40tQc6tMOGGxMy33HXzYkNwe5Grnc+
-        mWjgGBcf3IwSeqy9QYwmYpxjLyP+SBfK5aqjzOhqLbxDS45K9y1d1PsX6J3Y
-        dr5qOFpZLRiLmq3RyYHaTU7lP6HNGopTtah1GwbNEk3NI5qhevU/yZF5T5tF
-        RZ9SLI1/+8KO1bjBZf6IgQ0TjlJcoN8Cvpo0YVatonpK4x9tPsbUGmZ0ywv0
-        40BAHDzfbTzx5O8NSlGM5heARJI/4rT+gmQCrmETjfSbgiRfkiRPXwLNG7vu
-        YkNXJL+MTb+j9bZ79isaJXc3RXMKX9NKJj06ja1kh0eWGtxHOhwg/YbWbcvY
-        dQ97BdxyT3HNLd6ur8lX+5ChPcbfJ0RcjGM+Rks2uX8ZhzhS9h4Or4VpCWBa
-        0I0jgXtZfENznHm+00gPmc/Ps0UecdR7oPKugXpeSYFX9ET5jFZpnWD4ZR0t
-        j0B/fexppGsv3P7Q4+yfCqLaSzy4w9J9nL6UHL6L0b9WhUIKQiEFER2jiApP
-        oV8fynFanQ3qJEM4bB2c1ezPoeMp2Z932U88A/ZZWk3iwlPhvIaLAc4UrS49
-        Ez7n+M9TPy7n/TpPZf/Gjh8Rjdzqyq5g+g7evIO3eFlE8K07ska3C2NuhFN1
-        dlKBnZQft3P8d5OPn/NrLdp1BzO3gmauh/GSFvVgEgNUcg/JnfDJyTVOpXAM
-        j4ocUJGDFKq46ofsiI/WnE1qvKVXEM8uw6h1kQfSHIA0Yw5mELdZF6ziU9vr
-        +yVymGXYq3tR9FFEOEHltrr4QNN9CJfuovorlm67gohvIoLv3PlzfE8zT/27
-        FJf3phEp4P0CPqARH/LhowKu4+NpMBuf4NNpNNtos/GZ+9dkY9DGgI2TNtpd
-        yT4bnTa6bRy1kSfJ/3e4UsLJDgAA
+        H4sIAAAAAAAA/61WW1cTVxT+zoQkwxAhRLlbGitqIEoQrVZBWqRYg1wUkKrU
+        2iEZwsBkJp2ZULQ3e7P3PvrQ1ac++6CrrWJdq6X2rT+qq/tMxiEmg8tlXSs5
+        58yes7+9z7cvZ/759/c/ABzGDwzNll1csFIjhqYpGVs19KmFZVqEwRiWxpfl
+        VTmlyXouVRIPlCRFW9XKVAbL9qV1W8kp5sDQwPiKYWuqnlpezadUkpq6rKXy
+        srmimFbqzIRcKCjZCedxgCFaaSmMGoYdftbCCDF0PzV4GCJDaFDVVXuIIZDo
+        notAQp2EICIMcRcn48GXc2GdIT/qGWqVfMG+Oq5aNkMs0V1GApcNRBBFo4QG
+        xBgiXV1ZRVNysq1c6aNzVe/dgaZaCGhmqLGXVIuhddw/BkRLOKfYM+o1xXE8
+        zVD/OFoYOwnFog0RdKKjDi/gRQYxY+i2rOoEXZNId19iaKyKTxi7CX1V1orK
+        1CJlAe3zCWIEe7BXQhf2MTQlqrOh+1IEu9DN7fYQHJ07r+jEESNX6x55Maxp
+        DG0J38wZ4N71+r8bTFYbHHIUdo8bZi61rNgLJjeQknXdsOVS8CYNe7KoacSd
+        6Lpjiehn6PRLGDqnSQBqxgrjMB0xs6RkVlyEs7Ip5xXayLDP5+hlkhkOkhvg
+        iXUERyW8jFci6EWK03KcuPU/OfGlWqM8r5zgEpMnMMRVXiXXVbIr24bJI1Oe
+        bmlXTtpJ3xf+pRjBME5y7NfJlpzN0pE2t53XrWKhYJi2kp0qcBTybnQtoxRK
+        xfYGwyFPHletOHEd9zTii4YZNxU5e8DQtavxzTISka7ImTKaJJyRcBrjVJjk
+        jZMgqadIgs0D8SwIZjRFJoZCppI3VqlEYtVRotItvXVsiKV1mhJ+V7m5xaLu
+        GEudNZWsmqHSdQwcffKewQNbuiYUqPQ7n2zBcY0XCLkWQTs6JGoKlx7rhJPF
+        /AIv1bd4Ruj2HK/WCN7mWy/jCi+9l7iSTKlkG8OmKVMqJRLzPnXqI6PeNzh7
+        3KfEEvOzs6RBA3Esc1QRxNgevwLaDNRsyYEwlhiGtij2p/QsggyWJahYYdju
+        63lTwv9Eya26zBZWDG6lQOwOZjTnguB00q0gpidnZocnR0YjsNHGu3WRCKho
+        5f6lRs320cU3QeHNyrZMMiG/GqAbl/Ghlg+gJknHE9ZU/kTZImQPMvy0cX2n
+        JLQKkhDtpL8oCWKQ5jp3Toh/3xBaN673i7GamNAn9LGTYVF4+HNIiAbGGqPh
+        dqFP7A9Fa2kWTj+8GRhriUqOLBKta/d06A0bq41G+Btn3RDd5r2t53rTsWgN
+        x7jw8GaQ0EPtNWIwGuI+UiMlz+PpfL5oywuassnx6JqtUCelFty7QjdAx3RR
+        t9W8ktZXVUulncObPZoyf0bN6bJdNKlqa0aMLE0N46qulBJ+liPzcjYysjYn
+        myp/doVdlbhem37MwLYZW86s0GeAqybNGEUzo5xS+UObizFX5RkOUqiD9A+D
+        B72NR5/O+wWFKETzQSAa4/c3rW+QTMB72E4jfU6Q5EuSHKcnogiRnnvY1rOO
+        7b+h5Y6z8ysaeXaBtEX6f813lfailaxwXqkJuDgJnh9co+dXtNxHnOGWs2NT
+        S/K0qAu4WkcIn1uo51od60jcR1Io02wuvXU1+Wo/DjiW6LZCwME45mI0JmOH
+        1nGMIyXvY6AaptGDaUQ/Bj1K+vANzWFW4otGutb8T/Xak05FF5brUYXWKMPt
+        LbRKDoyUx4vGUx4//YTIXZce4PTF2Ng9TPxZcSjJO5TkcTNJ3AjPoF9OyhSt
+        znpZkiActgVOJQ/n0P2M3k873s88B+/7aDWL88+E8yYueDhztLr4XPw5xz93
+        XV5Sbn4Ee+5i/pZXbCFHWF5oQRfuHP9mdZWn3XRvSv6Frh8RDNzqSW7g8l28
+        cxcLHCyAb52R1VahNrvl/MjJphLp0WFKuf8XtAyyLklHXf8akrEcL8cNhJPr
+        0G5XgDR4IA1YRN5jSnHAdNeZvS5TIodZx7uVdSS6KCJML1dbHHyg7gGEi/dg
+        /YLVO44g4JoI4Dtn/hzf08yDvUZMX51HII1rabyfxgf4kJb4KI2PcX0ezMIn
+        +HQeDRbaLHzm/OosdFpot9BhYZcj2W+h10K/hRMWhknyH/VQQCa0DgAA
         """,
         """
         stubs/CollectionSubclass.class:
-        H4sIAAAAAAAAAK1WW1MURxT+evbKMMqyCgIqWSPqwgYX0XhjQwSCcZGLAhKV
-        JGbYHZaB2ZnNzCxBczOJuf4AH/KYZx+SqkQxqUqIj/lRqZyeGWfXZbAsK1XQ
-        3XO6z3e+c+vef/79/U8Ap/ADQ4dlV5es7JihaUrBVg19rrpU0GTLioExrEyu
-        yutyVpP1UnZmaZVODLmSqq1qdUq5unN53VZKijk0PDS5ZtiaqmdX18tZlaSm
-        LmvZsmyuKaaVvTwlVypKccr5HGJINFqKIcywN8haDFGG3hcGjyHOEM2pumoP
-        M4TSvQsSRDSLiEBiSHk4BR++PhrWZeKxm6FJKVfs25OqZTMk0711QeCyIQkJ
-        tIpoQZJB6ukpKppSkm3l1gD5tf3sXrQ1QUA7Q9heUS2GrsmdskCBiRcM3ZZV
-        nc6F0/nemwyt24IdwwGG2LqsVZWZZYZ2OheQEQndeEXEQaQYdj/LKoZXGdrS
-        29Pde1NCF3qacRhHyAQ5VlZ0CgLLMzQ/ZTaiaQyd6cDSGOKMjwfv5TLbDQ47
-        CocnDbOUXVXsJZMbyMq6btiym51pw56uahoPjUfHiqOfoTuoIsh3kwDUAhV0
-        llwsrCiFNQ/himzKZYUOMhwLcL1OMsdBSkO8ck5gUMQATkroRR8Py+sU72DP
-        KV6qNc4Lxyk7iuRZnOMq54m6SnZl2zB5turrKe/JSTsTuBHcaxJyeINjv0lW
-        S4o9p95RHKuUp7BFHxLGMMoPvEViuVgkn2s413SrWqkYpq0UZyrcDNEf3ygo
-        Fbfd3mY46ctTqpWiZKR8jdSyYaZMRS72G7p2O1VrpDjyDUVVF0cRl0VcwiS1
-        JrFxKij7AlVS85iXSaSgKTKFMGoqZWOdHE5uTyM1r7vr2Ii76zx1yaF6c8tV
-        3TGWvWIqRbVAzesYOPP8M7n+HakJFWr+7udbcKjxDnKo1d2A09XyEu/qm7xQ
-        dHuBN7aEdzEqYhHv8Y7cL9INckvCCJcJkCVcdGUFyr9tjJimTFWXTi8GtHSA
-        jO7B3Pz5gG5ML87PkwYNFG2Zo8axwnAkqNdqKZt3CcSwyjC8w73wgswkKNBE
-        rKHMsCeQeVs62KPMThfSDlY+5FaomI403NjBDUfX8NP3bYpyWJRtmWRCeT1E
-        TyvjQ4RuyTUSbaj8i6pBKJ5guL9194AodAiikOim/7goxCM0N3tzumPr7mA8
-        GU4KA8IAG408+SkqJEITrYlYlzAQH4wmmmgWLj25H5rYlxAdmZRo7vI1aIdN
-        NCUkvuOsWxK7/N3dXG82mQhzjOtP7nP0aFc4HklEObtBRsyRypfLVVte0pRa
-        zMY3bIUuUbp9j6/R5d80p5Z02a6a1HHhMaNIU8ukqitu2c5zXd6KRkHWFmRT
-        5d+esGe2qttqWcnr66qlksi/g0dqNzzD/sZjz+zumrPlwho98R6oOGdUzYJy
-        UeUfnZ7qwjZFuroFevMFxNAElkjyd5j8/YKSI8BGktb0s4DGL0mSI5lA8+6+
-        R9jVF8ptYs9v2PeLc/YrGkVnt53mdtyjlUR6dBod6OT55x3qIZ32kX7Fvv2b
-        OPQYRwU8cE7dczCEOk2+OoY07TH+wCDkYJzzMFozyeObOMWRMo9xejtMqw/T
-        in6c8d3L4GuaYxz1NUeFXiKPn2uLPOKoj0FFXAN1vRJ9r+iN8Rg1aF1g+HkH
-        LZfAML6hOerbp3sr2P748+xf9KM6SDy4w+IfuHQjOfEIU381hEL0QyH6EZ2m
-        iAovoV8fyhlaXfHrJE04bAecRvZX0fOS7Gcd9nP/A/sMreZx7aVw3sF1H2eB
-        Vjf+Fz5X+e9LLy6zXp23Zf7GwR8RCT3oy2xh8SHef4gPeFmE8K0zsianC6NO
-        hNvr7LT5dtq8uF3lP3w8/KxXa5G+h1h64DdzPYybtIgLkxihkntK7oJHTqpx
-        KgZjuFQkn4rkp1DBsheyMx5aSyap8pbeQiyzCb3WRS5Iiw/SghUYftxKDljF
-        o3bU8yvOYTZhNfZi3EMJedohfOfMd/E9zTyrVXJ5fRGhPD7KY4NG3ObDnTw+
-        xieLYBY+xWeLaLHQaeFz56/ZwpiFEQujFrocyTELvRb6LZy1kCPJf/behL1p
-        DgAA
+        H4sIAAAAAAAA/61WW3PTVhD+jhzbsiISx5CQC01NCeDEEIdAoeA0baChOOQC
+        SUiBlFLFVhwlsuRKchrojd7bP8BDH/vMA51pIbQzbcpjf1Sne2ShGFthGMqM
+        rXO0Z/fbb/fsnqN//v39TwAn8CNDp+1UluzMOVPX1byjmcZcZSmvK7YdBWNY
+        mVxV1pWMrhjFzMzSKmlkq5KKo+k1RiM1ejnDUYuqlR3NTq6Zjq4ZmdX1UkYj
+        qWUoeqakWGuqZWcuTinlslqYcl+zDPF6T1E0MewJ8hZFhKH/ucGjEBkiI5qh
+        OaMMoVT/ggwJzRLCkBmSHk7eh6/Nhn2ReLQwxNRS2bk1qdkOQyLVX5MELsvK
+        iKNNQisSDHJfX0HV1aLiqDeHKK5G3T1oj0FAB0OTs6LZDN2TO+0CJSZaVJ05
+        7bbqUs8xtDyNF8U+wrFJQUYveprxCl5lEPOm4SiaQeBNqVz/dYa2hh2K4gCh
+        ryt6RZ1ZZuggvYBtlHEQhyT04TBDe6qxHvqvy9iPfu53gOAo8pJqUJYYUW1+
+        wmJM1xm6UoG1k+XsBoPXRtKNDkddgwOTplXMrKrOksUdZBTDMB2lun3TpjNd
+        0XXKnejRsUUMM/QGlQzFaRGAlqeKP0Eh5lfU/JqHcEmxlJJKigyHA0Kvkcxx
+        kGKWl9ZJnJLwOt6QMYgMT8sZym1w5JQvzR7nleVuLmXyTYxyk7eIukZ+Fce0
+        +M7UFlzOk5N1OnAhuBlljOEsx36HfCmFAoW0rXbFsCvlsmk5amGmzFGI3fhG
+        Xi1X2+1dhuO+PKnZScp10rdILptW0lKVwlHT0G8ltxtJRK6uZmrSJOGihAuY
+        pNYkNm6BZJ6jCLYD4lUQzuuqQhmKWGrJXKcWSTTuEjVvddX1IVbnOSr4/bXu
+        liuG6yxzyVILWp6a13Vw6tk6I0d3pCaUqfl7n+3BpcYbhKjJ6EaPRMfC9afO
+        wulKaYm36vu8IgxngXerjA+46g3c5K33GjdSqJQcc8yyFCqlVGoxoE8DZHT6
+        jcyfCWix1OL8PFnQg3KscFQRlLGDQQ20vVHzVQJRrDCM7tDsz8lMRh6rEjSs
+        MewOZN6eCo4ovdMps4MXk3spU2x153RwF9E5+uRWm6KdKyiOQjKhtB6iC5Xx
+        R4w/QOcfMRc2NP5GhSAUjjHc3bqzTxI6BUmI99JflAQxTGOzN6Y6t+4Mi4mm
+        hDAkDLGz4cc/R4R4aKItHu0WhsThSDxGo3Dh8d3QxN645MrkeHO3b0ErbCIW
+        l/mKO2+N7/JXW7jdbCLexDGuPr7L0SPdTWI4HuHs6HQkzslcqVRxlCVd3U7c
+        +Iaj0vFI5+rgGh3rsTmtaChOxaJmazpnFmhondQMtVqn89yWd6GZV/QFxdL4
+        uyfsm60YjlZSc8a6Zmsk8k/Xse2zm6GnXu2p1V1zjpJfo9vdA5XmzIqVV89r
+        /KXLM11oMMQx6pEw/aOIgcUT/AqmeO/Q5giwkKA5fRHQ80uSnCEZpQPywEPs
+        GtjE7t+w9xdX8yt68m4DOiDS/2uuVdVFJ7rcfacu9nBSvAq4xcCv2PsISYZ7
+        rsa2leRbURt7VicJn3to4VY9m0g9QlqoseyornqWfHYER11PdN0g5GKc9jDa
+        0onjmzjNkdKPkG2EafNh2jCMET8lQ/iGxihHPeaa0L0UHNXbz4qKbhyPUZ3V
+        OMP9HayqBM7hWxojvv/zfn6GCZFTl/7AhWuJiYeY+qsuKMkPSvJzM025EV7A
+        vjYpMzS75FdJinDYDjj1ebiM/hdkP+uyn3sJ7IdoNo8rL4TzHq76OAs0u/ZS
+        +Fzm36teXjJefYQHHmDxnt9sEVdY22hhD+4y/+j0jGe9cm9P/42+nxAO3RtI
+        b+HGA3z4AEscLITv3CeLNaBWSbb7JNurSY+PUcn9v03Lo+Al6ZTHrzWdKPJ2
+        3EI0vQn9fh1Iqw/SimWU/EypLpjhkTnkZUrkMJv4qL6PRA8l5FmH8L07foEf
+        aOT7aFMSnUWEcqjksJ7Dx9igKW7lcBufLILZ+BSfLaLVRpeNz91fs41eG902
+        emzsdyVHbAzaGLbxpo0xkvwHiMP5IlQOAAA=
         """,
         """
         stubs/ImmutableCollectionExtensionsKt.class:
-        H4sIAAAAAAAAAJ2V3VLbRhiG37X8IyvCFrZJYkMS4wCBJCAgadIUSprSJHVj
-        SCZ0Mp3hSAaNR2DLjHfNJGdcS6+gLSedHnSYHvYWei+dfrsoklHsTpIBaXe/
-        n/d79kfrv//9408A9/GKYZaLfpPb9U6nL5xm293sttvunvC6/tO3wvU5dfgL
-        kQFjsA6cY8duO37Lftk8oKAMNIZk2+OCoTC/0FD+vvDadoNsawy3PjCuNyKR
-        ui/clttb26DIm41ur2UfuKLZczyf247vd4UjMbi93RXb/XaboqqHXdH2fHsv
-        hOR2BKw4swxZt3Mk3slqJi4hbcCAyZBpuaKhUJPnjRXnNZGHlUUC4wwadylk
-        /AL/jivnNBe3jZpSeQgshSvKywy6oiSDiasoGbiCMkOaIHdkZU2987HqJqZw
-        TRJep4iOcxQn3HKOqPCjuG0Y4SdAk4KCvvkemgwmZjFtYAZz59BbEkZT73wM
-        yMQCbkvoOwxGpMtw9QJntI+EsTjCNWqtS8OCM1hmGCO4zYGixuDg8vD6Ju7h
-        viT+gma8vkfr4YkNmt78whv6YD7yRM983Cl5+NlbdeeTVmi8EezsliucfUc4
-        ZEt0jjW6B5h8pRjYoewkyP7Wkz1avcT+CsM/ZydzxtmJkbCu06MbCV2jthq0
-        M0FbozZdMa3xil5IFhLLiWVGo0I4SlcKVrGSOx8FNoMiSmFErnbFOjuJ0v/6
-        Oa1T3UpS16wk+VKRVuTKWHrtmpWNC0cBlyyTcseiKpErb1lyiquM1gDV/70C
-        lw7pc8zueC3fEf2eyzD5uu8Lr+PW/WOPe5T1JLqx6IrZ7O678lPwfHe732m6
-        vR+lMh2/nW6/t+c+8+SgHGi8+UABK3T6krQHSVTkrUSjH+Te4BFeUJsmXp3a
-        irwPQt9XMR99dqFvLeajAx761i/4sigjRSMNDRrVyMqkV1v7HWO/yNOCLXob
-        lCfpUvScq2QuqJSRCzWmlAJF/4ZCpJBW1tSI7CJKwwgqcYIsKWQDjYmYxmSo
-        MUBwI05gjMiuYnoYwa04QY4IcoFGLaYxH2oMENyNE+RHZC9iKcieDQiyahfO
-        sBKHKFJKMZCxYzKrocwAxIM4RGloto6H+JL6MvunAGJGQZyioDbkFDfUspzi
-        7nu4Uzz4NVSvKZ2U+tOJdowei6Y8QQ/97tEyl6jqtqpdx0tqDyjza4re2IVW
-        x+M6vqE3ntTxLTbr+A5Pd8E4nuH5LiY47nF8r/5XOZY48qqf40hzLKj+PMc0
-        x5TqT3KUOBY5UhxVjuJ/gOL8xQkJAAA=
+        H4sIAAAAAAAA/51VW1PbRhg9a/kiK8IWtnOxIYkxhEATEJA0aQolTWmSqjGk
+        LZ288CSDxiOQZca7ZtI3fkt/QVteOn3oMH3sX+h/6fRbWZGMsDtJbGt3v9s5
+        Zy9a//3vH38CeIjvGe5w0W9x0+p0+sJuec5W1/OcfeF2/edvheNzGvBXIgfG
+        YBzaJ7bp2X7bfN06pKQcFIa053LBUFpYbAbxvnA9s0m+dYa7l5wbzRjE8oXT
+        dnrrm5Q52+z22uahI1o92/W5aft+V9hSBjd3umKn73mUVT/qCs/1zf1IJDdj
+        wYHOPEPe6RyLnySbjivIatCgM+TajmgGUtODzkjq1VGEkUcKkwwKdyhl8oL+
+        XUfOaT7pGzel6gixlB6ovMagBirJoeMGKhquo8qQJZG7klkJ2mKCXcc0bkqF
+        tyijYx8nFW7bx0T8JOkbpfADRBNCIHr2nWhy6LiDGQ1zmB+I3pZilKAtJgTp
+        WMQnUvQ9Bi3GZbhxQWe8jyRjaUxo3FpXRiXnsMIwQeK2hki1YePaaH4dD/BQ
+        Kv6UZryxT+vhik2a3sLiG3ph3vNEz73fKXn80Vt174NWaLIZ7uy2I+wDW9jk
+        S3VOFLoHmGzysgEDO5KDFAXfunJES5g6WGX45/x0Xjs/1VLGLXpULaUq1NfD
+        fi7sG9Rna7oxWVNL6VJqJbXCyCpFVrZWMsq1wsAKfRplVKKMQuO6cX4al//1
+        c1Yl3lpaVYw0xTIxVhzKGWrjppFPAscJVwydaidiljhUNAw5xTUmZ1//33tw
+        +Yjeyfyu2/Zt0e85DFM/9H3hdhzLP3G5S1XP4muL7pmt7oEj3wfXd3b6nZbT
+        +1Ei0xnc7fZ7+84LVxrVEOPNJQSs0hFM0x6kUZNXE1mv5N7gCZrUZ0mvSn1N
+        XgpR7PNEjN69KLaeiNEpj2IbF2J5VJEhS8E2WXXyyk/6d0z8EpySHWo1qpLa
+        FHoGGLkLGFUUIoTpdwi/oRQjZANvZkx1GZXL/LUkf55y8iHC1QTCVIQwxH87
+        ya+Nqa5j5jL/3SR/gXIKIUIjgbAQIQzx30/yF8dUL2E5rJ4Nq3O0/udYTUoo
+        U1E5BDETIGsRyJCER0kJlZHVKh7jMxrL6u/C6mmScIYSbcQZbtNynOH+QNQZ
+        Hv0aoTaC+gwxy0Ok0QbRXzBNVH5LxEZ/eMT2OuD8lrCBQ6r8grI396BYeGrh
+        SwvP8JWFLXxt4Tle7IFxvMQ3e7jK8YDDCn5rHMscxWBc4MhyLAbjBY4Zjulg
+        PMVR4VjiyHDUOcr/AfU3caL+CAAA
         """,
         """
         stubs/ListObject.class:
-        H4sIAAAAAAAAAK1Y+18U1xX/3ln24TDIggICUbdG48JGFzXVBiiVGNMMIiaC
-        NEo0HXZHHJmd3c7MUkwfsa/0/W5smr7Td2tbbRKF2CbG/tY/qp+ee2d2dtmd
-        VcrHD3LvnXPv+Z7nPffIf/777nsAnsAHDEnHLc872UnDcU/NX9ZzbhyMYX7y
-        srakZU3NWsh65BGPUnYNUxwerTmhWq6+oNsjYyOTi0XXNKzs5aVC1iCqbWlm
-        tqDZi7rtZE+c1EolPX9SfI6Q6HoZcbQwbF4rJ44Yw8C6YeNIMMRGDctwxxgi
-        6YFZBTJaZUShMKR8nFzRNEmeUbSc7LHq+gRJ28ywSS+U3CtcOENneqDO8BEF
-        SXTIaEcng7J7d1439QXN1V8aIosaz25F1yZI6GZocS8ZDiFO1nucXJHIFS1X
-        Myzab0mrA+cYOhrcG8cjDPElzSzrpy4ydNO5kBgo2IGdMrYjxdCVbgzjwDkF
-        fdjVijgeJThSvqBbZChTGVorWoybJkNvusaaqpdGuHb7w/dGM40CxwTDo5NF
-        eyF7WXfnbS4gq1lW0dW8CEwV3amyaXI3+Oo4CWQYdoRFney0CcDIOXHsIxNz
-        l/Tcoo/wnGZrBZ0OMuwNMb2GMs1BFkZ4dmQxJGM/DijYizR3yyHybbjllFAL
-        usv9usb1PryCwzjCAT7CEDWsvL5M/hUzDxcPq9okJKqCEXyUs45xFuc4zz+R
-        vRSsoxjnO0+RdwwyTXOLNg9+bVqqPp0UzIRuhF9WBU/jOMf+OIXe1BxX9ZRV
-        oHraTFCCm5SmaiC3r+E61MjONt1sJn8SJ7mcUwz9gUvDkIea7zaHfp5DT5ND
-        nfK8d5m3ptUGHEIfCCE3gz2DWQ77AlWJi3axoPphdouVFSXItPGyLqJH8W5x
-        6EPBBZznbC8RWcvnKT2r6Gcsp1wqFW1Xz58qcZso044v5/QSX8Qxz3AooKcM
-        J0X3JhVwpC4W7ZSta/l9Rcu8kqrWtQTydclWk/IyLsrIYYHylJs+SxWTtBKX
-        vi+tNr/1Q00211z7qrc4S3YdhWItRzRn6hqlWszWC8UlnRfMhhtD3vd2hc6y
-        rZdMLed97KkVeLFsCXHkZM2+4rmREopbPPzgc+E5wJmlEhX7XQ8WJPTkFVWo
-        FnF48eipZtsaZJ4rFNOGulsoaVWts+F7o/uaqtodDrbm9Z0qF+b5+/J5XmMs
-        d5Y/MQqu4ryMV/AF/l70y/SGfYlXuJ189RVesEb56qu8WIjV1xW8yDkkfFOB
-        5nF8WzxTIRVvlh8x+JHv8VoddiSswC7jCuf5obhx47atUZVMp+dCuENo9PyP
-        zgyHPFDpuZkZ4qCBsk/jqAm8TtUiLHHjeINyLOxhqp6Z8VSL42cMY00e0XXq
-        rOA1/ELGz/FLhi2hNnWlw23NNHu9m0j5DZfyW0qA0ZwpuifuaGqZEurU9Mz4
-        1LHjCv6IXt7K/IkcsK5qSU1MpR88Sbcgr7ka0aTCUoSaT8aHKPUdi0RaNvgX
-        3Skpf4Cxo3evDsnSNkmWkin6TchSIkpzK80RmnfQHKM5TTM/M8jpiX+/Km27
-        e/VgorOlUxqShthT8YR0782YlIxMdCTjfdJQ4mAsuYlm6dl71yITPUlZ0JRk
-        a1+FR6EdNtGdbOOn6PTmymmB0044SX+ngsMmNiU7OI5Ytyc7A6wtQkpHcmsD
-        R3uyKzjVLSg9tZQauWxiZ7In2GG0s81H662cON2ZbOHrF+5di5KWsb6WRDQZ
-        4348yMjHSKmFQtnV5k29mgLHl12dGijqvPYvUrnpP122XKOgq9aS4Rh0crza
-        mlH9mjYWLM0t21SIW44V8zS1TxqW7pWMGY7MK3Qxp5mzmm3wb5+4ux436M7W
-        CGibdrXcIrXwPps8XSzbOf0Zg3/0+hizDZrhAGVilH7j4DnZy5OT7F2hNIrR
-        PAgkO3nvTetVokn4C3bTSP8VIMq7RBmlL4nmzYO30TYYGV3BlnfQc1OcvUOj
-        LHZjNMfwT1opxEensY3kcM9STfSRDgdIb6OnfwUfWsVuCdfFKc7Z7e36nHy1
-        B4/RHuMNJyIC40kfoyPT+fgKDnKkzCqeaITpCGA6kMGHA/MG8C+a48yznUaq
-        1ERu1G8VT0q4i+037qPfsNCvxpc0Ur1vbu/H1mcvtbI+Rlp8k5c5xiqOsRp+
-        z9Ny4GlqUn0v1XE9y3CjCZfnlGfqbFDvZ8OJ9dlALWu4Ns89SJupOm2oQ/WR
-        DvnatPoRmpFQH57WQJVWPzwe6Ok6UOpPfdAxmnlVVQToI6s4G6lBTXl7AaqC
-        cwKVr+ZoJfn4n6jDpyc+PISfvF8IteCyHCS53B75DnJnO/XbuPR+naVyoJMc
-        OJ16heDaelaF8Xs21fIP+zZ5SBKtL2PRvxYbReK3ruIdUyCmfcT/z7ba21ug
-        lRWUJl4UWBOces8WsWuDni0Jz37qIWg/IPQY3ZAewq/JceI/snF++rHhbMiO
-        MpYCO1xaffoh+YM61YeUsS/jMxu07HOBRp+lUtMXZMppv9x0ZT7A9jcQjVwf
-        zNzFK7fwxVv4Mr/EEbwnRrZJPIUxoVGsRk5XIKfLyySK4OEggsM+fmyw/xZe
-        vYHKk9qIEwtwYr7lz/O/hDTRU6rR82sb05Pw1XXhf2PD+BeCCpn1K2R08Ba+
-        dT3UDd51jnow5EQtCNJRXzmlqtN3wjE8VWpLeSUkGr7ro53wk7BtsP/xCtz3
-        b4bCeTnZFsC1BTnZJoAlAl7GD+4D/KPwkD8QmNav4Zqf7Ed8+9sznT/hHdFd
-        /DSzgl/Vv4vtAVw7Xsevg4z/sQB709fyMT8SCQ6zgt/VP9QJHyWB3wdVuEfg
-        03t7B9LZ2/jDW/jzTUGI+CIieF/Mt6mdgrju1ymSf51DRMXfVPydRtzgw00V
-        /8Bbc2AO3sY7c+hz0OvglvjX6uCCgxcdnHc4nSh7HOx1kBHrww6GHex0MOLg
-        qIOnBVF1MCkWZxycczD3Pw/jQRHOFwAA
+        H4sIAAAAAAAA/61Y+18U1xX/zizsLssqCwoIWN0aEheILmqaNC5FiSXNImIU
+        QqO2NcPugAOzs9uZWYrpI6aPJH2mTVvbpu/03dpWm0Qh9tNa+1v/qH56zp3L
+        7LI7q5T40b33zrn3fM/znns+/Oe/7/0DwGP4u4KE45bnnPSk4bin5xb1nBuB
+        omBuclFb1tKmZi2kPXLGo5RdwxSHR6pOZC1XX9DtzGhmcqnomoaVXlwupA2i
+        2pZmpguavaTbTvrkKa1U0vOnxGeGRNfKiKBJwfaNciIIKxjYNGwEUQXhEcMy
+        3FEFodTAbBwxtMbQjLiCpMTJFU2T5BlFy0mfqKxPkrTtClr0Qsm9zMIVdKQG
+        agzPxJFAewxt6FAQ7+/P66a+oLn6xWGyqP7sTnS2QEWXgib3kuEQ4mStx8kV
+        kQXdnTZe1IXKWTrr0Eccu9HXigg+oCCaK1quZlgE0JTKDpxX0F7n/wg+SEjL
+        mlnWT88r6KJzAUGK4yH0x7APDyvoTNXHeeB8HHuxn+WmCI6sK+gWeUIhtVrX
+        tRgzTQU9qSpzK27MsHYHg/dGhuoFjgqGhyaL9kJ6UXfnbBaQ1iyr6GpeiKaK
+        7lTZNMlPUamOEwW5e09QWpCdNgEYOSeCw2Ri7pKeW5IIz2q2VtDpoIL9AaZX
+        UaYZZCHD6fMYPhTDETwex6M4wG75MPk22HIKHwWS/brB9RI+jgxGGOAjCpoN
+        K6+vkH/FzOHisGYbhCQbx3E8xawnmMUZ5wQVuULBGsfTvPMx8o5Bpmlu0ebg
+        V+dtVtJJwaHAjeDbHEcWE4w9SaE3NcfNesrGMeVpc5pugEl5nPXl9tbdlyrZ
+        6YabjeSfwVmWM6Ogz3dpEPJw493G0LMM/Tw51CnPebd9Zypbh0PoAwHkRrDn
+        cYFhP0llZN4uFrIyzG5RrkJaPk/ZV2F+znLKpVLRdvX86RKrTIk0vpLTS7yI
+        YE7BEZ+eNJwkXYukz5GcL9pJW9fyB4qWeTlZqWtR5GtyqSqjY5iPIYcFSkO2
+        bJYqJmkl7nRvKtv4Ug832NxwqyvOYJb0JurARo7mnKlrlElhWy8Ul3UumHUX
+        gpzr7QqdY7ZeMrWc9/FwtcD5siXEkZM1+7LnRsoXtvjo/c8Fh5iZ1RJVn333
+        FyT05IIpVAs5XBu6K8m0AZmLPsW0rqwWSlpF63Tw3siBhqp2BYPF0Yu+GD1M
+        X9jwDk+VC3P8kFzhYmK5s/yWxPFFPvoyvsQPQ5KZvsKlrJ9Xr3JlGuPVV7kq
+        iNXXxdsTUMZmuewGbQRFmK7MmG1rVOZSqQsBPAE0euBHZo4GvDCpCzMzxEED
+        5ZfGqFG8Qdc9KDUj+B5lUdDLUjkz46kWwVUFow1ewU3qHMfr+GEMP8CPFOwI
+        tKkzFWzrUKPnt4GUn7KUn1FgR3Km6I84VtQURbNT0zNjUyfG43gLPdys/Ioc
+        sKlyR13Iesd3ivI8r7ka0dTCcojaS4WHFh5A3cMS0VcM/qKro+YPKcrxO1eG
+        Y+ouNaYmkvSLxtRoM82tNIdo3kNzmOYUzXxmkOnRf7+i7rpz5XC0o6lDHVaH
+        laciUfXuW2E1EZpoT0R61eHo4XCihWb1mbtXQxPdiZigxROtves8cdpRJroS
+        2/gUnd6+flrgtBFOQu6s4ygTLYl2xhHrtkSHj7VDSGlP7KzjaEt0+qe6BKW7
+        mlIlV5nYm+j2dxTa2SXRetZPnO1INPH6+btXm0nLcG9TtDkRZj9Sh0PeTWYL
+        hbKrzZl6JQ/GV1yd2iDqnw4uUVXpO1u2XKOgZ61lwzHo5FilwaIyNW0sWJpb
+        tqneNp0o5mlqmzQs3asHM4zMhbiY08xZzTb4WxL7a3H9HmuDgG3TrpZbok5d
+        ssWmi2U7pz9t8EePxJit0wyHKB2b6RcBJ2YPZyjZ+zalUZjmNJDo4Bab1u8Q
+        TcVv0E8jdfxEeZcoR+mLXIT44C1sG1zFjnfRfUOcvEkj3wBGitLvFp/yzmIX
+        SWG/Uo2UOCnOYeYYfAfda9ij4Jo4UeGK+VxUJCXX44TPErYzV98qHlnDgFrF
+        2eXtSk5eDWJISKJWEyGB8aTEaB/qOLSKJxhpaA1P1sO0+zDtGCbD111yEKs0
+        RxTPXzRmhI/q9VvDqIo72Hf9HvodE/pV+Z9GegAa2/vRzdlLTWywp5+5l6ep
+        PZVequE6peB6Ay7PKSdrbJi6lw3Pbs4GalaDtXnuftpM12hDvalEOiK1aZUR
+        OqeiNjytviqtMjwe6MdrQKkzlaCjNIfEpWDQ3Wv4VKgKNent+ahxXBSovHqB
+        VqrE/0QNvuan/WFCYM1it5E716HfwqV/1ugc89Fjvvs0GJJ/ROoXxO9pV81/
+        TGrnIfF1X8SSTPCtIg2LwuHZaQrEAxLx/7Ot+h4WaGX5hSlFOEoDnNo0L2L/
+        Fj1bEp799APQ/qDQY2xLegi/JsaIf2Tr/PTPhrMlO8pY9u1wafWZB+SPFVx+
+        QBn7Ij67Rcs+72v0OSobu/0HKy1LUPPgTbx0DesvXlgQq1+7Zgl3hv/qI5nP
+        yqrTOfQv7HsTzaFrg0N38PJNfPkmXmGwENbEqLTUoXpKdvpKdnppSOHP+OE/
+        KvHDg3038dr1QO265Nu8jhOWbjvDfwppoKdapefXtqYn4U9tCv8bW/aD9n6u
+        s+D/5vtOuxJUQlrBtx4EEq1fx7dlAj8hfdY21PFd7lfu4PtDq3iz9tVq8+Ha
+        8AZ+7GfxdwTYT6Raj8gsjjLMKn5e+4xGJUoUv/Ara7fAp9fwNtRzt/DLt/Hr
+        G4IQkiJCeE/Mf8NtmvkK/5Zuwe/odczi91n8IYs/4k+0xLUs/oy/XIDi4K+4
+        fgG9Dnoc3BD/Wx3sdpjS52CvoAw6eNTBsFhnHBxz0O/guINxB1lBnHJwRizO
+        O7jo4IX/Af1E8byHFwAA
         """,
         """
         stubs/ListSubclass.class:
-        H4sIAAAAAAAAAK1Y+XcT1xX+3shaPB5jWWAb2wFUliBbARmTQmO7Dg4hzRgD
-        CTZuggPpWBqbsaWROjNyTbqE7vve0DTd072lLbQJ2ElP6/Jj/6ie3vdmNJKl
-        Ebg+HGDe0333fne/7x3+89/3/gngSfyDIWE75Xk7M2XYznR5PpvXbDsKxjA/
-        taStaJm8Zi5mLswv6Vln1KWUHSMv2MdqOFTT0Rd1a3R8dGq56OQNM7O0UsgY
-        RLVMLZ8paNaybtmZs+e0UknPnRM/Rxni9TqiaGHYsVlPFBGGgS3DRhFjiIwZ
-        puGMM4RSA7MKZLTJCENhSHo42WI+T/qMomlnTlf3Z0nbDoZWvVByrnPlFKDU
-        QJ3jowri6JTRgQSDcvBgTs/ri5qjvzpEHjXy7kJXKyR0M7Q41wybYddUY8wp
-        GLFs0XQ0wySOlpQ6cJmhsyHAUTzGEF3R8mX9wgJDN/EFZEHBXuyTsQdJhq5U
-        YyIHLivow/42RHGA4Mj8gm6Sq0xlaKtYMZHPM/SmavypxmmUW3c0+Gws3ahw
-        XAgcmCpai5kl3Zm3uIKMZppFR3NzcL7onC/n8zwMnjl2DGmGvUF5Jz8tAjCy
-        VKpHyMXsNT277CG8oFlaQSdGhsMBrtdQpjnI4iivjwyGZBzFMQWHkeJhOU6x
-        DfacSmpRd3hcN4Xeg1dwAic5wIcYwoaZ01cpvmLl6eJpVZukRFUwig9z0XEu
-        Yp/hFSjql5J1ChP85BmKjkGuaU7R4smvLUzVo5OB6cCD4HZV8CzOcOyPUOqp
-        EB3VNVaB6lozSSWep0JVfb19DQ1RozvT9LCZ/imc43ouMPT7IQ1CHmp+2hz6
-        RQ49TQG1y/NuO+9KqQ04hD4QQG4GewmzHPYlmhMLVrGgeml2ipUdFci08Zou
-        skf5brHph4KruMLFXiWylstReVbRL5l2uVQqWo6eu1DiPlGlnVnN6iW+iWKe
-        4bhPTxp2kvom6UskF4pW0tK13JGimb+erE62GHJ1xVZT8jIWZGSxSHXKXZ+l
-        mUlWiabvS6nNu36oyeGmtq9Gi4tktjAoNkuEs3ldo1KLWHqhuEKBTDR2DEXf
-        PRU2y5ZeymtZ98ehWoULZVOooyBr1nU3jFRQ3OORh/MF1wAXlko07vc/XJGw
-        k09UYVrI5sOjp1ptm5B5rVBOG+ZuoaRVrc4En40daWpqdzDYpvv3fLkwz++X
-        z/AZYzqz/IpRcANXZLyOz/L7ol+mW+zzfMLt47sv8oE1xndf5sNC7L6q4BUu
-        IeHrCjRX4pvimgqYeLOcxeAs3+GzOoglaMCu4jqX+b7ouAnL0mhKplJzAdIB
-        NHoAjM2MBFxQqbmZGZKgD1WfxlFjeJOmRVDhRvEW1VjQxVTlmXFNi+InDONN
-        LtEt2qzgDfxMxk/xc4adgT51pYJ9TTe7vZto+RXX8mvybUuDkN4nlcfeOSrw
-        nOZoRJMKKyF6WzL+CdOTYplIqwb/Re0i5Y4xNrJxY0iWdkuyFE/Sv5gsxcK0
-        ttEaonUvrRFaU7RynkFO371xYziWaElIQ9IQeyZ8/+2IFA9NdsajfdJQbDgS
-        b6VVev7+zdBkT1wWNCXe1leRUOiETXbH2zkXce+ocAucDsKJeycVHDbZGu/k
-        OGLfEU/4WDuFls74rgaJjniXz9UtKD21lBq9bHJfvMc/YXSy20PrrXBcTMRb
-        +P6l+ze5t5G+llg4HuERHGYUXSTVQqHsaPN5vZrXM6uOTq8iek4dXaYZ0jpt
-        LJqaU7ZofracLuZo6ZgyTN3t9BkuywdrMavlZzXL4L894sGLZdMxCrpqrhi2
-        QST/UTVRfbLRfV3Ptum0fdrRssv0MvdA5eli2crqzxn8R68nOtsgiGPU3GH6
-        F0UrWDzBn8/k79+pgCT8FgdoT695+r5DlDGiSbTuGLyH9sHQ2Bp2voueO4L3
-        XfrK4jRKaxR3aaeQHHFjN3p5jfKh5iGd8JHeQU//Gj6wjoMSbgkuLtntnnqS
-        fHcIj9MZ4y9GhATGUx5GZzrxxBqGOVJ6HU82wnT6MJ1I44O+ewO4x83lqINC
-        hEYtkRvtW8dTEjaw5/YD7BsR9q3RPuLj0cBu7u/TW/OX3qIeRkr8pihzjHWc
-        ZjXybqRlP9L0yvSiVCf1PMPtJlJuUJ6r80F9kA9nt+YDvTmDrXnhYdacr7OG
-        npge0nHPmjYvQzMS6tPT5pvS5qXHBb1YB0oPTA90nFY+OxUB+tg6Xg7VoCbd
-        Mx9VwWWByndztJM8/I/W4dMdHZzCjz0ohZrfLMOkl/sjv4/sywn9Hq79q85T
-        2bdJ9oNOl73ftq5XQfKuT7XyI55PLpJE+yUse22xXSTedZXo5AViykP8/3yr
-        7d4C7Ux/NPGhwJrg1Ee2iP3bjGxJRPbjj8D6AWHH2LbsEHGNT5D8ye3L0x8L
-        9rb8KGPF98Oh3SceUTzoqfmIKvY1fHKbnn3at+hTNGr6/Eq56I2brvS/sect
-        hEO3BtMbeP0uPncXX+BNHMK6+LJWcRVGhEXRGj1dvp4ut5Iogyf8DI54+JHB
-        /rv40m1UrtRGnIiPE/E8f5H/V0YTO6UaO7+yPTsJX90S/te2jX/Vn5AZb0KG
-        B+/iG7cCw+C2c9iFoSBqfpJOecYpVZu+FYzhmlI7yisp0fBtD+2sV4Ttg/1P
-        VOC+eycQzq3Jdh+u3a/JdgEsEfAqvvcA4B8Ep/yhwLR/Aze9Yj/p+d+RTvyI
-        v4g28OP0Gn5Rfy92+HAdeBO/9Cv+hwLsbc/Kx71MxDjMGn5Tf1HHPJSQJx3C
-        e2L9G96nlXfy7yhJv59DSMUfVPyRvvgT/9xS8Wf8ZQ7Mxl9xew59Nnpt3BF/
-        22xctfGKjSs2pxPlkI3DNtJif8LGiI19NkZtnLLxrCCqNqbE5pKNyzbm/gd3
-        15BHbhcAAA==
+        H4sIAAAAAAAA/61Y+3cbRxX+ZmU9LCuxrMR2bIdEpG4jW02kJKWllnHqBpfK
+        cZwmdk0bA+laWjtrr1Zid2Wc8kp5tTwLBQKUd3lDgACtY8M5YPIjfxSHO7Pj
+        lSytEuPmJNqdvTP3u999zJ05/s9///5PAI/hDkPCdqoLdmZKt52Z6kLBUG07
+        DMawMLWsrqoZQzWXMhcXlrWCk3MlVUc3xPLRuhV509GWNCs3lptaKTuGbmaW
+        V0sZnaSWqRqZkmqtaJadOX9BrVS04gXxmWOIN9oIo41h/047YYQYhnYNG0aE
+        ITSqm7ozxhBIDc3FEEVHFEHEGJISp1A2DLKnl007c642Pk/W9jO0a6WKc50b
+        pwClhhocz8UQR1cUnUgwxAYHi5qhLamOdjVLHjWvPYjudijoYWhzruk2w8Gp
+        5phTMMJLmjOjv6wJ0nlabdNHDIcx0IEw3sMQKZRNR9VNgmhL5YeuMHQ1ZSCM
+        9xLSqmpUtYuLDD20zidNMTyEwSiO4WGG7lRzpoeuxHAUx7ndFMGRfyXNpFgw
+        otWxzWLcMBj6UnUO1wKZ4+xO+s+NppsNjgmFh6bK1lJmWXMWLG4go5pm2VHd
+        JE2XnemqYVCcIpKOHQEF/IhfYZCfFgHoBarl0+Ri4ZpWWJEIz6mWWtJoIcNx
+        H9frJDMcZCnHC+gxvC+KM3g8hkdxgofl/RRbf88pfZRIHtcdoZfwMeQwygE+
+        wBDUzaK2RvEVb54untZ8i5TkY3gKT3PVc1zFnuAlKmqFkjWBZ/jMhyg6Ormm
+        OmWLJ7++cvNSTgTTvhP++zmGPCY59hSlnirVybtkY5h22VykPWBQJec9u/1N
+        O6bOdqblZCv7l3CZ25llGPBC6oecbT3bGnqOQ79AAbWrC+5+P5jKN+EQ+pCP
+        uBXsFcxz2I9SI1m0yqW8TLNTlqOAWixS9dWUnzftaqVSthyteLHCKVMhTawV
+        tAofhLHAcMaTJ3U7Sdsi6WkkF8tW0tLU4omyaVxP1jpbBMWGWqqr6CgWoyhg
+        icqQezZHPZNYiT3dn8q33tTZFpM7dnUtGFwls4s+sFMjWDA0lSopZGml8ip1
+        xETzhqDgurOCc9TSKoZacD8erje4WDWFOQqyal13w0j1wj0euf86/xRzZaVC
+        3efY/Q0JnrxhCmoBm/eG3lox7UDmTZ9y2tRWSxW1xjrjPzd6oiXVHn+wGPox
+        EKWj6TM7TuLpammBHyQ3eDMxnTl+lsTwOb70FXyeHwxJrvRF3soG+ehV3pnG
+        +ejLvCuI0VfF2ePTxuZ42/Wb8MswbZlxy1KpzaVS8z46PjI64kdnR3xOmNT8
+        7Cxp0IPqS+WoEbxB292vNMP4DlWR38lSWzPrUgvjJsNYi1Nwl5xjeB3fj+J7
+        +AHDAV+fulP+vqZbHb8trPyYW/kJ+barTkYXjO3r3AUq4aLqqCRTSqsBuj0y
+        /mjnD9DFYIXkazr/ol2hFE8xNrJ1IxtVDilRJZ6kXySqRIL07qB3gN5H6B2i
+        d4refM0wlx/aunE6kmhLKFkly54O3n0rpMQDk13xcL+SjZwOxdvprTx792Zg
+        sjceFbJYvKN/WyNGM2yyJ76Pr6LV+7dXC5xOwonLmW0cNtke7+I4YtwZT3hY
+        B4SVrvjBJo3OeLe3qkdIeusldXbZ5NF4rzfDaOaQROvbXnE5EW/j4xfu3uTe
+        hvrbIsF4iEeQri0U12S+VKo66oKh1ZI7seZodLehS9HJFWoV7TP6kqk6VYva
+        ZNu5cpFenVO6qbnbeJbr8v5ZLqjGnGrp/FsKBy9XTUcvaXlzVbd1EnlXo/Ha
+        xYtO3cZlO2b3zThqYYUu4BI0OlOuWgXtGZ1/9EnVuSZFnKImEaRfGO1g8QS/
+        JZO/f6ICUvAzup4yfmmn559JMkIyCgdiw3ewb3gDB95B71/Eytv05O0GhBOh
+        H5fG3LU4hD5Rm9TkJE6KVyrXGH4bvZs4wnBLrKhpRT0t6nJS63HC5xb2c62B
+        DTyyiSGlTrPHnZWafDSMtLBEd0UEBMaTEqMrnTi1gSc4UnoTTzbDdHkwXciS
+        49shOYm/cic5akaoUO8lcTO/TYwp2MKx2/fgd1bw+xuNQx4edfDW/n5wd/7S
+        LdQ/0s/eK9J0v5RRatC6wHC7hZYblPMNPkzfy4fnducD3Tb92Tx/PzYzDWzo
+        cimRzkg2HTJDLypoTE+HR6VDpscF/XADKF0tJegYvQNiU3DQw5v4WKAONenO
+        eagxXBWofPQSjRSJ/5EGfNUr+9OEwJlF/4HCiwntDq79q4Fz1EOPeuFToUv9
+        UcnPT99lV69/VrJzkfh2X8aKLPC9ImVF43D9NATiCYn4//lWvw9LNDK9xpQi
+        HNYCp7HMyzi+x8hWRGQ//gDYnxQ8xvfEQ8Q1Pk76o3vXp38W7D35UcWq54dD
+        o088oHis4foDqtiX8ck9evZpj9GnqG0c9g6sjGxBweF1fPYWtk+8kBDWn3ZB
+        CXeJ/9lGKl+WXac7/W8cexPBwK3h9BZeWccX1vElDhbA2+LJ2ptQXZLdHslu
+        twwp/Tkv/SMSPzQ8sI7Xbvuyc3FCHk5Ihu0S/1tGC55KHc+v7I0n4U/vCv9r
+        e46D+m62s9D/+rsuuwoUQlrDNx4EEo1fxzdlAT8hY9aZTnyb31e28N30Bt5s
+        PLU6PbhOvIEfelX8LQH2I0nrEVnFEQ6zgZ82HqMRiRKQ2gG8I95/xDq9+e78
+        ORX4W3Tw5fGLPH6Zx6/waxriN3n8Fr+bB7Pxe/xhHv02+mzcEv87bBy2uWTA
+        xlEhGbbxqI2sGOdsnLUxaOMpGxM28kI4beOSGFyxcdXGS/8DOjz+UycXAAA=
         """,
         """
         stubs/MapObject.class:
-        H4sIAAAAAAAAALVY+3/T1hX/XvmJowTFIU9GyWgAJ4E60NJC7bEmWQIm4RFC
-        QwkrVHGUVMSWPEnOSPcoe7R7vzfWde/uvbEtrG2Ass/G2G/7o/bZuZIsO46c
-        OIF9PrZ0de+533Pu95x77pH+898P/gHgGfydYbtpFWfM5Gm5cHbmmpK1ImAM
-        1vg1eVFO5mRtPul0p5yeoqXmuGy6QiCjWcq8YqR8uo6nxhd0K6dqyWuL+aRK
-        vYYm55J52VhQDDM5RkgFZfa0/ZhikKq1RhBkaFylOYIwQ2/dqBFEGcJpVVOt
-        4wyBRO+UiBgaYghBZOh0cbJ6LkfqVF2zmTDHSHMTQ1TJF6wl6mBoTvSuZiAl
-        QkJzDNsRZxB7emaVnDIvW8rVAeJ0jegOtG6DgDaGoPWqahLeeBXvtPyGrK5Z
-        sqqZY8oSCSYyvdMkuIbVCD7EEFmUc0Xl7BxDG8n5UC/iCeyOYRe6GVoTa/3Z
-        Oy2iC3saEMGTRMwCV8kyxHbJiCmuQMR+RybBELJVkuy8YjH0jOvGfPKaYs0Y
-        XDopa5puyQ6FZ4q5nDyTU2hN+/xUr+0S0Y+DXM9TtDTVHOG82+4iKwdwiI8c
-        ZoiR5hHNMlTFrPbIpMIZPFfdl17tiR4+e6nu4D1OkE+ut07d4ktN8UjhwKRQ
-        xFEc4eYeo4WQueRKk7Pgb1eVPopU8oON8hEH5biDMqm+pth0kIOCJj2IGMIg
-        Fxhm2EYCtrNIUccqRcNeWBP0wRpDNU2x3W2KOIlRrolUh7I5RTYY9pdnvKiZ
-        xUJBNyxl9mxBMWxiRq5nlQJvRDDO8LTX362a3URetzeje043ug1Fnj2oa7ml
-        7vIujOJMVdROkte1+ZSzfc/FcBoTRE1WzxeKFlFzIlHTp/Zy54qaDZwcUkfd
-        Zspv1zC8sXmk9EGfKX59/b5U+9shFCiRtNQYOsSwe4PVURZy2cnMDc6YFJ8M
-        I/WubQOO9M3i+DK0GTZ2rWslnRzeWs8ZirPYUF4x5ik0pmsb++jR8tZjAf8/
-        BRBlzACRwtCeyPieEbTJaXwwl2OIJ6rOrN4phnRVZ9pPfw2baHpwztDzdKyR
-        jnIMpupkrIa9hpLXF8mr+zc4V8pT4msF/af7nZGUYwylkJOzSpmN+ny9ejEE
-        FHOBbLr3JDYKN+LvlQ2EHjVsplZVXGeK+RleXJCPolRTucf/IgZjKOKTvFjY
-        GaMSZomXBHbrU/zQ3s1bn+GtHG+9LlJVeYS3Pici5bS+IOIFjiLgDREjGOWt
-        L1Ulo7VF5kZ70CscJnGBI36VYbhOxPXxpnGZ431DxBUH+VsMF+sKl61YfxWv
-        cB3fZThaX0j6gWQxy0F+IELFNd76oYgFxyE/Yji2CeOrK0QdBY7yE96ykX9G
-        0ZHO5ux6mj9TER3NnJm8MHhmeETEO+jkZe6vGJ7b4vsCr4zdovy0YsmzsiXz
-        XJZfDNALC+OXENWpC9R1XeVPdEgKs4cYa3tw40BM6BBigtRD/2hMiPL2Hvrv
-        ozY9S0/QPUD3BrqHo/9+U+h4cONwUzwYFwYE5zrAhiJR4eE7YUEKnGqW4l3C
-        QMvhsLSD7sLJhzcZ9bW6fW1eX4fU3hXsYANChWTAxug4tU3q5PJc7nyPFOza
-        EZfiqzWGB0IvPbwZIvlwVzAakaLnO6RtXVF3tHIsRmNxqYFrqOgVpUaa0eTN
-        2F4xJknNnB06BkB5TCkVzsEFuybtzuTzRYuX6eVacOS6pWgmr22fWqA8sPN8
-        UbPUvJLRFlVTJcnBcvFLdeekOq/JVtGg3Bgc1mcV/uKjaoqTSC5wZJ599ayc
-        m5INlT+7nY2TlpxdoLBwn2OTetHIKqMqf+h0lU6tUYlDFFsh+kfAo6yThxut
-        7D0KgzDdnwOkOH/Tovb71CfgN0jQlV73qGeFetL0JNC9qe8OGvsC6btoeR/t
-        t23ZO3SN2aMS3SXcpZZI80gaHaSHc0gp0EV61kN6D+077+LD99Aj4JYtxWe2
-        OaPuTN7ai300xnjyrI3Ruz5Gn4tBaZfGOMYxF6O5jJEU8AC7lqtgmj2YZteU
-        Em0HbEl6yXLNStgqiAwOeQ9PswqTHEJiHiGU6xHwm/U8w3KNWY5rnq10G11T
-        tZA+uhFSugqJzhr/lXxsvZXQueSv/9RG+k9U6R/zwi1BiLb8fZy+FD97B+f/
-        WVM/nWKuS9M0K1BjVrcz4vkyhilcdJFewiVCcGx6kfroHHtkxJc9xI9T35XH
-        biOdfi4iZz9YA7HPGamBeNGO7xhmCDvgYss0Soeit+03Y62zO3iLbzeB2grm
-        XCsPk7RQA6nNtaOM9GpFKpqnFh3OW7KoerWMH+4u0uYs2ou8Hd0L0LbITd7j
-        Jm9bQgWCi/Q4PHjR3jH6Y+PpEzC25LkpiqWS50xM8A9lrkXn3YTb2v8v7Hob
-        ocCtvv4HKK7g+gpe4+klgHv2lW2zj5SwbZFUoafV09Pq8jnBP7LVgf/pTeP3
-        ufj9XrxU47PlMv5nl7dkvzTIP965+M+7+OG+/hXcWEbpaF2LE/Zwwh4PR+kU
-        cPyVdLNwqG8Fn/eHcVJoqOpYmeCfznxAvlg/SJpAhrxTpBLkzVt1gEzwL2Y+
-        Fny5fgtOEKeT+IprwcnSLuCu2nVgBV/zR/LbEaX9amdeQp3G12uhfnMrqC/b
-        qFdq2/rtrdt6Fd9xUacof/AM0uSg0v/gCr7nj+zkmsqyqYTcRMh5t6iyTwvS
-        kcX3XR0TruUtpQ1xoLQvbq63hBZPUYuXHluc9Ejwqgc/5sI3ektYwVvrATd6
-        wI3eChqdFRDwgv+Oe3tTO45wdPzYxbnkctxc5tg28qf+Me/QXFlWloxs9mhu
-        JprzNs36ujz8fIs8IIpfeNVWu60SaLgP4dId/PJd/Pq23VEqCgL4wL6/i/t0
-        X6Jpv6Vt97vLCGTw+wz+QFf8kV/+lKFC8c+XwUz8BX+9jC4TnSaW7V+Didul
-        9jMmjpj4m4mUiSETL5gYNHHSHhoxMWryidTea2K/iT4T/SZ2mxj4H6im5hh+
-        GwAA
+        H4sIAAAAAAAA/7VY+1cbxxX+ZiUkIYS9yObdJNihRoCxMHGd2FJpgWJHNmAD
+        Do5xE2cRC1m02lV3V9SkTeM+8uj77abpO323bktOWztpzmld97f+UT29M7tI
+        QkggMDlH2p29c+e739y5c+fu/vd///gngFP4C8NB28kv2PFJJXdpYUVNO0Ew
+        BmdiRVlV4rpiLMddccKV5B1N57rJEoWU4ajLqpWoIBpOTGRMR9eM+MpqNq6R
+        1DIUPZ5VrIxq2fGLhJRTFyfFY4JBLrcahJ+hcZPlIAIMvTWjBhFiCCQ1Q3OG
+        GXyx3rkIwmgIow4RhnYPJ23qOpnTTEN4wr5Ilg8whNRszlkjAUNTrHezBxIR
+        yGgK4yCiDJHu7kVVV5cVR70xSD7donoYzfWQ0MLgd17UbMKbKPM7TT+8rDrj
+        hmNpql1ucFblCpfLZcnNhrr56LWa12aYIB+fMK3l+IrqLFiKRrNXDMN0FNcT
+        U6Yzldf1BHcEByaDETyKzgYE8RhDkOheVNeI67EqvMrs0UJkVBflcRel20WZ
+        1V5SxeKkyD82PUQQQw9X6GWoJ4U5Rc9zp7RtMjRWWDWCHqjSVZXKqsCM4ASO
+        c0txhoa0aTjcCzQrIhJL9c7TOmwZHsQTRFsMv7TE0EJ6FWxE8BGcDtMee5Kh
+        ObZ1P/XOR3ASZ7jpszT3DDfJaP6NGyTEnCMYdnU+xlAnTJIuOYShe7uFo1VT
+        FnQ1wZemgumtoghG8QluZ5ymptnjPO7FihDL83ia9xC3urSuKhZDT3H8M4ad
+        z+VMy1EXL+VUSxAYv5lWc7wRxATDEwV5l2Z3EcmuwoiuJdPqslRlccA09LWu
+        4i4MYarMa7O0LYzlhLt9L4cxiWlimjazubxDPjkfqxr0Ih6W8oYAjo9q57xm
+        otKqMby6e6TkQIUhlWT9FWOxMg8pR4nkUJWukwyP7TA7ykKed1JLIws2bWCG
+        8VrntoOPzN3iVPTQbrzxyLYs6eQozPWypbqTrcuq1jKFxnx1sg8fLW/uC/gH
+        FEBDtIPJKQytsVTFHEVZkPpHdJ0hGis7s3rnGJJlwmQl+1U40XD/kmVmKa2S
+        jWIMJmr0WBW+lpo1V2lVe3bIa8Uh0a2KlYdXytGUYyw1pytpteiN2tZ682QI
+        KOwBCXcfje0UbuS/F3ZQetiwoVzagc4w1SV0Ih9xW6sRHEMPb92MoB/Heeul
+        TZXZVD67wA/Bz1JZQLWXd0x9jg96Ga/wQ22ID/o8P7pE64v8cDnNW6+WpaCt
+        peVOO6+wgGM14myPcrWmMNgLv6dqC7BKJ3EGOnfWVxnO7IJeedyGkmldVL0c
+        i0rdUGpq9srI1Nh4BN9COy9Gv83w5B6rel6/eqXzpOooi4qj8IyTXfXRawXj
+        l3p+AZU0GZLf1PgTnWfS4knGWu7fOh6W2qSwJHfTPxSWQrx9lP7HqE3P8qN0
+        99G9ge6B0H9ek9ru3xo6EPVHpUHJvQ6y0WBIevB2QJJ9F5rkaIc0eGgoIB+m
+        u/T0g9uMZM2erKUga5NbO/xtbFAq0fQJjLYL9XI71+d6M92yv+NwVI5uthgY
+        rHv2we060g90+ENBOTTTJtd3hLze0r4w9UXlBm6hRBqRG2nEgcKIgyV9stzE
+        vUMZm3wWVDdeAvwZUV8fqlDlB/E2nXGiydCVymbzDi/5ioXv+E1HNWxeD57I
+        UN7tnMkbjpZVU8aqZmukOVIsGKnIntWWDcXJW5Tn/GPmospfYjRDdTf7FY7M
+        M6mZVvQ5xdL4sydsnHWUdIZoec+RlGGo1piu2DafQXjWzFtp9ZzG+9o9DnNb
+        GFDWkOiVTKI6k4dmO49R8sRvKGwCdH8EkKP8JYravyWZhO/SG4LE3+RI8juS
+        nKUnch4ifffQ2PcuDv0dre8Izd/Tle8BgkCI/n/gWq4u2sgK9zilQfgETozH
+        LB/R9ze0vocuhnWhURwV9ka5PD5UypGuR6ohfXgnpKNlSJSGvbmVIfUx3KmC
+        xHjKrmx/cCf7A2X2KY979k9TL/ffAY7U+S6eeg8JqYRDi9vrofFWEh8V1oe3
+        w/j49hgjHsaoGMsxzngYTUWMcxLu49R6GUxTAabJo7IxtTGhSW80lV17YTvX
+        XiwEW4xcLPrex+S16KV7mPlX1VGzuOLRT9IoX5VRXW5PgXcYc7jqIT2La4Tg
+        LtIzJJvH9YdGfK6A+EmSPb/vHG/gBQ/xHI3yV0Hsc3uqIF4VaxnGAmH7PGyF
+        etNY9NZhd2zdSOAtHlo8XahY8lgOkbZUBanF41FEerEkES1TS8PKnhiVz5bx
+        s99D2h2jJLIikjMw9uibbME3WcHERM5D2o8VvCp2jLlvfvoUrD2t3BzF0sbK
+        2ZjmX7M8nLiXCer67iK/jo2TIyCEpadGXVn+n+YfsyqAfLp2kKMEEiuk+1KQ
+        tTs1gEzzb1gVGHymdgYDBHKSEqzLYMZLtM39/8apt1Dnu9PXfx8v38Wtu/gC
+        Z+TDH8WV1W9Bd33eXPB5sxdb0/xLVg34X9o1Po9YJk/zL1hV8Nl6Ef+19b3y
+        Hy3szQ8AXx6hk+L1Pe6Ojb0rsjAhzeONh0Z6TiA9v2+cbuDLe8wnRaRs6YlA
+        mGl8ZT+yHSFpe0QqY0dImUIUnvWiJNDXfxdfq7wX3WgIFBADhWgw8fV99FdW
+        +Mvcn1lSGf2NQi3UKmwADe9DunYP3/wrvvOOEPhFKRUmtV9SVf+rQL2Xanz4
+        k7j/Gn+m+xr1f4+S0fevw5fC7RR+kMKb+CE18VYKP8KPr4PZ+Al+eh0dNtpt
+        /Ez8Gmz8fKNN8k4bv7BxxEbMxjEbPTZOiK5+G8fp3UK0kzaGbYzYGLVx2sb5
+        /wNOKu12BRsAAA==
         """,
         """
         stubs/MapSubclass.class:
-        H4sIAAAAAAAAALVY+1/b1hX/XvkFRhDZBAJkNCwliYFQk7Rpk9rLChkkDpAE
-        aElD1qTCCCqwJU+SWehe2aPt3u9lXffu3lu2sa0l7fb5bFl+3B+1z86VZNkY
-        GQzJPh9burr33O8593vOPedK//nv3/8J4CncY4iZVnHeTE7KhZnifDYnm2YE
-        jMGaWJZX5WRO1paSl+eXlayVcnqKlprj0ukKgYxmKUuKkfLpOpuaWNGtnKol
-        l1fzSZV6DU3OJfOysaIYZnKckArKwqT9mGKQqrVGEGRo3qQ5gjBDX92oETQw
-        hNOqplpnGQKJvlkRUTRFEYLI0OniZPVcjtSpumZzYY6T5haGBiVfsNaog4hK
-        9G1mICVCQiyKfYgziL29C0pOWZIt5eYQw74tovvR1ggB7QxB6xXVZGid2MI8
-        EdCU1TVLVjVzXFkj0USmb45Ub+E1gg8wRFblXFG5vMjQTnI+5It4DIei6EYP
-        Q1tiq0f75kR04XATInicqFnhKlmG+C4ZMcsViDjmyCQYQrZKkl1SLIbeCd1Y
-        Si4r1rzBpZOypumW7JB4qZjLyfM5hdZ01E/11i4RAxjkep6gpanmKGfedhhZ
-        OYQTfOQkQ5Q0j2qWoSpmtU9mFIu0XanuS2/2RS+fvVZ3+J4lyMe3W6du8aWm
-        eKxwYFIo4jROcXPP0ELIXHKlyVnwt6tKH8Uq+cFG+ZCDctZBmVFfVWw6yEFB
-        kx5EjGCYC5xjaCQB21mkqGOTonNeYBP0YI2hmqbY7jZFXMAY10SqQ9mcIhsM
-        x8ozXtDMYqGgG5aycLmgGDYxo7eySoE3IphgeNLr71HNHiKvx5vRs6gbPYYi
-        LwzqWm6tp7wPG3CpKmpnyOvaUsrZwFeimMQUUZPV84WiRdScT9T0qb3cxaJm
-        AydH1DG3mfLbNQyv7R4pPegzxa9vwJdqfzuEwhDPE/5DJxgO7bA6ykMuO5nF
-        4XmT4pNhtN617cCRvlscX4Z2w0b3tlZS7fDWesVQnMWG8oqxRKExV9vYh4+W
-        Nx8J+P8pgChjBogUhgOJjG+NoE1O48O5HEM8UVW1+mYZ0lWdaT/9NWyi6cFF
-        Q89TWSMd5RhM1clYDXsNJa+vkleP7VBXylPiWwX9p/vVSMoxhlLIyVmlzEZ9
-        vt68GAKKukA23YcTO4Ub8ffyDkIPGzazm85cl4r5eX64IB810KnKLf+rGI6i
-        iI/zw8LBKB1i1viRwG59ghftQ7z1Kd7K8dZnRDpZnuKtz4pIOa3Pi3iOowh4
-        TcQoxnjrjapktPWYudMe9A4OM3ieI36Z4VydiNvjzeE6x/uaiBsO8jcYrtYV
-        Lnux/iZe5jq+zXC6vpD0A8ligYN8T4SKZd76vogVxyE/YDizC+OrT4g6Chzl
-        R7xlI/+E4Zk9vgzQka30PjCpWPKCbMk8TeVXA/Q+wvglREfQFeq6pfInqn/C
-        wgnGpPu3j0eFDiEqSL30b4gKDbx9mP5HqU3P0mN0D9C9ie7hjvu3T7bEg3Fh
-        SHCuQ2wk9ODtsCAFLsakeJcw1HoyLO2nu3DhwR1GfW1uX7vX1yEd6Ap2sCGh
-        QjJgY3RcbJQ6uTyXm+6Vgl3741J8s77wUOjFB3e4znBXsCEiNUx3SI1dDe5o
-        5ViUxuJSE9dQ0StKzTSjxZuxr2JMkmKcF8rtoOSklE7DwRX7oNmTyeeLFj97
-        lw94o7csRTP5gfWJFdrcjTPqkiZbRYNSWvCcvqDwNxZVU5z9/zyfy5OmnpVz
-        s7Kh8me38+B0UbPUvJLRVlVTpa7h8lmYXhxmLDm7QgHhSkdn9KKRVcZU/tDp
-        Tp3dMhEnKKpC9I+gEUyK85clWtmfKQAE/IxyDeNvbHRdp5409Ql0b+m/h+b+
-        QPo9tL6LA3+xZfk1ao/G6B7DX6kl0jySRgc6eYzxHOYiPe0hvYMDB9/DB99H
-        r4C7thSf2e6MujN56wiO0hjj2a82Rt/2GP0uBuVNGuMYZ1yMWBkjKeA+uter
-        YGIeTMw15W/UDtP9uC1Jb0muWQlbBZHBId/Hk6zCJIeQqEcIJWsE/GY962D5
-        zXJc87Sn/xlbLlUL6cM7IaWrkKhY+K/kI9uthAqLv/6LO+k/X6V/3Au3BCHa
-        8v/A5LX45XuY/ldN/VSGXJemaVagxqweZ8TzZRSzuOoivYhrhODY9AL1USF6
-        aMSXPMSPUt+NR24jlS8XkbMfrIHY74zUQLxqx3cU84QdcLFlGqWq5m373Vjr
-        7A7e4ttNoLaCRdfKkyQt1EBqd+0oI71SkYqWqEXVdU8WVa+W8ersIu3OoiPI
-        29G9Am2P3OQ9bvK2JVThXaRH4cGr9o7RHxlPH4OxJ8/NUiyVPGdiin/pci2a
-        dhNu28C/0f0WQoG7/QP3UdzArQ28ytNLAO/YV9Zol5SwbVGsQk+bp6fN5XOK
-        fyWrA/+Tu8bvd/EHvHipxmfrZfxPr+/JfmmYf31z8Z918cP9Axu4vY5Sad2K
-        E/Zwwh4Pp6kKOP5Kulk41L+Bz/nDOCk0VFVWpvi3Lx+QL9QPkiaQEa+KVIK8
-        frcOkCn+ycvHgi/Wb8F54nQGX3ItuFDaBdxV3cc38BV/JL8dUdqvduYl1Dl8
-        tRbq1/eC+pKNeqO2rd/cu6038S0XdZbyB88gLQ4q/Qc38B1/ZCfXVB6bSsgt
-        hJx3D1V2tSAdWXzX1THlWt5a2hDHS/viznZLaPUUtXrpsdVJjwSvevDjLnyz
-        t4QNvLkdcLMH3OytoNlZAQGv+O+4t3a14whHxw9dnGsux7Eyx7aRP/aPeYfm
-        ymNlyciYR3OMaM7bNOvb8vDTPfLg1fsA3rXvf8IG3ddI5ue0o96+jkAGv8jg
-        l3TFr/jl1xn8Br+9Dmbid/j9dXSZ6DTxB/vXZOJuqf2UiVMm/mgiZWLExHMm
-        hk1csIdGTYyZfCK1j5g4ZqLfxICJQyaG/gcbVySQHhsAAA==
+        H4sIAAAAAAAA/7VY+1cbxxX+ZiUkIWR7kQ3m0STYoSDAWJi4TmyptECxIxts
+        AwlOcBNnEYuyaLWr7q6oSZvWbZP0/W7dNH2n7x7/QM9pnaQ9p3X9Y/+ont6Z
+        XSQhViAwOUfanb1z73e/uXPnzuz+93//+BeAs/gLQ6vtlJbs5IxSnC8tZXXF
+        tsNgDM70qrKmJHXFyCWvLa2qWSflSkqOpnPtdJVCxnDUnGqlfERjqem86eia
+        kVxdKyQ1klqGoicLipVXLTt5hZCK6vKMeEwxyLVewwgyHNriOYwQw0DDqGFE
+        GEJpzdCcMYZAYmAhhihaomhCjKHTw8mauk7uNNMQsbCvkOfDDBG1UHTWSUCB
+        SgxsjUAqBhmtURxBnCHW27us6mpOcdRbIwxHtqkeQ1szJLQzBJ1XNZvh6PS2
+        yFMAojnVmTIcS1PtWpfzqkMK12tl6a2uern1esOzM0aQT06bVi65qjpLlqLR
+        +BXDMB3FjcVV07la0vUUDwUHJocxPI7uFoTxBEOY6F5R14lrXx1eNf5oKvKq
+        i/Kki9Lrosxrr6liejIUIZseYkignysMMDSTwoKil3hQOrY4mizPG0EP1+mq
+        S2VNYMZwGqe4pyRDS9Y0HB4FGhURSWQGFmketpmH8RTRFubXVhjaSc/HRwwf
+        w7korbOnGdoS21fUwGIMZ3Ceu75AY89zl4zGf2iThBhzDGOuzicYmoRL0qWA
+        MPTuNHE0a8qSrqb41Pi43i6KYQKf4n6maGiaPcUzX8wIsbyEZ3kPcWvK6qpi
+        MfRX7J837FKxaFqOunytqFqCwNTtrFrkjTCmGZ4qy3s0u4dI9pQtelZMq8dS
+        leVh09DXeyrrMIKrNVGbp2Vh5FLuAr4exQxmiWnWLBRLDsXkUqJu0ot8WCkZ
+        Ajg5oV30mim/WWN4c+9I6WEfEz/ZkG8u+vOQiiO8Tvh3nWF4YpfRUR3yopNZ
+        GV+yaQEzTDU6tl1iZO4VxzdCe4nGYzuypL2jPNbrluoOtqmgWjlKjcX6ZB89
+        W94+EPAPKYFGaQVTUBiOJzK+NYqqIPWP6zpDPFGzaw0sMKRrhGk//3U4kXlw
+        xTILVFbJRyUHUw1GrA5fSy2YazSr/bvUtYpJfLuiv7lfjaYaY6lFXcmqlWg0
+        NtdbB0NAUQ9IhPtkYrd0o/i9sovSo6YN1dIudEfpZEI78gm3tRZDH/p563YM
+        QzjFW69tOZtdLRWW+Cb4eToW0OnL26a+wI1exxf5pjbKjb7Ety7R+grfXM7x
+        1ps1JWj74XK3lVeewMkGcXZGudFQGuyH3zONJZjfTpyHzoP1TYbze6BXm7dP
+        7/PITieezVP7jOooy4qj8GJSWAvQWwPjl2Z+AZ1W8iS/rfEn2qqk5TOMyQ/u
+        nIpKHVJUknvpH4lKEd4+Sf8+atOz/DjdA3RvoXuo48Gd0cPxYFwakdzrCJto
+        evhuSJIDl1vleJc0cnQ0JB+ju/Tsw7uMZG2erL0s65CPdwU72IhUpRkQGB2X
+        m+VOrs/15nrlYNexuBzf6i800vTCw7vcZ6grGAnLkbkOubkr4vVW90WpLy63
+        cA9V0ph8iCwOly2OVPXJciuPC5VhilZY3TzZB/Pi0HzU5+gexi9o4xJNhp5M
+        oVBy+Dmucpqduu2ohs0PeafzVEyb57WcoTgli8pTcNJcVvnbh2ao7hp9jtvy
+        AmhmFX1BsTT+7Am750qGoxXUjLGm2RqJxivnRzqEzjtKNk+0PO1YxjBUa5K/
+        p/ARROfNkpVVL2q8r9NDWtiGQ6VAojctiQ6PzWBynL8HUSR+Qwkj4Tvopza9
+        jNH1XZJcIBkFCrHB93Bo8H0c/TuO/1Vo/paufEEArYjQ/3dcy9VFBzpFLlId
+        Q0DgJHhmcovBv+H4B+hh2BAaFauoZ+Xy+Ah+T/cQ9Twm9E7UQ/robkgna5D6
+        xAh9kAYZ7tVBYrzm+vsf2c3/cI1/KsSe/3PUy+N3mCN1v49nPkBKquLQ7vZ6
+        aLyVxseF97GdMD65M8a4hzEhbDnGeQ+jtYJxUcIDnN2ogWktw7R6VDaHNik0
+        6ZXEP7SXdwrtlXKyJSjEou+fmHkxfu09zP27rtU8nvPop8kqUMeqx+0p845i
+        ATc8pBfwIiG4k/Q8yRZx85ERXyojfppkLx84x1t4xUO8SFbBOoiDbk8dxBti
+        LqNYIuyAh61QbxbL3jzsja2bCbzFU4uXCxUrHstR0pbqILV7PCpIr1YVohy1
+        NKzui1HtaBnfvD2kvTFKoyAyOQ9jn7EplGNTEExMFD2kg5jBG2LFmAcWp8/A
+        2tfMLVAubc6cjVn+OcrDSXqVoGnwPkob2Nw5QkJYvWs01dT/Wf41ygfks42D
+        nCSQRLncV4Os32sAZJZ/hPJh8LnGGQwTyBkqsC6DOa/Qtg39B2ffQVPg3uDQ
+        A7x+H3fu48ucUQB/EFfWvA3djXlbOeZtXm7N8k9RDeC/sWd8nrFMnuWfoOrg
+        s40K/lsb++U/UV6bHwK+PE47xVf3uTo2166owoS0iK89MtJLAunlA+N0C1/f
+        Zz2pIBWqdwTCzOIbB1HtCEnbJ1INO0LKl7PwgpclocGh+/iW/1p0syFURgyV
+        s8HEtw8wXgURL/NgRkk+/yieGH5Jh/NfhZq9KhLAn8T91/gz3dep/7tUZ753
+        E4EMvp/BDzL4IX5ETfw4g7v4yU0wG2/jpzfRZaPTxjvi12LjZ5ttknfb+LmN
+        EzYSNvps9Ns4LbqGbJyiVwTRTtsYszFuY8LGORuX/g8xSG5wpRoAAA==
         """,
         """
         stubs/SetObject.class:
-        H4sIAAAAAAAAAK1WW1cTVxT+zuQ2TAYJUUSw2lRRA6kG0Wo1FEHEGuSiJFKV
-        VjskYxyYzKQzE4r2Zm/28gN86GNXH32oq61iXaul9q0/qqv7TMYhhtDFcrkW
-        nHNmn7O/vfe39z4n//z7+x8AjuJ7hjbbqc7b6ZzqTM8vqAUnAsagTCwoS0pa
-        V4xSuibO1CRVR9P52cG6A1nDUUuqlRnKTCyajq4Z6YWlclojqWUoerqsWIuq
-        ZafPTyqVilqcdD8zDLFGExEEGVqfMxNBmKF306gRiAzhQc3QnCGGQLJ3VoaE
-        qIQQZIYuD6dg6jqZ00zDDds+T2a2MIhqueLcIgFDe7L3+XAzMmJol9CGOIPc
-        01NUdbWkOOr1fiJw3dFt6GiBgO0MQeemZhPeRAPJFL5YMA1H0QzaDiazvVfp
-        1DpKI3iFIbKk6FV1+gbDdjrXhHcZu/GqhF1IMHQk12eu96qMbuyJIoK9BEeu
-        l1WDomRZhugzL0Z0nRhK1sUy6tOU4d4dar43mFpvcMhV2DthWqX0gurMW9xA
-        WjEM01FqtE+ZzlRV1zkNnju2iBTD7mappjgtAtAKdgQHKcTCTbWw6CFcUCyl
-        rNJBhgNNQq+T5DhIKcNLIo1+CYdwWMYBJDktR4jb5pETX5o9xgvDrSdi8hiO
-        c5U3yXWN7CqOafHM1BdM1pOTdqrpRvPukXESGY79FlktqU5Ou626VilPQZs+
-        ZIxgmB84TWKlWKSY13AuGXa1UjEtRy1OV7gZcn9suaBW+CKCMYYjvjyh2QlK
-        RsLXSNwwrYSlKsWDpqHfSqx1iIi3G4qqjkcJWQlnMU49R964FZTeRJWsRczL
-        JFTQVYUoDFtq2VyigOPr08jQUtt1bdCal6y7rrtEpqrled4yOZ4Zw5nlXSPj
-        EoYl5DHLW2CnRF15WcYpLhNAyTxTk71LhDvmiGUplOZkcq5JDzWRMSQG8yeb
-        lH9yLp8nDRooPIWjilAYtjVjJoICw75mZb92Jl9zLQJiZ2iDFt2kzzKuoSTh
-        Bm4ybG0aU0eyeaypje6GDazo3EqZcjFY0N0LmRNNt7CYncrlR6ZGx2R8gC5+
-        T1LyezbzuvB71CNqkiqgqDgKyYTyUoDeMsaHEF1qiyRa1vgX3c1C8TDDT6t3
-        eiRhhyAJsT30L0qCGKI5SnOA5t00872k+PddYcfqnQExHowL/UI/Ox0Rhac/
-        hoVYYLw9FukW+sWBcKyFZuHc03uB8c6Y5MrkWLT7mY5MO2y8JdbKd9x1W2yL
-        v9vG9WbisSDHuPz0XojQw91BMRQLc18HGMWBRLZcrjrKvK6usTy27Kh0A9LV
-        eWiRbu6dM1XD0cpq1ljSbI1OjqzdrdQfOa1kKE7VonIJjppFlb9RmqHWGiTP
-        kXmXmQVFn1UsjX97wp5GXP96fc5Aa85RCov08HpqUs6sWgX1rMY/ujyM2XWe
-        4TAlO0T/EfC0d/H8U7yfU6rCNPcBsTh/O2n9BckEOIjTSA84Sb4kySB9CTRv
-        6XuE1r7A4Aq2/obOB+7Zr2iU3N2oq/E1rWTSo9PYQXY4s3QDeEjHfKRf0blz
-        Ba89Ro+A++4prrm9tutp8tU+7Kc9xl8MBFyMEx5Geyr++goGOFLqMY6uh2n3
-        YdqRwht+eL24S3OE1WKnkZ4Wz7+ka4si4qiPcYLVgdaikvyo6NHwPGrQop9A
-        P2+gVXNgsJ57GulebG5/9P/sn/FZHSA/eMDSE5y9Ej/3COf/bKBC8qmQfEYn
-        yJrwAvr1VE7SasqvE54htgFOo/fT2POC3l9wvb/4ErzvpdXMS8G5yH/oefHM
-        ePXZkfoLu35AKHC/L7WK/EO88xBXeDoD+MYdWYvbPWGXmWidnQ7fTocX70X+
-        C8TDT3s1Eup7iLn7fhPWw9TIDtVgYiNUKs+cG/ack9d8eq85Rs0V2XdF9qm/
-        huseZcc9tLZUfJ634iqKqRVoa9VfA2nzQdqgYMHn7X0XbNFzbb8Xl8hhVmA0
-        9pDooYgw/YrrdPHJ5ScQrjxC5RfYD1xBwDMRwLfufAff0TxHalXiZWkOgSw+
-        zGKZRtziw+0sPsLHdMDGJ/h0DjEbXTY+c/+iNkZsnLIxbKPbleyzccBGyl0f
-        s3GSFv8BceJNatwNAAA=
+        H4sIAAAAAAAA/61WbVcTRxR+ZkOyy7JIiCICVlNFDUQJotVqKBYp1iAvSpCq
+        2NolWXFhs5vubij21b7Z9g/4oR97+tEPetoq1nNaar/1R/X0zmZdQhJ6ONZz
+        yMzsnXufe+8z987w9z+//Q7gOL5naHHc0ryTymru1PyilnNFMAZ1fFFdVlOG
+        ai6kyuJ0WVJydYPrDlYoZExXW9Ds9FB6fMlyDd1MLS4XUjpJbVM1UgXVXtJs
+        J3VhQi0WtfyE95lmiFa7ENHA0LzBjYgIQ8+WUUVIDJFB3dTdIYZQomdWgYwm
+        GWEoDB0+Ts4yDHKnW6aXtnOB3GxjkLRC0b1NAobWRM/GdNMKomiV0YIYg9Ld
+        ndcMbUF1tRv9RGCN6g60NULAToYG95buEN54FcmUvriguVn9I82LM0OqDn0o
+        2I2uJoh4heLJWaar6ibZNyQyPdcIpoZzEa8S0rJqlLSpmww7Sa/OwSjYj24Z
+        +3CAoS1Re7Q91xTsxSHuN0FwlFtBM4kGRmE1PY9i2DCIwkRFsiMBj2keXV/9
+        vcFkrcMhz2D/uGUvpBY1d97mDlKqaVquWj6XScudLBlGmh9LORxHApG9p14t
+        UJ42Aeg5R8QApZi7peWWfISLqq0WNFJkOFQn9QpJloMspHnNHMdrMo7hhILD
+        OMJpeZ24rZ858aU7o7xyvIMkJtMY5CZvUOg6+VVdy+YnU1lRGV9O1sm6G/Xb
+        S8EZvMmxz5IvNZ+nlNbVLptOqVi0bFfLTxU5CkU3upLTinwhYpThWCCP606c
+        uI4HFvGblh23NTV/xDKN2/H1DpHwdlXNVNAkIyPjHMao5ygar0BSWyiC9YR4
+        FYRzhqYSQxFbK1jL1A6x2lNiaCzvej5ozSuS1go60SVTq2U3XCeTpcI8743L
+        /AhMd5a3h4J3uOosrvBaj3Mjci661rBtq3R2icRcncaoI2OID86crlPTibmZ
+        GbKggZJSOaqEGww76vEhQmU4UK+W13VmyqGJyDEMbdJ3W4xZwXVoMvKgO2J7
+        3ZzaEvVzTW7W8Jt4WeReloj3wZzhXcOcaLp7pcxkdmZ4cmRUgYUOfjsWGbq3
+        8qbw29MnaoLOPa+6KsmEwnKIXjDGh0Y+gK4r8ius6PyLbgohf5Thp7U73bKw
+        S5CF6D76SbIghWluojlE8x6a+V5C+uuusGvtzoAUa4gJ/UI/OytKwrMfI0I0
+        NNYaFTuFfmkgEm2kWTj/7F5orD0qezIl2tT53EahHTbWGG3mO966Jbot2G3h
+        dtOxaAPHuPLsXpjQI50NUjga4bHStUUZxDOFQslV5w1tnerRFVeju40uxb4l
+        upO7pkumqxe0jLmsOzppDq/fmtQaWX3BVN2STX3UMGLlNf486aZW7ogZjswb
+        zMqpxqxq6/zbF3ZX4wYX5wYHzVlXzS3Rm+ubyVmrZOe0czr/6PAxZmsiw1E6
+        8TD9RPCz7+BFQPneoaOK0JwCojH+bNL6C5IJsBGjkd5uknxJktP0RRRB6X2M
+        5t5VbP8V7Q89za9o5EUG0pXo9zXXKutiF3nhvNIt4eMkeJ1wi95f0P4Eexju
+        exrrVnJgRdeEb3WC8LmHbdyqaxUHn6BHqLDcWd71LfmqF0nPE70fCHkYp3yM
+        1mTs6CpOcqTkE5yqhWkNYFrRT4k/p6QP39AssjJfNNJDUz+rof/Kip4QP6Iq
+        qxGGB5tYlQMYrjwvGt8K+BkgRB66/BTnrsbOP8aFP6qSkoOk5ICbceJGeAH7
+        SlImaDUZVEmCcNgmONU8TOHQC0Z/0Yv+0kuIvo9W0y8F5xL/x9HPJ+Wfa7j3
+        EWbuB00S8YSVDRL24S7x//5842m/TNuSf2LfDwiH7vcm1zD7CFcfYY6DhXDX
+        G1ljDWo5yLYgyLYyWdFhKpX/R/Z1vOuTdNKPryUZe5+30Rrmk6tYeFAF0hKA
+        tOAGbgVMveeB6X4wB32mJA6zCqO6/iUfRUIhqLF2D59Sfgrh6mOYP+ODh54g
+        5LsI4Vtv/hzf0TxHZg4x7c4hlEEpg+UMPsQKLXE7g4/wMSk4+ASfziHqoMPB
+        Z95fk4PdDjoddDnY60l6HRx20O+t0w7O0OJfSxUks8cNAAA=
         """,
         """
         stubs/SetSubclass.class:
-        H4sIAAAAAAAAAK1W3VcTRxT/zeaTZZEQBQWrTRU1kGoQrVZDEVSsQT4UkKq0
-        2iFZ48JmN93dULRf9Otf8KEPfeizD+05rWJ7Tkt97B/V0zubZRPJ0sPxeA7M
-        zN6Z+7v3/ubeO/nn39//BHAa3zN02E510c7Oqs5sdbGgc9uOgTHwiSW+wrM6
-        N0rZ6cUlteDkapKqo+ni9FDDgbzhqCXVyg3nJpZNR9eM7NJKOauR1DK4ni1z
-        a1m17Oy1SV6pqMVJ9zPHkNhqIoYwQ9tLZmKIMvTtGDWGOEN0SDM0Z5ghlO6b
-        VyCjVUYECkO3h1MwdZ3MaabhBm5fIzO7GOJqueI8JAGxku57OdycggQ6ZLQj
-        yaD09hZVXS1xR703wNDedHQPOlsgoYsh7DzQbIbdE000EwHxgmk4XDPoQDid
-        77tDdptIjeENhtgK16vq9H2GLjoXwLyCg3hTxgGkGDrTzXfXd0dBDw61IobD
-        BEfOl1WD4mR5htZNL0Z1nThKN0RzyScqJ7w7Ebw3lGk2OOwqHJ4wrVJ2SXUW
-        LWEgyw3DdHiN+CnTmarquqDBc8eOI8NwMOiyKU6LALQCZedxCrHwQC0sewjX
-        ucXLKh1kOBYQeoNkVoCUciIpshiQcQInFRxDWtByirgNjpz40uwxkRpuRhGT
-        Z3BWqLxLrmtklzumJW6mMWXynpy0M4EbwfWj4DxyAvs9slqiZNEeqa5Vuqew
-        TR8KRjEiDlwkMS8WKeY6zk3DrlYqpuWoxemKMEPuj60W1IpYxDDGcMqXpzQ7
-        RZeR8jVS900rZam8eNw09Iepeo3E8f6WpGrgUUZexhWMU9WRN24GZXeQJfWI
-        RZpECrrKicKopZbNFQo42XyNDC21XdcGrUXKuuuGNjJVLS+KkpkVN2M486Jq
-        FNzEiIw5zIsS2C9TXd5ScEHIJNBlXq7JPiTCHXPUsjhdczq9EFBDATKG1NDc
-        +YD0Ty/MzZEGDRQeF6hxcIY9QczEUGA4EpT29TNzNddiIHaGtynRHfqs4C5K
-        Mu7jAfWlwJg608GxZrbrDdtY0YWVMkPvTp4Oan6br8ckXW6RO5xkUnklRE8V
-        E0OE+tUyiVY18UWNVyqeZPhxY61XlvZJspQ4RP9xWYpHaG6lOUTzQZrFXnrf
-        xtpgPBlOSgPSALsYefFTVEqExjsSsR5pID4YTbTQLF198Tg0vjchuzIl0dqz
-        qaHQDhtvSbSJHXfdntjl77YLvZlkIiwwbr14LNCjPeF4JBEVXg4yigCpfLlc
-        dfiirtapG1t1VGpr1A9PLFM7bpnVSgZ3qhbdcviSWVTF46IZai2v54SuKA6z
-        wPV5bmni2xP2zlQNRyureWNFszUS+V1xtN5zGfZvPfbSbtuswwvL9J56oPKs
-        WbUK6hVNfHR7qvNNijhJ9ROh/xhawBJJ8fxRvJ/TJUkw0UFreoNp/IIkQyST
-        aN7V/wxt/aGhdez+DXt/cc9+SaPs7orGouArd8XEaexDt8gDUcIe0hkf6Vfs
-        3b+Ot56jV8IT95TQ7KrteppidQRHaY+Jlo+Qi3HOw+jIJN9ex6BAyjzH6WaY
-        Dh+mAxm844fXhzWaYwK131Wht8HzL+3aoogE6nOcYw2gtahkPyrq+p5HW7To
-        V8zP22jVHBjC1zRHffvU2ILtX/o/+5d9VgfJDxGw/Aeu3E5efYZrf22hQvap
-        kH1GJ8ia9Ar6jVRO0mrKzxNxQ2wbnK3eT+PQK3p/3fX+xmvwvo9WM68F54b4
-        pebFM+PlZ2fmbxz4AZHQk/7MBuae4oOnuC2uM4Rv3JG1uNUTdZlRGux0+nY6
-        vXhviJ8QHn7Wy5FI/1MsPPGLsBGmRnakBpMYpVTZdG7Ec06p+/RRMEaXV9Sb
-        rig+9Xdxz6PsrIfWnkkuilLcQDGzDq2e/TWQdh+kHRxLPm8fu2DLnmtHvbji
-        AmYdxtYainsoIU87hG/d+TN8R/MCnalQyJ8sIJSHlYdNIxwxVPNYwad0wMYq
-        Hi4gYaPbxiP3r9XGqI0LNkZs9LiSIzaO2ci46zM2ztPiPxBMeXd8DQAA
+        H4sIAAAAAAAA/61WW3PTVhD+jhzfFIUohgBJKLgQwIkhDoFCwWlooKE45AJx
+        SIHQUsUWRoksuZKchl7p5Tfw0Ic+9JkHOtNCaGfalMf+qE73yIrs2EonQ5mx
+        dI727H67+53dc/z3P7/9AeAMvmfosp3qkp3Jq06+ulTQFduOgjEoU8vKqpLR
+        FaOUmV1aVgtOtiapOprOtUcbFHKGo5ZUKzuWnVoxHV0zMsur5YxGUstQ9ExZ
+        sVZUy85cm1YqFbU47X5mGeRmF1G0MXRscRNFhGFgx6hRxBgio5qhOWMModTA
+        ggQR7SLCkBh6PJyCqevkTjMNN3H7GrnZxRBTyxXnIQmIldTA1nSzEmR0iehE
+        gkHq7y+qulpSHPXeMENni+oedMchYC9Dm/NAsxl2T7XQTARES/Spfaa6keZI
+        2aYPCQfQ144o3qCICqbhKJpBCG2p3MAdCqyF9SjeJKRVRa+qs/cZ9pJewNZI
+        OIJ+EYdxlKE71bq5A3ckHMJx7jdFcJRdWTWICEZhtW9GMa7rRGKqId3LPpNZ
+        Ht1Q8NpoutXhmGtwZMq0Spll1VmyuIOMYhimo9R2ZsZ0Zqq6nuUbUwvHjoHo
+        PhhUDZSnRQBagcp3hFIsPFALKx7CdcVSyiopMhwPSL1BkucgpSyvmjN4S8Rp
+        nJVwAic5LW8Tt8GZE1+aPcFrx91IYjKLUW7yDoWukV/FMS2+M401lfPkZJ0O
+        XAhuMAkX8S7HvkS+lGKRUqqr3TTsaqViWo5anK1wFIpuYq2gVvgkigmG0748
+        qdlJ4jrpWyTvm1bSUpXiSdPQHybrPRLD+00100CTiJyIK5ikrqNo3ALJ7KAI
+        6gnxKggXdFUhhiKWWjZXqR0SrbvEEK+tuj5oziuS5hJ60SdSs+W3HCgz1fIS
+        742bfAsMZ4G3h4QPuOoCbvFaT3Ijch51zHHLUmjvUqnFgMYIkDEkR+cvBNR0
+        anF+nizoRUkpHDWGewx7gviIQmE4GlTLdZ35WmhRFBjGtum7HcYs4S5UEUXQ
+        GbE7MKfuVHCu6e0afhsvy9zLCkP/Ti4MOtE274xp2tKi4igkE8qrIbqgGH/F
+        +Qt0EhGksKbxLzoEhOIphh83HvWLwn5BFOTD9MREIRamsZ3GEI0HaeRrqf0b
+        j0ZiibaEMCwMs0vhlz9FBDk02SVHe4Xh2EhEjtMoXH35ODS5TxZdmSS3925a
+        SLTCJuNyB19x553yLn+1k9vNJeQ2jnHr5WOOHulti4XlCI+SziKKPZkrl6uO
+        sqSrdf4m1hyVDiw66YZW6KCN57WSoThVi8q/7bJZVPm9ohlqrZDnuS3vC7Og
+        6AuKpfFvT9g/VzUcrazmjFXN1kjkn3fj9dOUoa9ZbctqR95RCit0lXqgYt6s
+        WgX1isY/ejzThRZDnKImCtMTRRxMTvCbj/L9nDZJQBldNKfrl95fkOQCyYgO
+        SIPP0TG4jt2/Yt/PruaX9ObtSGuI0fOVO3N1sR897v5Tm3s4KV4N3GLwF+x7
+        gYMMT1yNupXoW1Gfe1ZnCZ972MWt+tZx7AUGhAbLvbVVz5LPBpF2PdEFgJCL
+        cd7D6EonTq3jHEdKv8D5VpguH6YLw5T4JiVD+JrGKEfNuCZ0UwRnNfZfWdEd
+        4EXUZHWZ4ek2VrUAxvGIxojv/z2fnxFC5KGLv+PK7cTV57j2Z1NSop+U6HMz
+        RdwIr2DfSMo0zWb8KkkRDtsGp5mHWRx/xeivu9HfeA3RD9Fs7rXg3OD//Lx8
+        Mt6+hgefYf6J3yQRrynqZIQ9uBv875tnPOeVaXf6Lxz+AeHQk8H0Bhae4fYz
+        LHKwEL5x3yzegloLstsPsrtGljxOpfL/yL6LDz2SznnxdaYTH/M22sBSeh2l
+        p00gnT5IJ+7hgc/URy6Y5gVzzGMqxmHWoTfXf8xDCXnWIXzrjp/hOxoXSccg
+        Es1FhHKo5PBJDhZsmsLJoYpVUrDxKdYWIdvosfHQ/bXbOGCj10afjUOuZNDG
+        CRvD7jxr4yJN/gX455r+Zw0AAA==
         """
     )
 
@@ -926,7 +914,8 @@
                 }
             """
             ),
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -1008,7 +997,8 @@
                 }
             """
             ),
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -1053,7 +1043,8 @@
                 }
             """
             ),
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -1110,7 +1101,8 @@
                 }
             """
             ),
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -1220,7 +1212,8 @@
                 }
             """
             ),
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -1308,6 +1301,7 @@
             """
             ),
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             KotlinMutableCollectionExtensions.kotlin
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
@@ -1399,6 +1393,7 @@
             """
             ),
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             Stubs.Composable,
             KotlinMutableCollectionExtensions.bytecode
         )
@@ -1497,7 +1492,8 @@
                 }
             """
             ),
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
             .run()
@@ -1536,6 +1532,7 @@
             """
             ),
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             KotlinImmutableCollectionExtensions.kotlin
         )
             .skipTestModes(TestMode.TYPE_ALIAS)
@@ -1575,6 +1572,7 @@
             """
             ),
             Stubs.SnapshotState,
+            Stubs.StateFactoryMarker,
             Stubs.Composable,
             KotlinImmutableCollectionExtensions.bytecode
         )
diff --git a/compose/runtime/runtime-saveable-lint/src/test/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetectorTest.kt b/compose/runtime/runtime-saveable-lint/src/test/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetectorTest.kt
index 15ce6b5..37f46b7 100644
--- a/compose/runtime/runtime-saveable-lint/src/test/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetectorTest.kt
+++ b/compose/runtime/runtime-saveable-lint/src/test/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetectorTest.kt
@@ -42,7 +42,7 @@
     private val rememberSaveableStub: TestFile = bytecodeStub(
         filename = "RememberSaveable.kt",
         filepath = "androidx/compose/runtime/saveable",
-        checksum = 0x90b6d5a7,
+        checksum = 0x7556f44f,
         """
         package androidx.compose.runtime.saveable
 
@@ -81,53 +81,54 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcUlkZiXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbKsTnW1qSmJSTGlySWJLqXcJlzqWIS61ecWJZKkitkFBQam5qblJq
-        UTBUBKiRl4ulJLW4RIjVLT/fu0SJQYsBAFB+NmSMAAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uaSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFeIPzkssKM7ILwkuSSxJ9S7hMudSxKVYrzixLDUxKSdVSCgoNTc1
+        Nym1KBgqAtTIy8VSklpcIsTqlp/vXaLEoMUAALqJaBaNAAAA
         """,
         """
         androidx/compose/runtime/saveable/RememberSaveableKt.class:
-        H4sIAAAAAAAAAM1X3VMbVRT/3WSTbD4aluWjsEVagdiQQBcQvwqiWIuNDbSS
-        iK34MUtYcEmyy+xumPbFQf8Hx/HVF2d86puoMx3GR/8V/wGfHM/dbNJAgqR2
-        plNmcu+55557Pn73nLOXP//57TGAeXzJMK+Z27ZlbD9QS1Z133J01a6ZrlHV
-        VUc70LWtiq6u61W9uqXbBZ9x242AMUh72oGmVjRzV72ztaeXiBskrn1KmuHb
-        9Gb+tOxC/ny7XIO90HK04NqGubuQL1tuxTDVvYOqulMzS65hmY664lMzC5Pt
-        1hh+Wixeb+cvPYtri8XiQraDzqd3eTFLqpYWJmlkSJ1t/4a35h6Q3HjesnfV
-        Pd3dsjWDtGmmablaXfOa5a7VKhWSmvgvKRLxlYUNc7/mOiLiDKMtzhqmq9um
-        VlFzJo/EMUpOBBcYBkpf6aWyb+auZmtVnQQZrqY74NkGx+RGAj2QYkiilyHE
-        YbVF9DEIhmm4IgZOOtEBsQguek4fWGXKsP50hztPYBhKHEO4xNDX4ZoZJrtO
-        QoZgWX/IILfHwnDlvIRkGDpdFRPb+o5Wq7gM3z3n6si1W+tYMFGt5lqeEYZs
-        unuoEphAKoYAXkkghDCn0gzfP/cecKbu1ZrLVReoCnjm//1CN4buwlj02sdS
-        t1HXxRliDl8V6tU31ejoNdeoqMu2rT2kUr9GVVay9h/e2aFy6YRJbrIDM4EZ
-        zMagYo6ht9pi2c+nYrrrq3+axJvHazzdXqce2hUOEbzJ8POLUH/dJSsvqAyP
-        kO7u3hlp2zVePAk65Shd+CLvwkvU89K8US/hnRgEvEvNvUvVEbzH8NcZDj5z
-        EXUf4dNUQ5eynRzimIUM0+SZ3du4/lXd1bY1V6O9QPUgSM8txocQAytzIkD8
-        BwanZojanmWsdHw4FTs+jAWGAt4k0eAvA2KQ1r00Ey0lW9iKQmJKUhbkwK0A
-        H2eCM2xMEI8PJWIoS5KgjMgxWawLzITkBK3CsjDESDDUFJ3rl8KK5GsJi6yu
-        hxRoUkQh3pjoiWWIPTcoiUpCFkmoriU65s1zg2JAirUrmYsRP65wmcRcQrqg
-        NHxJ3or88WM4IPUou2Sk6WHDo7PM9EvSOUZkMpJsDbppqpdDTT2JFRndB652
-        /ZGQG9fa+lHvO/0wvlam77lww9qmJ0lP3jD1tRrfLtafwXLeKmmVDc02+Npn
-        RgvGrqm5NZvoS+t14znzwHAM2l5+8lajh9zp3ear64TYBXK5VF7V9n0DsYJV
-        s0v6isEXw76OjTb9mKW2IoD/hendRB9uWm3QSvP5wxk5cQQ5K/fTOC0P8vFX
-        jDA84smMT7yDFCQSuEd0pn4IcbzkKR1GH0Zpn1OXcYVOcGoALyOI+56GCD6l
-        mXc3keYo/Ta5jECH+KIxxhq0FMUYxonmXq6RuTDNIwNC6OsfEDmiux0QIkSG
-        2GomOzV9hMm6o5/RKCAQFz2XBylSkOkIaYzTKJP+fpo5AhkfgW9o5sGkGghM
-        NxHIZB4f4dXsEd7wLBzjrSdoKOSQTBEOkZERXCQchgiBfnodDbcglGoilMKU
-        j1CqiVDqBELZ/4PQdR+h6z5CvadgWXwCSxAs6rmeBO9LPR4eUZoV/qQjIa5n
-        3HMMiP8O4f4vWD7GjUeewUYGgLyv+/s2HaRPsn+Qz6z9YKDl4LgHTKIuhpsE
-        B3xV79Pvc4/6GF94WcmwQnf0wSaCOdzKIUcjPszhNvI5rGJtE8zBHdzdhOxg
-        wsGog48crDuYd1BwcNOh/zoQ9zh9Di57xICDooOwgykHmX8BaeisIyQPAAA=
+        H4sIAAAAAAAA/81X3VMbVRT/3WSTbD4Ky/JR2GJbgdiQ0C4gfhVEEYvEBlqb
+        iK34tYQtLkl2md0N07441f/BcXztizM+9U3UmQ7jo/+Kf4EvjufubkJKgqR2
+        ptOH3Hvuueeej9895+zNn//89hjAHL5imNPMbdsytu+pZau2Zzm6atdN16jp
+        qqPt69pWVVdv6TW9tqXbxYBx3Y2BMUi72r6mVjVzR72xtauXiRsmrn1MmuG7
+        zGbhuOx84XS7XIM933K06NqGuTNfqFhu1TDV3f2aerdull3DMh11JaCm5yfb
+        rTH8tFC62s5ffBbXFkql+VwHnU/v8kKOVC3OT9LIkD7Z/rK35h6Q3HjBsnfU
+        Xd3dsjWDtGmmabmar3ndctfr1SpJTfyXFIkEyqKGuVd3HRFJhvMtzhqmq9um
+        VlXzJo/EMcpODGcYBstf6+VKYOamZms1nQQZLmU64NkGx+RGCr2QEuhBH0OE
+        w2qL6GcQDNNwRQw+6UQHxGI46zm9b1UowwYyHe48hREoSQzjHEN/h2tmmOw6
+        CRnCFf0+g9weC8PF0xKSYfh4VUxs63e1etVl+P45V0e+3VrHgolrddfyjDDk
+        Mt1DlcIE0gmE8EoKEUQ5lWH44bn3gBN1r9VdrrpIVcAz/+8XuzF0F8eC1z8W
+        uw3bF2dIOHxV9MtvqtHS665RVZdsW7tPtX6Fyqxs7d2/cZfqpRMo+ckOzBSm
+        MZOAilmGvlqL5SChSpmu7/5pMm8Or/F8e52aaFc4xPAmw88vQgF2l628orI8
+        Qrq72yfkbdd48STolKR04Qu8DS9S08vwTr2IdxIQ8C519y5Vx/Aew18nOPjM
+        VdR9hE9TDV3KdnKIYxYxTJNndl/j+td0V9vWXI32QrX9ML23GB/ifAADq3Ai
+        RJv3DE5NE7U9w1j58MFU4vBBIjQc8iaJhmAZEsO07qOZaKmnha0oJKb0yIIc
+        Wg3xcTo8zcYE8fCBRAxlURKUUTkhi77AdERO0SoqC8OMBCNN0dkBKapIgZao
+        yHw9pECTYgrxxkRPLEvs2SFJVFKySEK+lviYN88OiSEp0a5kNkH8pMJlUrMp
+        6YzS8KVnNfbHw2hI6lV2yEjTw4ZHJ5kZkKRTjMhkpKc16KapPg41NSZWYvwm
+        LnX9qZAbd9v6ae8//jy+UqGvurBsbdPDpLdgmPp6nW+X/MewXLDKWnVDsw2+
+        DpjxorFjam7dJvrcLd943tw3HIO2l45ebPScO77bfHs9IXaGXC5X1rS9wECi
+        aNXtsr5i8MVIoGOjTT9mqLcIPEERpdcTfb5p9QmttIA/kpVTB5Bz8gCNl+Uh
+        Pv6KUYZHPJlx2ztIQSKFO0Rn/UNI4iVP6Qj6cZ72OXUBF+kEpwbxMsL41NMQ
+        wybNvMWJvFjo9xmXEehQ3Ksbf0w0aCmOMYwTzb1cJ3NRmkcHhcg3PyJ2QHc7
+        KMSIjLC1bG7q8gEmfUc/p1FAKCl6Lg9RpCDTMdKYpFEm/QM0cwSyAQLf0syD
+        STcQuNxEIJt9fIBXcwd4w7NwiLeO0FDIIZkiHCYjozhLOAwTAgP0RhppQSjd
+        RCiNqQChdBOh9BMI5f4PQlcDhK4GCPUdg2XhCJYwWNxzvQe8L/V6eMRpVvjD
+        joS4nnHPMSD5O4Q7v2DpEMuPPIONDAB57/v7Nh2k73JwkM+s/WCo5eC4B0zK
+        F8M1ggOBqvfp94VHbeBLLysZVuiOPthEOI/VPPJ5fIjreRSwlqdsuLEJ5uAm
+        PtqE7GDCwXkHtxwUHcw5KDm45tB/DyQ9Tr+DCx4x6OBjB1EHUw6y/wIvfIxc
+        Kg8AAA==
         """,
         """
         androidx/compose/runtime/saveable/Saver.class:
-        H4sIAAAAAAAAAI1PTUvDQBB9m/QjjVVT60f9BWIOphZBUBG8CJVKoQEvPW2b
-        tWzbbCS7LT3md3mQnP1R4sTai3pwYd6bffOGmXn/eH0DcIEWwwlXUZrIaBWM
-        k/gl0SJIF8rIWASaLwUfzUUQUpJWwRgebvqpnEjF51e9KV/yYM7VJOiPpmJs
-        rsNv/x+l298Sg/dTq6LE0OjNEjOXKngUhkfccHJa8dKmfVkBZQY2I2kli1+b
-        suicwc+zumu1LNdyKLw8c55beeaXnDzzmO84zLN8q213KIqODsNp75+H03xn
-        czWlmysZ7YPmQMQiHol0o57NDEMtlBPFzSIlkxsmi3Qs7mXRcTxYT3iSWpL5
-        TqnEcCMTpSu0FcpYPxsHhBbx4Rfv44j4kuZVyFMdwu7C6aJGCLeArS7q2B6C
-        aexgd4iShqfR0NjTaH4C2V0QQe0BAAA=
+        H4sIAAAAAAAA/41PTU/CQBB92yKUilrED/gFxh4sEhMTNSZeTGowJDTxwmmB
+        lSzQrekuhGN/lwfTsz/KOBW5qAc3mZm3b95k3rx/vL4BuECL4YSrcZrI8SoY
+        JfFLokWQLpSRsQg0Xwo+nIsgIpBWwBgebnqpnEjF51fdKV/yYM7VJOgNp2Jk
+        rqNv/R+t298Ug/eTq6DEUO/OEjOXKngUho+54aS04qVNflmRqkUCA5sRv5LF
+        r01ofM7g51nNtZqWazkUXp45z80880tOnnnMdxzmWb7VtjsUxUSH4bT7z+vJ
+        hLM5neDmVFY4afRFLOKhSDfs2cwwVCM5UdwsUhK5UbJIR+JeFhOt/nrDk9SS
+        xHdKJYYbmShdJlfYwvrZOKJsUT3+qodoUr2kfWXSVAawQzghqiFcbBNELcQO
+        dgdgGnvwBihp1DX2NRoaB5+QkX6G8gEAAA==
         """
     )
 
@@ -162,7 +163,8 @@
             ),
             rememberSaveableStub,
             Stubs.Composable,
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .run()
             .expect(
@@ -276,7 +278,8 @@
             ),
             rememberSaveableStub,
             Stubs.Composable,
-            Stubs.SnapshotState
+            Stubs.SnapshotState,
+            Stubs.StateFactoryMarker
         )
             .run()
             .expectClean()
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index 0c044c9..b33800b 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -230,8 +230,8 @@
 
   public final class CompositionLocalKt {
     method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.CompositionLocalContext context, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?>![] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?>![] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalOf(optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> defaultFactory);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> staticCompositionLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
   }
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index fbaec58..7a487a5 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -248,8 +248,8 @@
 
   public final class CompositionLocalKt {
     method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.CompositionLocalContext context, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?>![] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?> value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonSkippableComposable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?>![] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalOf(optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> defaultFactory);
     method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> staticCompositionLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
   }
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/state/ComposeStateReadBenchmark.kt b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/state/ComposeStateReadBenchmark.kt
index 44a1a9f..8916a28 100644
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/state/ComposeStateReadBenchmark.kt
+++ b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/state/ComposeStateReadBenchmark.kt
@@ -17,12 +17,14 @@
 package androidx.compose.runtime.benchmark.state
 
 import androidx.benchmark.junit4.BenchmarkRule
-import androidx.benchmark.junit4.measureRepeated
+import androidx.benchmark.junit4.measureRepeatedOnMainThread
 import androidx.compose.runtime.Applier
 import androidx.compose.runtime.Composition
 import androidx.compose.runtime.Recomposer
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.snapshots.Snapshot
+import androidx.compose.runtime.snapshots.SnapshotApplyResult
 import androidx.compose.runtime.snapshots.SnapshotStateObserver
 import androidx.test.filters.LargeTest
 import kotlin.coroutines.CoroutineContext
@@ -138,7 +140,7 @@
         measure: () -> Unit
     ) {
         val benchmarkState = benchmarkRule.getState()
-        benchmarkRule.measureRepeated {
+        benchmarkRule.measureRepeatedOnMainThread {
             benchmarkState.pauseTiming()
             runInReadObservationScope {
                 before()
@@ -157,12 +159,20 @@
         when (readContext) {
             ReadContext.Composition -> createComposition().setContent { scopeBlock() }
             ReadContext.Measure -> {
-                SnapshotStateObserver { it() }.apply {
-                    val nodes = List(MEASURE_OBSERVATION_DEPTH) { Any() }
-                    start()
-                    recursiveObserve(nodes, nodes.size, scopeBlock)
-                    stop()
+                val snapshot = Snapshot.takeMutableSnapshot()
+                snapshot.enter {
+                    SnapshotStateObserver { it() }.apply {
+                        val nodes = List(MEASURE_OBSERVATION_DEPTH) { Any() }
+                        start()
+                        recursiveObserve(nodes, nodes.size, scopeBlock)
+                        stop()
+                    }
                 }
+                val applyResult = snapshot.apply()
+                check(applyResult !is SnapshotApplyResult.Failure) {
+                    "Failed to apply snapshot"
+                }
+                snapshot.dispose()
             }
         }
     }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLocal.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLocal.kt
index 1073e39..4f9cf8c 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLocal.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLocal.kt
@@ -223,6 +223,7 @@
  */
 @Composable
 @OptIn(InternalComposeApi::class)
+@NonSkippableComposable
 fun CompositionLocalProvider(vararg values: ProvidedValue<*>, content: @Composable () -> Unit) {
     currentComposer.startProviders(values)
     content()
@@ -243,6 +244,7 @@
  */
 @Composable
 @OptIn(InternalComposeApi::class)
+@NonSkippableComposable
 fun CompositionLocalProvider(value: ProvidedValue<*>, content: @Composable () -> Unit) {
     currentComposer.startProvider(value)
     content()
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateList.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateList.kt
index c339e9d..ec16338 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateList.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateList.kt
@@ -101,6 +101,10 @@
         }
         return SubList(this, fromIndex, toIndex)
     }
+    @Suppress("UNCHECKED_CAST")
+    override fun toString(): String = (firstStateRecord as StateListStateRecord<T>).withCurrent {
+        "SnapshotStateList(value=${it.list})@${hashCode()}"
+    }
 
     override fun add(element: T) = conditionalUpdate { it.add(element) }
     override fun add(index: Int, element: T) = update { it.add(index, element) }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMap.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMap.kt
index 9b77e7ce..94290eb 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMap.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMap.kt
@@ -65,6 +65,10 @@
     override val entries: MutableSet<MutableMap.MutableEntry<K, V>> = SnapshotMapEntrySet(this)
     override val keys: MutableSet<K> = SnapshotMapKeySet(this)
     override val values: MutableCollection<V> = SnapshotMapValueSet(this)
+    @Suppress("UNCHECKED_CAST")
+    override fun toString(): String = (firstStateRecord as StateMapStateRecord<K, V>).withCurrent {
+        "SnapshotStateMap(value=${it.map})@${hashCode()}"
+    }
 
     override fun clear() = update { persistentHashMapOf() }
     override fun put(key: K, value: V): V? = mutate { it.put(key, value) }
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionTests.kt
index ee5f19f..cce19c1 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionTests.kt
@@ -62,6 +62,7 @@
 import kotlinx.coroutines.channels.consumeEach
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -3947,6 +3948,74 @@
         expectChanges()
     }
 
+    data class Foo(var i: Int = 0)
+    class UnstableCompConsumer(var invokeCount: Int = 0) {
+        @Composable fun UnstableComp(foo: Foo) {
+            use(foo)
+            invokeCount++
+        }
+    }
+    @Test
+    fun composableWithUnstableParameters_skipped() = compositionTest {
+        val consumer = UnstableCompConsumer()
+        var recomposeTrigger by mutableStateOf(0)
+        val data = Foo()
+        compose {
+            Linear {
+                use(recomposeTrigger)
+                consumer.UnstableComp(foo = data)
+            }
+        }
+
+        assertEquals(1, consumer.invokeCount)
+
+        recomposeTrigger = 1
+        data.i++
+        advance()
+
+        assertEquals(1, consumer.invokeCount)
+    }
+
+    // regression test from b/232007227 with forEach
+    @Test
+    fun slotsAreUsedCorrectly_forEach() = compositionTest {
+        class Car(val model: String)
+        class Person(val name: String, val car: MutableStateFlow<Car>)
+
+        val people = mutableListOf<MutableStateFlow<Person?>>(
+            MutableStateFlow(Person("Ford", MutableStateFlow(Car("Model T")))),
+            MutableStateFlow(Person("Musk", MutableStateFlow(Car("Model 3"))))
+        )
+        compose {
+            people.forEach {
+                val person = it.collectAsState().value
+                Text(person?.name ?: "No person")
+                if (person != null) {
+                    val car = person.car.collectAsState().value
+                    Text("    ${car.model}")
+                }
+            }
+        }
+
+        validate {
+            people.forEach {
+                val person = it.value
+                Text(person?.name ?: "No person")
+                if (person != null) {
+                    val car = person.car.value
+                    Text("    ${car.model}")
+                }
+            }
+        }
+
+        advanceTimeBy(16_000L)
+        people[0].value = null
+        advanceTimeBy(16_000L)
+
+        expectChanges()
+        revalidate()
+    }
+
     private inline fun CoroutineScope.withGlobalSnapshotManager(block: CoroutineScope.() -> Unit) {
         val channel = Channel<Unit>(Channel.CONFLATED)
         val job = launch {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt
index bc3a3d5..7c0249d 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt
@@ -584,6 +584,7 @@
 }
 
 @Composable
+@NonSkippableComposable
 private fun RecomposeTestComponentsA(counter: Counter, triggers: Map<Int, Trigger>) {
     counter.inc("A")
     triggers[99]?.subscribe()
@@ -600,6 +601,7 @@
     }
 }
 
+@NonSkippableComposable
 @Composable
 private fun RecomposeTestComponentsB(
     counter: Counter,
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ComposeContact.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ComposeContact.kt
index d85c2d3..494fc5c 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ComposeContact.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ComposeContact.kt
@@ -17,6 +17,7 @@
 package androidx.compose.runtime.mock
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.NonSkippableComposable
 
 // <linear>
 //  <text text="Name: ${contact.name}" />
@@ -79,6 +80,7 @@
 // </linear>
 @Suppress("ComposableNaming")
 @Composable
+@NonSkippableComposable
 fun SelectContact(model: ContactModel) {
     Linear {
         Linear {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ContactModel.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ContactModel.kt
index 4848929..2e2bbf3 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ContactModel.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/ContactModel.kt
@@ -18,31 +18,36 @@
 
 class ContactModel(
     var filter: String = "",
-    val contacts: MutableList<Contact>,
+    var contacts: List<Contact>,
     var selected: Contact? = null
 ) {
     val filtered get() = contacts.filter { it.name.contains(filter) }
 
     fun add(contact: Contact, after: Contact? = null) {
+        val retList = mutableListOf<Contact>().apply { addAll(contacts) }
         if (after == null) {
-            contacts.add(contact)
+            retList.add(contact)
         } else {
-            contacts.add(find(after) + 1, contact)
+            retList.add(find(retList, after) + 1, contact)
         }
+
+        contacts = retList
     }
 
     fun move(contact: Contact, after: Contact?) {
+        val retList = mutableListOf<Contact>().apply { addAll(contacts) }
         if (after == null) {
-            contacts.removeAt(find(contact))
-            contacts.add(0, contact)
+            retList.removeAt(find(retList, contact))
+            retList.add(0, contact)
         } else {
-            contacts.removeAt(find(contact))
-            contacts.add(find(after) + 1, contact)
+            retList.removeAt(find(retList, contact))
+            retList.add(find(retList, after) + 1, contact)
         }
+        contacts = retList
     }
 
-    private fun find(contact: Contact): Int {
-        val index = contacts.indexOf(contact)
+    private fun find(list: List<Contact>, contact: Contact): Int {
+        val index = list.indexOf(contact)
         if (index < 0) error("Contact $contact not found")
         return index
     }
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt
index c5727ac..9d6add5 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt
@@ -798,6 +798,28 @@
         }
     }
 
+    @Test
+    fun toStringOfSnapshotStateListDoesNotTriggerReadObserver() {
+        val state = mutableStateListOf<Int>(0)
+        val normalReads = readsOf {
+            state.readable
+        }
+        assertEquals(1, normalReads)
+        val toStringReads = readsOf {
+            state.toString()
+        }
+        assertEquals(0, toStringReads)
+    }
+
+    @Test
+    fun testValueOfStateListToString() {
+        val state = mutableStateListOf(0, 1, 2)
+        assertEquals(
+            "SnapshotStateList(value=[0, 1, 2])@${state.hashCode()}",
+            state.toString()
+        )
+    }
+
     private fun <T> validate(list: MutableList<T>, block: (list: MutableList<T>) -> Unit) {
         val normalList = list.toMutableList()
         block(normalList)
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt
index 8cd5fb0..c5a809f 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt
@@ -634,6 +634,28 @@
         // Should only get here if the above doesn't deadlock.
     }
 
+    @Test
+    fun toStringOfSnapshotStateMapDoesNotTriggerReadObserver() {
+        val state = mutableStateMapOf(0 to 0)
+        val normalReads = readsOf {
+            state.readable
+        }
+        assertEquals(1, normalReads)
+        val toStringReads = readsOf {
+            state.toString()
+        }
+        assertEquals(0, toStringReads)
+    }
+
+    @Test
+    fun testValueOfStateMapToString() {
+        val state = mutableStateMapOf(0 to 0, 1 to 1)
+        assertEquals(
+            "SnapshotStateMap(value={0=0, 1=1})@${state.hashCode()}",
+            state.toString()
+        )
+    }
+
     private fun validateRead(
         initialMap: MutableMap<Int, Float> = defaultMap(),
         block: (Map<Int, Float>, Map<Int, Float>) -> Unit
diff --git a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt
index 20af49c..9f026f5 100644
--- a/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt
+++ b/compose/ui/ui-geometry/src/commonMain/kotlin/androidx/compose/ui/geometry/Offset.kt
@@ -64,8 +64,8 @@
     val x: Float
         get() {
             // Explicitly compare against packed values to avoid auto-boxing of Size.Unspecified
-            if (packedValue == UnspecifiedPackedFloats) {
-                throwIllegalStateException("Offset is unspecified")
+            checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+                "Offset is unspecified"
             }
             return unpackFloat1(packedValue)
         }
@@ -74,8 +74,8 @@
     val y: Float
         get() {
             // Explicitly compare against packed values to avoid auto-boxing of Size.Unspecified
-            if (packedValue == UnspecifiedPackedFloats) {
-                throwIllegalStateException("Offset is unspecified")
+            checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+                "Offset is unspecified"
             }
             return unpackFloat2(packedValue)
         }
@@ -124,12 +124,10 @@
 
     @Stable
     fun isValid(): Boolean {
-        val x = (packedValue shr 32) and FloatNonFiniteMask
-        // Only check y if x didn't fail
-        if (x > FloatInfinityBase || (packedValue and FloatNonFiniteMask) > FloatInfinityBase) {
-            throwIllegalStateException("Offset argument contained a NaN value.")
-        }
-        return true
+        val convertX = (packedValue shr 32) and FloatNonFiniteMask
+        val convertY = packedValue and FloatNonFiniteMask
+
+        return (convertX <= FloatInfinityBase) && (convertY <= FloatInfinityBase)
     }
 
     /**
@@ -140,8 +138,8 @@
      */
     @Stable
     fun getDistance(): Float {
-        if (packedValue == UnspecifiedPackedFloats) {
-            throwIllegalStateException("Offset is unspecified")
+        checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+            "Offset is unspecified"
         }
         val x = unpackFloat1(packedValue)
         val y = unpackFloat2(packedValue)
@@ -155,8 +153,8 @@
      */
     @Stable
     fun getDistanceSquared(): Float {
-        if (packedValue == UnspecifiedPackedFloats) {
-            throwIllegalStateException("Offset is unspecified")
+        checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+            "Offset is unspecified"
         }
         val x = unpackFloat1(packedValue)
         val y = unpackFloat2(packedValue)
@@ -173,8 +171,8 @@
      */
     @Stable
     operator fun unaryMinus(): Offset {
-        if (packedValue == UnspecifiedPackedFloats) {
-            throwIllegalStateException("Offset is unspecified")
+        checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+            "Offset is unspecified"
         }
         return Offset(-unpackFloat1(packedValue), -unpackFloat2(packedValue))
     }
@@ -188,11 +186,11 @@
      */
     @Stable
     operator fun minus(other: Offset): Offset {
-        if (
-            packedValue == UnspecifiedPackedFloats ||
-            other.packedValue == UnspecifiedPackedFloats
+        checkPrecondition(
+            packedValue != UnspecifiedPackedFloats &&
+            other.packedValue != UnspecifiedPackedFloats
         ) {
-            throwIllegalStateException("Offset is unspecified")
+            "Offset is unspecified"
         }
         return Offset(
             unpackFloat1(packedValue) - unpackFloat1(other.packedValue),
@@ -209,11 +207,11 @@
      */
     @Stable
     operator fun plus(other: Offset): Offset {
-        if (
-            packedValue == UnspecifiedPackedFloats ||
-            other.packedValue == UnspecifiedPackedFloats
+        checkPrecondition(
+            packedValue != UnspecifiedPackedFloats &&
+            other.packedValue != UnspecifiedPackedFloats
         ) {
-            throwIllegalStateException("Offset is unspecified")
+            "Offset is unspecified"
         }
         return Offset(
             unpackFloat1(packedValue) + unpackFloat1(other.packedValue),
@@ -230,8 +228,8 @@
      */
     @Stable
     operator fun times(operand: Float): Offset {
-        if (packedValue == UnspecifiedPackedFloats) {
-            throwIllegalStateException("Offset is unspecified")
+        checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+            "Offset is unspecified"
         }
         return Offset(
             unpackFloat1(packedValue) * operand,
@@ -248,8 +246,8 @@
      */
     @Stable
     operator fun div(operand: Float): Offset {
-        if (packedValue == UnspecifiedPackedFloats) {
-            throwIllegalStateException("Offset is unspecified")
+        checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+            "Offset is unspecified"
         }
         return Offset(
             unpackFloat1(packedValue) / operand,
@@ -266,8 +264,8 @@
      */
     @Stable
     operator fun rem(operand: Float): Offset {
-        if (packedValue == UnspecifiedPackedFloats) {
-            throwIllegalStateException("Offset is unspecified")
+        checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+            "Offset is unspecified"
         }
         return Offset(
             unpackFloat1(packedValue) % operand,
@@ -301,11 +299,11 @@
  */
 @Stable
 fun lerp(start: Offset, stop: Offset, fraction: Float): Offset {
-    if (
-        start.packedValue == UnspecifiedPackedFloats ||
-        stop.packedValue == UnspecifiedPackedFloats
+    checkPrecondition(
+        start.packedValue != UnspecifiedPackedFloats &&
+        stop.packedValue != UnspecifiedPackedFloats
     ) {
-        throwIllegalStateException("Offset is unspecified")
+        "Offset is unspecified"
     }
     return Offset(
         lerp(unpackFloat1(start.packedValue), unpackFloat1(stop.packedValue), fraction),
@@ -318,8 +316,8 @@
  */
 @Stable
 val Offset.isFinite: Boolean get() {
-    if (packedValue == UnspecifiedPackedFloats) {
-        throwIllegalStateException("Offset is unspecified")
+    checkPrecondition(packedValue != UnspecifiedPackedFloats) {
+        "Offset is unspecified"
     }
     val x = (packedValue shr 32) and FloatInfinityBase
     val y = packedValue and FloatInfinityBase
diff --git a/compose/ui/ui-graphics/api/restricted_current.txt b/compose/ui/ui-graphics/api/restricted_current.txt
index c4ca8f3..8595a42 100644
--- a/compose/ui/ui-graphics/api/restricted_current.txt
+++ b/compose/ui/ui-graphics/api/restricted_current.txt
@@ -440,6 +440,7 @@
     method @androidx.compose.runtime.Stable public static float luminance(long);
     method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.graphics.Color> block);
     method @ColorInt @androidx.compose.runtime.Stable public static int toArgb(long);
+    field @kotlin.PublishedApi internal static final long UnspecifiedColor = 16L; // 0x10L
   }
 
   @kotlin.jvm.JvmInline public final value class ColorMatrix {
diff --git a/compose/ui/ui-graphics/benchmark/src/androidTest/java/androidx/compose/ui/graphics/benchmark/ColorBenchmark.kt b/compose/ui/ui-graphics/benchmark/src/androidTest/java/androidx/compose/ui/graphics/benchmark/ColorBenchmark.kt
new file mode 100644
index 0000000..84a8a27
--- /dev/null
+++ b/compose/ui/ui-graphics/benchmark/src/androidTest/java/androidx/compose/ui/graphics/benchmark/ColorBenchmark.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 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.compose.ui.graphics.benchmark
+
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.benchmark.junit4.measureRepeated
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.compose.ui.graphics.lerp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class ColorBenchmark {
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+
+    @Test
+    fun colorLerp() {
+        benchmarkRule.measureRepeated {
+            for (i in 0..500) {
+                lerp(Color.Red, Color.Green, i / 500.0f)
+            }
+        }
+    }
+
+    @Test
+    fun wideColorLerp() {
+        val start = Color(1.0f, 0.0f, 0.0f, 1.0f, ColorSpaces.DisplayP3)
+        val end = Color(0.0f, 1.0f, 0.0f, 1.0f, ColorSpaces.DisplayP3)
+        benchmarkRule.measureRepeated {
+            for (i in 0..500) {
+                lerp(start, end, i / 500.0f)
+            }
+        }
+    }
+}
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
index 51b9f61e..d65109d 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
@@ -27,6 +27,7 @@
 import androidx.compose.ui.graphics.colorspace.ColorSpaces
 import androidx.compose.ui.graphics.colorspace.Rgb
 import androidx.compose.ui.graphics.colorspace.connect
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.lerp
 import kotlin.math.max
 import kotlin.math.min
@@ -162,8 +163,7 @@
             return if ((value and 0x3fUL) == 0UL) {
                 ((value shr 48) and 0xffUL).toFloat() / 255.0f
             } else {
-                Float16(((value shr 48) and 0xffffUL).toShort())
-                    .toFloat()
+                halfToFloat(((value shr 48) and 0xffffUL).toShort())
             }
         }
 
@@ -185,8 +185,7 @@
             return if ((value and 0x3fUL) == 0UL) {
                 ((value shr 40) and 0xffUL).toFloat() / 255.0f
             } else {
-                Float16(((value shr 32) and 0xffffUL).toShort())
-                    .toFloat()
+                halfToFloat(((value shr 32) and 0xffffUL).toShort())
             }
         }
 
@@ -208,8 +207,7 @@
             return if ((value and 0x3fUL) == 0UL) {
                 ((value shr 32) and 0xffUL).toFloat() / 255.0f
             } else {
-                Float16(((value shr 16) and 0xffffUL).toShort())
-                    .toFloat()
+                halfToFloat(((value shr 16) and 0xffffUL).toShort())
             }
         }
 
@@ -393,9 +391,13 @@
     }
 }
 
+// Same as Color.Unspecified.packedValue, but avoids a getstatic
+@PublishedApi
+internal const val UnspecifiedColor = 0x10UL
+
 /**
  * Create a [Color] by passing individual [red], [green], [blue], [alpha], and [colorSpace]
- * components. The default [color space][ColorSpace] is [SRGB][ColorSpaces.Srgb] and
+ * components. The default [color space][ColorSpace] is [sRGB][ColorSpaces.Srgb] and
  * the default [alpha] is `1.0` (opaque). [colorSpace] must have a [ColorSpace.componentCount] of
  * 3.
  */
@@ -407,7 +409,7 @@
     alpha: Float = 1f,
     colorSpace: ColorSpace = ColorSpaces.Srgb
 ): Color {
-    require(
+    requirePrecondition(
         red in colorSpace.getMinValue(0)..colorSpace.getMaxValue(0) &&
             green in colorSpace.getMinValue(1)..colorSpace.getMaxValue(1) &&
             blue in colorSpace.getMinValue(2)..colorSpace.getMaxValue(2) &&
@@ -419,41 +421,79 @@
     if (colorSpace.isSrgb) {
         val argb = (
             ((alpha * 255.0f + 0.5f).toInt() shl 24) or
-                ((red * 255.0f + 0.5f).toInt() shl 16) or
-                ((green * 255.0f + 0.5f).toInt() shl 8) or
-                (blue * 255.0f + 0.5f).toInt()
-            )
-        return Color(value = (argb.toULong() and 0xffffffffUL) shl 32)
+            ((red * 255.0f + 0.5f).toInt() shl 16) or
+            ((green * 255.0f + 0.5f).toInt() shl 8) or
+            (blue * 255.0f + 0.5f).toInt()
+        )
+        return Color(argb.toULong() shl 32)
     }
 
-    require(colorSpace.componentCount == 3) {
+    requirePrecondition(colorSpace.componentCount == 3) {
         "Color only works with ColorSpaces with 3 components"
     }
 
     val id = colorSpace.id
-    require(id != ColorSpace.MinId) {
+    requirePrecondition(id != ColorSpace.MinId) {
         "Unknown color space, please use a color space in ColorSpaces"
     }
 
-    val r = Float16(red)
-    val g = Float16(green)
-    val b = Float16(blue)
+    val r = floatToHalf(red)
+    val g = floatToHalf(green)
+    val b = floatToHalf(blue)
 
     val a = (max(0.0f, min(alpha, 1.0f)) * 1023.0f + 0.5f).toInt()
 
-    // Suppress sign extension
     return Color(
-        value = (
-            ((r.halfValue.toULong() and 0xffffUL) shl 48) or (
-                (g.halfValue.toULong() and 0xffffUL) shl 32
-                ) or (
-                (b.halfValue.toULong() and 0xffffUL) shl 16
-                ) or (
-                (a.toULong() and 0x3ffUL) shl 6
-                ) or (
-                id.toULong() and 0x3fUL
-                )
-            )
+        (
+            ((r.toLong() and 0xffffL) shl 48) or
+            ((g.toLong() and 0xffffL) shl 32) or
+            ((b.toLong() and 0xffffL) shl 16) or
+            ((a.toLong() and 0x03ffL) shl 6) or
+            (id.toLong() and 0x003fL)
+        ).toULong()
+    )
+}
+
+/**
+ * Create a [Color] by passing individual [red], [green], [blue], [alpha], and [colorSpace]
+ * components. This function is equivalent to [Color] but doesn't perform any check/validation
+ * of the parameters. It is meant to be used when the color space and values are known to
+ * be valid by construction, for instance when lerping colors.
+ */
+@Stable
+internal fun UncheckedColor(
+    red: Float,
+    green: Float,
+    blue: Float,
+    alpha: Float = 1f,
+    colorSpace: ColorSpace = ColorSpaces.Srgb
+): Color {
+    if (colorSpace.isSrgb) {
+        val argb = (
+            ((alpha * 255.0f + 0.5f).toInt() shl 24) or
+            ((red * 255.0f + 0.5f).toInt() shl 16) or
+            ((green * 255.0f + 0.5f).toInt() shl 8) or
+            (blue * 255.0f + 0.5f).toInt()
+        )
+        return Color(argb.toULong() shl 32)
+    }
+
+    val r = floatToHalf(red)
+    val g = floatToHalf(green)
+    val b = floatToHalf(blue)
+
+    val a = (max(0.0f, min(alpha, 1.0f)) * 1023.0f + 0.5f).toInt()
+
+    val id = colorSpace.id
+
+    return Color(
+        (
+            ((r.toLong() and 0xffffL) shl 48) or
+            ((g.toLong() and 0xffffL) shl 32) or
+            ((b.toLong() and 0xffffL) shl 16) or
+            ((a.toLong() and 0x03ffL) shl 6) or
+            (id.toLong() and 0x003fL)
+        ).toULong()
     )
 }
 
@@ -467,7 +507,7 @@
  */
 @Stable
 fun Color(@ColorInt color: Int): Color {
-    return Color(value = color.toULong() shl 32)
+    return Color(color.toULong() shl 32)
 }
 
 /**
@@ -484,7 +524,7 @@
  */
 @Stable
 fun Color(color: Long): Color {
-    return Color(value = (color.toULong() and 0xffffffffUL) shl 32)
+    return Color((color shl 32).toULong())
 }
 
 /**
@@ -506,7 +546,8 @@
     @IntRange(from = 0, to = 0xFF) blue: Int,
     @IntRange(from = 0, to = 0xFF) alpha: Int = 0xFF
 ): Color {
-    val color = ((alpha and 0xFF) shl 24) or
+    val color =
+        ((alpha and 0xFF) shl 24) or
         ((red and 0xFF) shl 16) or
         ((green and 0xFF) shl 8) or
         (blue and 0xFF)
@@ -535,12 +576,12 @@
     val endA = endColor.green
     val endB = endColor.blue
 
-    val interpolated = Color(
-        alpha = lerp(startAlpha, endAlpha, fraction),
-        red = lerp(startL, endL, fraction),
-        green = lerp(startA, endA, fraction),
-        blue = lerp(startB, endB, fraction),
-        colorSpace = colorSpace
+    val interpolated = UncheckedColor(
+        lerp(startL, endL, fraction),
+        lerp(startA, endA, fraction),
+        lerp(startB, endB, fraction),
+        lerp(startAlpha, endAlpha, fraction),
+        colorSpace
     )
     return interpolated.convert(stop.colorSpace)
 }
@@ -568,7 +609,7 @@
     val g = compositeComponent(fg.green, background.green, fgA, bgA, a)
     val b = compositeComponent(fg.blue, background.blue, fgA, bgA, a)
 
-    return Color(r, g, b, a, background.colorSpace)
+    return UncheckedColor(r, g, b, a, background.colorSpace)
 }
 
 /**
@@ -609,7 +650,7 @@
 @Stable
 fun Color.luminance(): Float {
     val colorSpace = colorSpace
-    require(colorSpace.model == ColorModel.Rgb) {
+    requirePrecondition(colorSpace.model == ColorModel.Rgb) {
         "The specified color must be encoded in an RGB color space. " +
             "The supplied color space is ${colorSpace.model}"
     }
@@ -619,11 +660,7 @@
     val g = eotf(green.toDouble())
     val b = eotf(blue.toDouble())
 
-    return saturate(((0.2126 * r) + (0.7152 * g) + (0.0722 * b)).toFloat())
-}
-
-private fun saturate(v: Float): Float {
-    return if (v <= 0.0f) 0.0f else (if (v >= 1.0f) 1.0f else v)
+    return (((0.2126 * r) + (0.7152 * g) + (0.0722 * b)).toFloat()).fastCoerceIn(0.0f, 1.0f)
 }
 
 /**
@@ -643,13 +680,13 @@
  * `false` when this is [Color.Unspecified].
  */
 @Stable
-inline val Color.isSpecified: Boolean get() = value != Color.Unspecified.value
+inline val Color.isSpecified: Boolean get() = value != UnspecifiedColor
 
 /**
  * `true` when this is [Color.Unspecified].
  */
 @Stable
-inline val Color.isUnspecified: Boolean get() = value == Color.Unspecified.value
+inline val Color.isUnspecified: Boolean get() = value == UnspecifiedColor
 
 /**
  * If this color [isSpecified] then this is returned, otherwise [block] is executed and its result
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Float16.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Float16.kt
index 130b258..8aabeca6 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Float16.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Float16.kt
@@ -85,7 +85,7 @@
  *
  * This table shows that numbers higher than 1024 lose all fractional precision.
  */
[email protected]
+@JvmInline
 internal value class Float16(val halfValue: Short) : Comparable<Float16> {
 
     /**
@@ -94,11 +94,7 @@
      *
      * @param value The value to be represented by the `Float16`
      */
-    constructor(value: Float) : this(
-        floatToHalf(
-            value
-        )
-    )
+    constructor(value: Float) : this(floatToHalf(value))
 
     /**
      * Constructs a newly allocated `Float16` object that
@@ -115,9 +111,7 @@
      * @return The half-precision float value represented by this object
      * converted to type `Byte`
      */
-    fun toByte(): Byte {
-        return toFloat().toInt().toByte()
-    }
+    fun toByte(): Byte = toFloat().toInt().toByte()
 
     /**
      * Returns the value of this `Float16` as a `Short` after
@@ -126,9 +120,7 @@
      * @return The half-precision float value represented by this object
      * converted to type `Short`
      */
-    fun toShort(): Short {
-        return toFloat().toInt().toShort()
-    }
+    fun toShort(): Short = toFloat().toInt().toShort()
 
     /**
      * Returns the value of this `Float16` as a `Int` after
@@ -137,9 +129,7 @@
      * @return The half-precision float value represented by this object
      * converted to type `Int`
      */
-    fun toInt(): Int {
-        return toFloat().toInt()
-    }
+    fun toInt(): Int = toFloat().toInt()
 
     /**
      * Returns the value of this `Float16` as a `Long` after
@@ -148,9 +138,7 @@
      * @return The half-precision float value represented by this object
      * converted to type `Long`
      */
-    fun toLong(): Long {
-        return toFloat().toLong()
-    }
+    fun toLong(): Long = toFloat().toLong()
 
     /**
      * Returns the value of this `Float16` as a `Float` after
@@ -161,9 +149,9 @@
      */
     fun toFloat(): Float {
         val bits = halfValue.toInt() and 0xffff
-        val s = bits and FP16_SIGN_MASK
-        val e = bits.ushr(FP16_EXPONENT_SHIFT) and FP16_EXPONENT_MASK
-        val m = bits and FP16_SIGNIFICAND_MASK
+        val s = bits and Fp16SignMask
+        val e = bits.ushr(Fp16ExponentShift) and Fp16ExponentMask
+        val m = bits and Fp16SignificandMask
 
         var outE = 0
         var outM = 0
@@ -171,8 +159,8 @@
         if (e == 0) { // Denormal or 0
             if (m != 0) {
                 // Convert denorm fp16 into normalized fp32
-                var o = floatFromBits(FP32_DENORMAL_MAGIC + m)
-                o -= FP32_DENORMAL_FLOAT
+                var o = floatFromBits(Fp32DenormalMagic + m)
+                o -= Fp32DenormalFloat
                 return if (s == 0) o else -o
             }
         } else {
@@ -180,14 +168,14 @@
             if (e == 0x1f) { // Infinite or NaN
                 outE = 0xff
                 if (outM != 0) { // SNaNs are quieted
-                    outM = outM or FP32_QNAN_MASK
+                    outM = outM or Fp32QNaNMask
                 }
             } else {
-                outE = e - FP16_EXPONENT_BIAS + FP32_EXPONENT_BIAS
+                outE = e - Fp16ExponentBias + Fp32ExponentBias
             }
         }
 
-        val out = s shl 16 or (outE shl FP32_EXPONENT_SHIFT) or outM
+        val out = s shl 16 or (outE shl Fp32ExponentShift) or outM
         return floatFromBits(out)
     }
 
@@ -198,9 +186,7 @@
      * @return The half-precision float value represented by this object
      * converted to type `Double`
      */
-    fun toDouble(): Double {
-        return toFloat().toDouble()
-    }
+    fun toDouble(): Double = toFloat().toDouble()
 
     /**
      * Returns a representation of the half-precision float value
@@ -212,12 +198,10 @@
      *
      * @return The bits that represent the half-precision float value
      */
-    fun toBits(): Int {
-        return if (isNaN()) {
-            NaN.halfValue.toInt()
-        } else {
-            halfValue.toInt() and 0xffff
-        }
+    fun toBits(): Int = if (isNaN()) {
+        NaN.halfValue.toInt()
+    } else {
+        halfValue.toInt() and 0xffff
     }
 
     /**
@@ -226,9 +210,7 @@
      *
      * @return The bits that represent the half-precision float value
      */
-    fun toRawBits(): Int {
-        return halfValue.toInt() and 0xffff
-    }
+    fun toRawBits(): Int = halfValue.toInt() and 0xffff
 
     /**
      * Returns a string representation of the specified half-precision
@@ -236,26 +218,24 @@
      *
      * @return A string representation of this `Float16` object
      */
-    override fun toString(): String {
-        return toFloat().toString()
-    }
+    override fun toString(): String = toFloat().toString()
 
     /**
      * Compares to another half-precision float value. The following
      * conditions apply during the comparison:
      *
      *  * [NaN] is considered by this method to be equal to itself and greater
-     * than all other half-precision float values (including `#PositiveInfinity`)
+     * than all other half-precision float values (including [PositiveInfinity])
      *  * [PositiveZero] is considered by this method to be greater than
      * [NegativeZero].
      *
      * @param other The half-precision float value to compare to the half-precision value
      * represented by this `Float16` object
      *
-     * @return The value `0` if `this` is numerically equal to `h`; a
-     * value less than `0` if `this` is numerically less than `h`;
+     * @return The value `0` if `this` is numerically equal to [other]; a
+     * value less than `0` if `this` is numerically less than [other];
      * and a value greater than `0` if `this` is numerically greater
-     * than `h`
+     * than [other]
      */
     override operator fun compareTo(other: Float16): Int {
         if (isNaN()) {
@@ -263,9 +243,7 @@
         } else if (other.isNaN()) {
             return -1
         }
-        return toCompareValue(halfValue).compareTo(
-            toCompareValue(other.halfValue)
-        )
+        return toCompareValue(halfValue).compareTo(toCompareValue(other.halfValue))
     }
 
     /**
@@ -278,15 +256,11 @@
      * * `NaN.sign` is `NaN`
      */
     val sign: Float16
-        get() {
-            if (isNaN()) {
-                return NaN
-            }
-            when {
-                this < NegativeZero -> return NegativeOne
-                this > PositiveZero -> return One
-                else -> return this // this is zero, either positive or negative
-            }
+        get() = when {
+            isNaN() -> NaN
+            this < NegativeZero -> NegativeOne
+            this > PositiveZero -> One
+            else -> this // this is zero, either positive or negative
         }
 
     /**
@@ -295,9 +269,9 @@
     fun withSign(sign: Float16): Float16 =
         Float16(
             (
-                sign.halfValue.toInt() and FP16_SIGN_MASK or
-                    (halfValue.toInt() and FP16_COMBINED)
-                ).toShort()
+                sign.halfValue.toInt() and Fp16SignMask or
+                    (halfValue.toInt() and Fp16Combined)
+            ).toShort()
         )
 
     /**
@@ -311,7 +285,7 @@
      * the result is positive infinity (see [PositiveInfinity])
      */
     fun absoluteValue(): Float16 {
-        return Float16((halfValue.toInt() and FP16_COMBINED).toShort())
+        return Float16((halfValue.toInt() and Fp16Combined).toShort())
     }
 
     /**
@@ -334,7 +308,7 @@
         var result = bits
 
         if (e < 0x3c00) {
-            result = result and FP16_SIGN_MASK
+            result = result and Fp16SignMask
             result = result or (0x3c00 and if (e >= 0x3800) 0xffff else 0x0)
         } else if (e < 0x6400) {
             e = 25 - (e shr 10)
@@ -366,7 +340,7 @@
         var result = bits
 
         if (e < 0x3c00) {
-            result = result and FP16_SIGN_MASK
+            result = result and Fp16SignMask
             result = result or (0x3c00 and -((bits shr 15).inv() and if (e != 0) 1 else 0))
         } else if (e < 0x6400) {
             e = 25 - (e shr 10)
@@ -398,7 +372,7 @@
         var result = bits
 
         if (e < 0x3c00) {
-            result = result and FP16_SIGN_MASK
+            result = result and Fp16SignMask
             result = result or (0x3c00 and if (bits > 0x8000) 0xffff else 0x0)
         } else if (e < 0x6400) {
             e = 25 - (e shr 10)
@@ -429,7 +403,7 @@
         var result = bits
 
         if (e < 0x3c00) {
-            result = result and FP16_SIGN_MASK
+            result = result and Fp16SignMask
         } else if (e < 0x6400) {
             e = 25 - (e shr 10)
             val mask = (1 shl e) - 1
@@ -447,19 +421,15 @@
      * returns [MinExponent] - 1.
      */
     val exponent: Int
-        get() {
-            return (halfValue.toInt().ushr(FP16_EXPONENT_SHIFT) and FP16_EXPONENT_MASK) -
-                FP16_EXPONENT_BIAS
-        }
+        get() = (halfValue.toInt().ushr(Fp16ExponentShift) and Fp16ExponentMask) -
+            Fp16ExponentBias
 
     /**
      * The significand, or mantissa, used in the representation
      * of this half-precision float value.
      */
     val significand: Int
-        get() {
-            return halfValue.toInt() and FP16_SIGNIFICAND_MASK
-        }
+        get() = halfValue.toInt() and Fp16SignificandMask
 
     /**
      * Returns true if this `Float16` value represents a Not-a-Number,
@@ -467,9 +437,7 @@
      *
      * @return True if the value is a NaN, false otherwise
      */
-    fun isNaN(): Boolean {
-        return halfValue.toInt() and FP16_COMBINED > FP16_EXPONENT_MAX
-    }
+    fun isNaN(): Boolean = halfValue.toInt() and Fp16Combined > Fp16ExponentMax
 
     /**
      * Returns true if the half-precision float value represents
@@ -478,9 +446,7 @@
      * @return True if the value is positive infinity or negative infinity,
      * false otherwise
      */
-    fun isInfinite(): Boolean {
-        return halfValue.toInt() and FP16_COMBINED == FP16_EXPONENT_MAX
-    }
+    fun isInfinite(): Boolean = halfValue.toInt() and Fp16Combined == Fp16ExponentMax
 
     /**
      * Returns false if the half-precision float value represents
@@ -489,9 +455,7 @@
      * @return False if the value is positive infinity or negative infinity,
      * true otherwise
      */
-    fun isFinite(): Boolean {
-        return halfValue.toInt() and FP16_COMBINED != FP16_EXPONENT_MAX
-    }
+    fun isFinite(): Boolean = halfValue.toInt() and Fp16Combined != Fp16ExponentMax
 
     /**
      * Returns true if the half-precision float value is normalized
@@ -503,8 +467,8 @@
      * @return True if the value is normalized, false otherwise
      */
     fun isNormalized(): Boolean {
-        return halfValue.toInt() and FP16_EXPONENT_MAX != 0 &&
-            halfValue.toInt() and FP16_EXPONENT_MAX != FP16_EXPONENT_MAX
+        return halfValue.toInt() and Fp16ExponentMax != 0 &&
+            halfValue.toInt() and Fp16ExponentMax != Fp16ExponentMax
     }
 
     /**
@@ -536,9 +500,9 @@
         val o = StringBuilder()
 
         val bits = halfValue.toInt() and 0xffff
-        val s = bits.ushr(FP16_SIGN_SHIFT)
-        val e = bits.ushr(FP16_EXPONENT_SHIFT) and FP16_EXPONENT_MASK
-        val m = bits and FP16_SIGNIFICAND_MASK
+        val s = bits.ushr(Fp16SignShift)
+        val e = bits.ushr(Fp16ExponentShift) and Fp16ExponentMask
+        val m = bits and Fp16SignificandMask
 
         if (e == 0x1f) { // Infinite or NaN
             if (m == 0) {
@@ -563,7 +527,7 @@
                 val significand = m.toString(16)
                 o.append(significand.replaceFirst("0{2,}$".toRegex(), ""))
                 o.append('p')
-                o.append((e - FP16_EXPONENT_BIAS).toString())
+                o.append((e - Fp16ExponentBias).toString())
             }
         }
 
@@ -627,78 +591,118 @@
          * Positive 0 of type half-precision float.
          */
         val PositiveZero = Float16(0x0000.toShort())
+    }
+}
 
-        private val One = Float16(1f)
-        private val NegativeOne = Float16(-1f)
+private val One = Float16(1f)
+private val NegativeOne = Float16(-1f)
 
-        private const val FP16_SIGN_SHIFT = 15
-        private const val FP16_SIGN_MASK = 0x8000
-        private const val FP16_EXPONENT_SHIFT = 10
-        private const val FP16_EXPONENT_MASK = 0x1f
-        private const val FP16_SIGNIFICAND_MASK = 0x3ff
-        private const val FP16_EXPONENT_BIAS = 15
-        private const val FP16_COMBINED = 0x7fff
-        private const val FP16_EXPONENT_MAX = 0x7c00
+private const val Fp16SignShift = 15
+private const val Fp16SignMask = 0x8000
+private const val Fp16ExponentShift = 10
+private const val Fp16ExponentMask = 0x1f
+private const val Fp16SignificandMask = 0x3ff
+private const val Fp16ExponentBias = 15
+private const val Fp16Combined = 0x7fff
+private const val Fp16ExponentMax = 0x7c00
 
-        private const val FP32_SIGN_SHIFT = 31
-        private const val FP32_EXPONENT_SHIFT = 23
-        private const val FP32_EXPONENT_MASK = 0xff
-        private const val FP32_SIGNIFICAND_MASK = 0x7fffff
-        private const val FP32_EXPONENT_BIAS = 127
-        private const val FP32_QNAN_MASK = 0x400000
+private const val Fp32SignShift = 31
+private const val Fp32ExponentShift = 23
+private const val Fp32ExponentMask = 0xff
+private const val Fp32SignificandMask = 0x7fffff
+private const val Fp32ExponentBias = 127
+private const val Fp32QNaNMask = 0x400000
 
-        private const val FP32_DENORMAL_MAGIC = 126 shl 23
-        private val FP32_DENORMAL_FLOAT = floatFromBits(FP32_DENORMAL_MAGIC)
+private const val Fp32DenormalMagic = 126 shl 23
+private val Fp32DenormalFloat = floatFromBits(Fp32DenormalMagic)
 
-        private fun toCompareValue(value: Short): Int {
-            return if (value.toInt() and FP16_SIGN_MASK != 0) {
-                0x8000 - (value.toInt() and 0xffff)
+@Suppress("NOTHING_TO_INLINE")
+private inline fun toCompareValue(value: Short): Int {
+    return if (value.toInt() and Fp16SignMask != 0) {
+        0x8000 - (value.toInt() and 0xffff)
+    } else {
+        value.toInt() and 0xffff
+    }
+}
+
+/**
+ * Convert a single-precision float to a half-precision float, stored as
+ * [Short] data type to hold its 16 bits.
+ */
+internal fun floatToHalf(f: Float): Short {
+    val bits = f.toRawBits()
+    val s = bits.ushr(Fp32SignShift)
+    var e = bits.ushr(Fp32ExponentShift) and Fp32ExponentMask
+    var m = bits and Fp32SignificandMask
+
+    var outE = 0
+    var outM = 0
+
+    if (e == 0xff) { // Infinite or NaN
+        outE = 0x1f
+        outM = if (m != 0) 0x200 else 0
+    } else {
+        e = e - Fp32ExponentBias + Fp16ExponentBias
+        if (e >= 0x1f) { // Overflow
+            outE = 0x31
+        } else if (e <= 0) { // Underflow
+            if (e < -10) {
+                // The absolute fp32 value is less than MIN_VALUE, flush to +/-0
             } else {
-                value.toInt() and 0xffff
+                // The fp32 value is a normalized float less than MIN_NORMAL,
+                // we convert to a denorm fp16
+                m = m or 0x800000 shr 1 - e
+                if (m and 0x1000 != 0) m += 0x2000
+                outM = m shr 13
             }
-        }
-
-        private fun floatToHalf(f: Float): Short {
-            val bits = f.toRawBits()
-            val s = bits.ushr(FP32_SIGN_SHIFT)
-            var e = bits.ushr(FP32_EXPONENT_SHIFT) and FP32_EXPONENT_MASK
-            var m = bits and FP32_SIGNIFICAND_MASK
-
-            var outE = 0
-            var outM = 0
-
-            if (e == 0xff) { // Infinite or NaN
-                outE = 0x1f
-                outM = if (m != 0) 0x200 else 0
-            } else {
-                e = e - FP32_EXPONENT_BIAS + FP16_EXPONENT_BIAS
-                if (e >= 0x1f) { // Overflow
-                    outE = 0x31
-                } else if (e <= 0) { // Underflow
-                    if (e < -10) {
-                        // The absolute fp32 value is less than MIN_VALUE, flush to +/-0
-                    } else {
-                        // The fp32 value is a normalized float less than MIN_NORMAL,
-                        // we convert to a denorm fp16
-                        m = m or 0x800000 shr 1 - e
-                        if (m and 0x1000 != 0) m += 0x2000
-                        outM = m shr 13
-                    }
-                } else {
-                    outE = e
-                    outM = m shr 13
-                    if (m and 0x1000 != 0) {
-                        // Round to nearest "0.5" up
-                        var out = outE shl FP16_EXPONENT_SHIFT or outM
-                        out++
-                        return (out or (s shl FP16_SIGN_SHIFT)).toShort()
-                    }
-                }
+        } else {
+            outE = e
+            outM = m shr 13
+            if (m and 0x1000 != 0) {
+                // Round to nearest "0.5" up
+                var out = outE shl Fp16ExponentShift or outM
+                out++
+                return (out or (s shl Fp16SignShift)).toShort()
             }
-
-            return (s shl FP16_SIGN_SHIFT or (outE shl FP16_EXPONENT_SHIFT) or outM).toShort()
         }
     }
+
+    return (s shl Fp16SignShift or (outE shl Fp16ExponentShift) or outM).toShort()
+}
+
+/**
+ * Convert a half-precision float to a single-precision float.
+ */
+internal fun halfToFloat(h: Short): Float {
+    val bits = h.toInt() and 0xffff
+    val s = bits and Fp16SignMask
+    val e = bits.ushr(Fp16ExponentShift) and Fp16ExponentMask
+    val m = bits and Fp16SignificandMask
+
+    var outE = 0
+    var outM = 0
+
+    if (e == 0) { // Denormal or 0
+        if (m != 0) {
+            // Convert denorm fp16 into normalized fp32
+            var o = floatFromBits(Fp32DenormalMagic + m)
+            o -= Fp32DenormalFloat
+            return if (s == 0) o else -o
+        }
+    } else {
+        outM = m shl 13
+        if (e == 0x1f) { // Infinite or NaN
+            outE = 0xff
+            if (outM != 0) { // SNaNs are quieted
+                outM = outM or Fp32QNaNMask
+            }
+        } else {
+            outE = e - Fp16ExponentBias + Fp32ExponentBias
+        }
+    }
+
+    val out = s shl 16 or (outE shl Fp32ExponentShift) or outM
+    return floatFromBits(out)
 }
 
 /**
@@ -716,7 +720,6 @@
     if (x.isNaN() || y.isNaN()) {
         return Float16.NaN
     }
-
     return if (x <= y) x else y
 }
 
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt
new file mode 100644
index 0000000..724538e
--- /dev/null
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/InlineClassHelper.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.compose.ui.graphics
+
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.contract
+
+// This function exists so we do *not* inline the throw. It keeps
+// the call site much smaller and since it's the slow path anyway,
+// we don't mind the extra function call
+internal fun throwIllegalArgumentException(message: String) {
+    throw IllegalArgumentException(message)
+}
+
+// Like Kotlin's require() but without the .toString() call
+@Suppress("BanInlineOptIn") // same opt-in as using Kotlin's require()
+@OptIn(ExperimentalContracts::class)
+internal inline fun requirePrecondition(value: Boolean, lazyMessage: () -> String) {
+    contract {
+        returns() implies value
+    }
+    if (!value) {
+        throwIllegalArgumentException(lazyMessage())
+    }
+}
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt
index 3df385d..28cd34c 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/ColorSpace.kt
@@ -705,7 +705,8 @@
  * @param r2: The third element of the vector
  * @return The first element of the resulting multiplication.
  */
-internal fun mul3x3Float3_0(
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun mul3x3Float3_0(
     lhs: FloatArray,
     r0: Float,
     r1: Float,
@@ -723,7 +724,8 @@
  * @param r2: The third element of the vector
  * @return The second element of the resulting multiplication.
  */
-internal fun mul3x3Float3_1(
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun mul3x3Float3_1(
     lhs: FloatArray,
     r0: Float,
     r1: Float,
@@ -741,7 +743,8 @@
  * @param r2: The third element of the vector
  * @return The third element of the resulting multiplication.
  */
-internal fun mul3x3Float3_2(
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun mul3x3Float3_2(
     lhs: FloatArray,
     r0: Float,
     r1: Float,
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt
index 415e66c..92b92c6 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Lab.kt
@@ -17,8 +17,9 @@
 package androidx.compose.ui.graphics.colorspace
 
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.packFloats
-import kotlin.math.pow
+import kotlin.math.cbrt
 
 /**
  * Implementation of the CIE L*a*b* color space. Its PCS is CIE XYZ
@@ -44,9 +45,9 @@
     }
 
     override fun toXyz(v: FloatArray): FloatArray {
-        v[0] = v[0].coerceIn(0.0f, 100.0f)
-        v[1] = v[1].coerceIn(-128.0f, 128.0f)
-        v[2] = v[2].coerceIn(-128.0f, 128.0f)
+        v[0] = v[0].fastCoerceIn(0.0f, 100.0f)
+        v[1] = v[1].fastCoerceIn(-128.0f, 128.0f)
+        v[2] = v[2].fastCoerceIn(-128.0f, 128.0f)
 
         val fy = (v[0] + 16.0f) / 116.0f
         val fx = fy + (v[1] * 0.002f)
@@ -63,8 +64,8 @@
     }
 
     override fun toXy(v0: Float, v1: Float, v2: Float): Long {
-        val v00 = v0.coerceIn(0.0f, 100.0f)
-        val v10 = v1.coerceIn(-128.0f, 128.0f)
+        val v00 = v0.fastCoerceIn(0.0f, 100.0f)
+        val v10 = v1.fastCoerceIn(-128.0f, 128.0f)
 
         val fy = (v00 + 16.0f) / 116.0f
         val fx = fy + (v10 * 0.002f)
@@ -75,8 +76,8 @@
     }
 
     override fun toZ(v0: Float, v1: Float, v2: Float): Float {
-        val v00 = v0.coerceIn(0.0f, 100.0f)
-        val v20 = v2.coerceIn(-128.0f, 128.0f)
+        val v00 = v0.fastCoerceIn(0.0f, 100.0f)
+        val v20 = v2.fastCoerceIn(-128.0f, 128.0f)
         val fy = (v00 + 16.0f) / 116.0f
         val fz = fy - (v20 * 0.005f)
         val z = if (fz > D) fz * fz * fz else (1.0f / B) * (fz - C)
@@ -94,18 +95,18 @@
         val y1 = y / Illuminant.D50Xyz[1]
         val z1 = z / Illuminant.D50Xyz[2]
 
-        val fx = if (x1 > A) x1.pow(1f / 3f) else B * x1 + C
-        val fy = if (y1 > A) y1.pow(1f / 3f) else B * y1 + C
-        val fz = if (z1 > A) z1.pow(1f / 3f) else B * z1 + C
+        val fx = if (x1 > A) cbrt(x1) else B * x1 + C
+        val fy = if (y1 > A) cbrt(y1) else B * y1 + C
+        val fz = if (z1 > A) cbrt(z1) else B * z1 + C
 
         val l = 116.0f * fy - 16.0f
         val a1 = 500.0f * (fx - fy)
         val b = 200.0f * (fy - fz)
 
         return Color(
-            l.coerceIn(0.0f, 100.0f),
-            a1.coerceIn(-128.0f, 128.0f),
-            b.coerceIn(-128.0f, 128.0f),
+            l.fastCoerceIn(0.0f, 100.0f),
+            a1.fastCoerceIn(-128.0f, 128.0f),
+            b.fastCoerceIn(-128.0f, 128.0f),
             a,
             colorSpace
         )
@@ -116,17 +117,17 @@
         val y = v[1] / Illuminant.D50Xyz[1]
         val z = v[2] / Illuminant.D50Xyz[2]
 
-        val fx = if (x > A) x.pow(1f / 3f) else B * x + C
-        val fy = if (y > A) y.pow(1f / 3f) else B * y + C
-        val fz = if (z > A) z.pow(1f / 3f) else B * z + C
+        val fx = if (x > A) cbrt(x) else B * x + C
+        val fy = if (y > A) cbrt(y) else B * y + C
+        val fz = if (z > A) cbrt(z) else B * z + C
 
         val l = 116.0f * fy - 16.0f
         val a = 500.0f * (fx - fy)
         val b = 200.0f * (fy - fz)
 
-        v[0] = l.coerceIn(0.0f, 100.0f)
-        v[1] = a.coerceIn(-128.0f, 128.0f)
-        v[2] = b.coerceIn(-128.0f, 128.0f)
+        v[0] = l.fastCoerceIn(0.0f, 100.0f)
+        v[1] = a.fastCoerceIn(-128.0f, 128.0f)
+        v[2] = b.fastCoerceIn(-128.0f, 128.0f)
 
         return v
     }
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt
index 4b1e958..fc50825 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Oklab.kt
@@ -17,10 +17,9 @@
 package androidx.compose.ui.graphics.colorspace
 
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.util.fastCbrt
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.packFloats
-import kotlin.math.abs
-import kotlin.math.pow
-import kotlin.math.sign
 
 /**
  * Implementation of the Oklab color space. Oklab uses
@@ -46,9 +45,9 @@
     }
 
     override fun toXyz(v: FloatArray): FloatArray {
-        v[0] = v[0].coerceIn(0f, 1f)
-        v[1] = v[1].coerceIn(-0.5f, 0.5f)
-        v[2] = v[2].coerceIn(-0.5f, 0.5f)
+        v[0] = v[0].fastCoerceIn(0f, 1f)
+        v[1] = v[1].fastCoerceIn(-0.5f, 0.5f)
+        v[2] = v[2].fastCoerceIn(-0.5f, 0.5f)
 
         mul3x3Float3(InverseM2, v)
         v[0] = v[0] * v[0] * v[0]
@@ -60,9 +59,9 @@
     }
 
     override fun toXy(v0: Float, v1: Float, v2: Float): Long {
-        val v00 = v0.coerceIn(0f, 1f)
-        val v10 = v1.coerceIn(-0.5f, 0.5f)
-        val v20 = v2.coerceIn(-0.5f, 0.5f)
+        val v00 = v0.fastCoerceIn(0f, 1f)
+        val v10 = v1.fastCoerceIn(-0.5f, 0.5f)
+        val v20 = v2.fastCoerceIn(-0.5f, 0.5f)
 
         val v01 = mul3x3Float3_0(InverseM2, v00, v10, v20)
         val v11 = mul3x3Float3_1(InverseM2, v00, v10, v20)
@@ -79,9 +78,9 @@
     }
 
     override fun toZ(v0: Float, v1: Float, v2: Float): Float {
-        val v00 = v0.coerceIn(0f, 1f)
-        val v10 = v1.coerceIn(-0.5f, 0.5f)
-        val v20 = v2.coerceIn(-0.5f, 0.5f)
+        val v00 = v0.fastCoerceIn(0f, 1f)
+        val v10 = v1.fastCoerceIn(-0.5f, 0.5f)
+        val v20 = v2.fastCoerceIn(-0.5f, 0.5f)
 
         val v01 = mul3x3Float3_0(InverseM2, v00, v10, v20)
         val v11 = mul3x3Float3_1(InverseM2, v00, v10, v20)
@@ -107,9 +106,9 @@
         var v1 = mul3x3Float3_1(M1, x, y, z)
         var v2 = mul3x3Float3_2(M1, x, y, z)
 
-        v0 = sign(v0) * abs(v0).pow(1.0f / 3.0f)
-        v1 = sign(v1) * abs(v1).pow(1.0f / 3.0f)
-        v2 = sign(v2) * abs(v2).pow(1.0f / 3.0f)
+        v0 = fastCbrt(v0)
+        v1 = fastCbrt(v1)
+        v2 = fastCbrt(v2)
 
         val v01 = mul3x3Float3_0(M2, v0, v1, v2)
         val v11 = mul3x3Float3_1(M2, v0, v1, v2)
@@ -121,9 +120,9 @@
     override fun fromXyz(v: FloatArray): FloatArray {
         mul3x3Float3(M1, v)
 
-        v[0] = sign(v[0]) * abs(v[0]).pow(1.0f / 3.0f)
-        v[1] = sign(v[1]) * abs(v[1]).pow(1.0f / 3.0f)
-        v[2] = sign(v[2]) * abs(v[2]).pow(1.0f / 3.0f)
+        v[0] = fastCbrt(v[0])
+        v[1] = fastCbrt(v[1])
+        v[2] = fastCbrt(v[2])
 
         mul3x3Float3(M2, v)
         return v
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt
index 08a24df..ae4d62a 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Xyz.kt
@@ -17,6 +17,7 @@
 package androidx.compose.ui.graphics.colorspace
 
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.packFloats
 
 /**
@@ -73,7 +74,8 @@
         return v
     }
 
-    private fun clamp(x: Float): Float {
-        return x.coerceIn(-2f, 2f)
+    @Suppress("NOTHING_TO_INLINE")
+    private inline fun clamp(x: Float): Float {
+        return x.fastCoerceIn(-2f, 2f)
     }
 }
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
index 68373e2..48b6984 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/painter/BitmapPainter.kt
@@ -24,7 +24,7 @@
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.toSize
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * [Painter] implementation used to draw an [ImageBitmap] into the provided canvas
@@ -95,8 +95,8 @@
             srcOffset,
             srcSize,
             dstSize = IntSize(
-                [email protected](),
-                [email protected]()
+                [email protected](),
+                [email protected]()
             ),
             alpha = alpha,
             colorFilter = colorFilter,
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorTest.kt
index 4adb50b..cd9b92d 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorTest.kt
@@ -568,6 +568,11 @@
         assertEquals(50f / 255f, srgbGreen.blue, 0.01f)
     }
 
+    @Test fun unspecifiedConstantValue() {
+        // See comments in Color.kt, we want to make sure Color.Unspecified doesn't change encoding
+        assertEquals(0x10UL, Color.Unspecified.value)
+    }
+
     companion object {
         fun Int.toHexString() = "0x${toUInt().toString(16).padStart(8, '0')}"
     }
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/testdata/RippleTestActivity.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/testdata/RippleTestActivity.kt
index 7b0aa4a..e89d8f6 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/testdata/RippleTestActivity.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/testdata/RippleTestActivity.kt
@@ -30,7 +30,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.material.Text
-import androidx.compose.material.ripple.rememberRipple
+import androidx.compose.material.ripple
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
@@ -57,7 +57,7 @@
                     modifier = Modifier
                         .clickable(
                             interactionSource = interactionSource,
-                            indication = rememberRipple()
+                            indication = ripple()
                         ) { /* do something */ }
                         .padding(10.dp)
                 )
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ComposedModifierDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ComposedModifierDetectorTest.kt
index 3f30abd..3d33d33 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ComposedModifierDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ComposedModifierDetectorTest.kt
@@ -46,7 +46,7 @@
     private val composedStub = bytecodeStub(
         filename = "ComposedModifier.kt",
         filepath = "androidx/compose/ui",
-        checksum = 0xad91cb77,
+        checksum = 0xc6ba0d09,
         """
             package androidx.compose.ui
 
@@ -59,50 +59,51 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlkZiXUpSfmVKhl5yfW5BfnKpX
-        VJpXkpmbKsQVlJqbmpuUWuRdwqXJJYyhrjRTSMgZwk7xzU/JTMsEK+XjYilJ
-        LS4RYgsBkt4lSgxaDACMRj6sewAAAA==
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuOSSMxLKcrPTKnQS87PLcgvTtUr
+        Ks0rycxNFeIKSs1NzU1KLfIu4dLkEsZQV5opJOQMYaf45qdkpmWClfJxsZSk
+        FpcIsYUASe8SJQYtBgBxwST5ewAAAA==
         """,
         """
         androidx/compose/ui/ComposedModifierKt$composed$1.class:
-        H4sIAAAAAAAAAJVUWU8TURT+7nQfipRFWdy1YgvKtOCaNiSEQJxQMBFsYni6
-        7Qxw6fSOmaXBN/6C/0Q0kUQTw7M/ynjutDW4gU4y956c831nn/n67dMXAA/w
-        lKHMpeW5wjowmm77tevbRiiM5a5orbuW2BG2txbke1YrX06BMazVWm7gCGns
-        d9qGkIHtSe4YNd5uWLxy2rYTymYgXOkbqz2pVO3bX0oRVBYrDFN/d5ZCnOHa
-        2Q5TSDIkq4LcLTLECsU6Q7xgFutZpKHrSGCAFMGe8BkWav9dMCWYFLLjtmyG
-        sUKxts873HC43DWeN/btZlDJYggZHRqGGQZO1ZbCKEPa3NjcWtpYXmEY/Knw
-        LC7iUgZjGCdQtelE6auMI1dTynwhQ9IVhuE+cd0OuMUDTilp7U6MhsjUkWBg
-        LSXESH8glFQiySozjJ4cJvWTQ13LabmTwymtxJ7pyjRPqVa5dOWbthv61DYw
-        TP9ba1KYZcj96I9l7/DQCRjeFv7Y2z7xvLU4x16umL93vnh2xCzuY4568GsN
-        cy1KN77sWjTRkZrb5E6de4I3HHtLHQxDNSHtjbDdsL2eJmtKaXvLDvd9m9Zo
-        aEU2HdcXcpdGsudaDJlNsSt5EHoE1jfd0Gvaq0IxJ1+EMhBtuy58Qa6WpHQD
-        HtWGEo03QY2nTwqTat40uDi9tAOkKZOUJwTNBsmZ2DGyR2rgmKcz29ViMOIM
-        qwXsMWYjDL0KrGEhgilF6hSRdYm5JSLmesR5upUtPfMRI+8x8e4MfroXOE1p
-        9wOPE1o9A5+hvTrG5Q+4ehQpEvSnAXSCdQETeBjVeQ8GHkVBYngc3SU8obtM
-        yGvEur6NmIkbJm7SiVsmbiNv4g6mt8F83EVhG5qPoo+Z7xp9fu/RBAAA
+        H4sIAAAAAAAA/5VU6U4TURT+7rR0GYoti7KIO2ILyrTg3oaENBAnFEwEmxh+
+        3XYGuHR6x8xMG/zHK/gKPoFoIokmhvjThzKeO20NbqCTzJ2Tc77v7He+fvv4
+        GcBdPGYocGl5rrD2jbrbfOn6ttESRrkjWmuuJbaF7a0GU12rNVWIgzGsVhpu
+        4Ahp7LWbhpCB7UnuGBXerFm8eNK23ZL1QLjSN1a6Ur7Usz+XIiguFhkm/u4s
+        jijD5dMdxhFjiJUEuVtkiGRzVYZo1sxVU0hA19GHflIEu8JnWKj8d8GUYEzI
+        ttuwGUayucoeb3PD4XLHeFrbs+tBMYU0kjo0DDL0n6gtjmGGhLm+sbm0Xl5m
+        GPip8BTO40ISIxglUKnuhOmrjENXE8p8LknSJMNgj7hmB9ziAaeUtGY7QkNk
+        6kiqAwysoYQIGfeFkvIkWQWGyeODhH58oGsZjT6Z44MJLc+e6F/exLSEpjDz
+        lHiJS1e+arotn5pIzqb/rVFx3GbI/OiWZW/zlhMwvM7+sdM94llLcoa9UDR/
+        n0Pu9IgpzMFgGP61hrkGpRstuxbNd6ji1rlT5Z7gNcfeVAdDuiKkvd5q1myv
+        q0mZUtpe2eG+b9NSpZdl3XF9IXdoQLuuxZDcEDuSBy2PwPqG2/Lq9opQzPFn
+        LRmIpl0VviBXS1K6AQ9rQ56G3UeNpwuGcTV9mmCUXtoI0syTNEUImg1iM5Ej
+        pA7DmS/QmepoMRByBtU6dhmzIYZeBdboyiuYUsRPEFmHmFkiYqZLnFfrpILP
+        fMDQO4y9PYWf6AZOUNq9wKOEVk//J2gvjnDxPS4dhoo+3KNTJ1gHMIb7YZ13
+        qP4HYZAIHobfAh6Ffym6/8S6soWIiasmrpm4jhsmNeOmiWnc2gLzkUWO7D5m
+        fMz6SH8Hu1pp5uIEAAA=
         """,
         """
         androidx/compose/ui/ComposedModifierKt.class:
-        H4sIAAAAAAAAALVU308bRxD+9vzr7BpibJISh1DSOAkYkrNJ2qY1IY1QkE4x
-        bhVTXnhazmuy+LyH7s6IvET8C33sa/+Cqk9RHyrUx0r9l6rOns+BAMKVqtq6
-        uZmdmW++nZ29P//+7XcAT/Atw32uOr4nO0eW4/UPvEBYA2mtD9XOpteRXSn8
-        V2EGjKGwzw+55XK1Z323uy8cWk0wmHFih+HdQvMyuBFMo9nzQlcqa/+wb3UH
-        ygmlpwJrI9ZqY/z1xuLV8Ax//TcCqyP/D0qGjbVxfFYfXl1t6Wr32vj93G16
-        /p61L8Jdn0sqzZXyQj6k0fLC1sB1KSq9Gr6RwZqJLMPcGcpShcJX3LVsFfqU
-        Lp0gg08YrjtvhNOL87/nPu8LCmR4sNA8f8KNMyttDbLXWNzOYwKTOeRxjWGC
-        cA8o0PNt1fVMTDFkulzbb02UGCYrmlvldEbmxu15ftyUjA2pU0hhVLHSEV0+
-        cEOGH//n6bQvdm/sAdf/3fX70L9KPYNbdOfsVnvrRWv9JcPjS0tcCdHI4zbm
-        spjFZx8PzCW7zuBOHimkczBwl2Fq1IRNEfIODzntwegfJuhzwrRIMbCeVgxa
-        P5Jaq5HWqTPwk+O53MlxzpgxRi+jcKoOn/LTwslx2aixKj0rkyZFlM1ismjU
-        krXEymwhVZ6JLDaUtfQfP6cNMxNJUxdaYSiOOJ4dGVyyrufk3sX2+QMVyr6I
-        e8h3XdHQYxsnvzwKBV0lT41Qtt4e6IDS+ZY/6tHMJde9jmC41pRKtAb9XeFv
-        aUBNxnO4u819qe14MduWe4qHA5/0W6+HNGx1KANJ7hend5+hct774Rp/FDbR
-        DrnT2+QHcYG8rZTw110eBILcubY38B2xIbXvZgy5faEc6nT4SeifgZt6Gsj6
-        kqzXZOsjnq4Wc+9RWCoWSS4Xp0lWf4mivyKZ1r1HFk9Jnx/G4zpuRHjTmMKn
-        5NdaCTOU8XWUl8E3caZJ7wY9pURsnJGFLNEpk67JPCPolAa6nXz3E3K/Yv4E
-        nzerS8vvURmSWSVJKBMRq8mISZr+Gfqcpcl6RnaOwGYjZjNYi5K+wHN6b9D6
-        PYK/v4OEjQc2Fkhi0UYVSzaW8XAHLMAjWDvIBkgFuBFgKkCNehegFGAlwOMA
-        T/4BiHoaCXoHAAA=
+        H4sIAAAAAAAA/7VUUU8bRxD+9mzss2OIsUlCHEJo4yRgSM4maZvWhAShIJ1q
+        3CqmvPC0+NZk8XkP3Z0ReYn4C33sa39B1aeoDxXqY6X+paqz53MggHClqjrd
+        7MzOzLffzs7un3//9juAZ1hjeMiV43vSObLaXu/AC4TVl9b6QHU2PUd2pPC/
+        DdNgDPl9fsgtl6s967vdfdGm2QSDGSc6DO/nG5fBDWHqja4XulJZ+4c9q9NX
+        7VB6KrA2Yq06wl+rL1wNz/DXfyOwMvT/oGRYXx3FZ+Xx1astXu1eHb2f+w3P
+        37P2Rbjrc0lLc6W8kA9oNL2w2XddikqthG9lsGoiwzB7hrJUofAVdy1bhT6l
+        y3aQxjWGG+23ot2N87/nPu8JCmR4NN84f8L1MzMtDbJXX9jOYRwTWeRwnWGc
+        cA8o0PNt1fFMTDKkO1zb70wUGSbKmlv5tEdmR+15blSXjAypUUh+uGLZER3e
+        d0OGH//n7rQvVm/kAdf+3fX7WL9yLY07dOfsZmtrrbn+muHppUtcCVHP4S5m
+        M5jBvU8b5pJdp/FZDmNIZWHgPsPksAibIuQODzntwegdJug5YVpktAAD62rF
+        IOeR1FqVNKfGwE+OZ7Mnx1lj2hgORv5UHfyl5/mT45JRZRX6lydMiiiZhWTB
+        qCarieWZ/FhpOrLYQFZTf/ycMsx0JE290DJDYUj0bN/gknndLA8u1tDvq1D2
+        RFxIvuuKuu7dOPn1USjoPnlqiLL17kAHFM/X/UmXGi+57jmC4XpDKtHs93aF
+        v6UBNRmvzd1t7kttx5OZltxTPOz7pN95M6Bhq0MZSHKvnT4ADOXz3o93+ZOw
+        8VbI291NfhAvkLOVEv66y4NAkDvb8vp+W2xI7bsdQ25fWA416oCkPl0ab+uW
+        IOsrst6QrY94qlLIfkB+sVAguVSYIln5JYp+TjKla48MviZ9bhCPG7gZ4U1h
+        ErfIr7UipinjmygvjXqcadK4Qn8xERtnZD5DdEqkazIvCHpMA91Nvv8J2V8x
+        d4LPG5XFpQ8oD8i8IEko4xGriYhJir40vWkpslbJzhLYTMRsGi+jpC/xisYN
+        mn9A8A93kLDxyMa8jQVUbCxiycZjPNkBC2ChuoNMgLEANwNMUuECLAcoBnga
+        4FmAL/4BKp/c6X8HAAA=
         """
     )
 
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt
index c5faed9..aba348a 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt
@@ -47,25 +47,25 @@
     private val DensityStub = bytecodeStub(
         filename = "Density.kt",
         filepath = "androidx/compose/ui/unit",
-        checksum = 0xaa534a7a,
+        checksum = 0x3ceb3f57,
         """
             package androidx.compose.ui.unit
 
             interface Density
         """,
-        """
+"""
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcIlnpiXUpSfmVKhl5yfW5BfnKpX
-        mqmXlp8vxOmWn++SWJLoXaLEoMUAAALEmjo+AAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuEST8xLKcrPTKnQS87PLcgvTtUr
+        zdRLy88X4nTLz3dJLEn0LlFi0GIAAHSOuCo+AAAA
         """,
         """
         androidx/compose/ui/unit/Density.class:
-        H4sIAAAAAAAAAIVOTUvDQBB9s7FNjV+pH1Bv4g9w2+LNkyBCoCIoeMlpm6yy
-        Tbor3U2pt/4uD9KzP0qcqHdn4M17M/DefH69fwC4xDHhTNly4Uy5koWbvzqv
-        ZWNkY02QN9p6E95iECGdqaWStbIv8n4600WIERH6k8qF2lh5p4MqVVBXBDFf
-        RuxNLXQIVPFqZVo1ZFaOCCebdS8RA5GIlNnzYLMeiyG1xzHhfPLfP5wBQvKn
-        LqrA4tE1i0LfmloTTh8aG8xcPxlvprW+ttYFFYyzvssZ2MJvCRz+YB9HPEds
-        2eHu5ogyxBl6jNhuIcmwg90c5LGH/RzC48Aj/QaMxaG1RAEAAA==
+        H4sIAAAAAAAA/4VOTUvDQBB9s9GmjV+pWqg38Qe4benNkyBCoCIoeMlpm6yy
+        bbor3U2pt/4uD9KzP0qcqHdn4M17M/DefH69fwAYo0c4V7ZcOlOuZeEWr85r
+        WRtZWxPkjbbehLcYREhnaqVkpeyLvJ/OdBFiRITuZO5CZay800GVKqgrglis
+        IvamBjoNgEBz3q9NowbMyiGht920E9EXiUiZPfe3m5EYUHMcES4m/z3FQeyb
+        /KnLeWDx6OploW9NpQlnD7UNZqGfjDfTSl9b64IKxlnf4gzs4LcETn7wGKc8
+        h2y5y93KEWWIM7QzdJAwxV6GfRzkII9DHOUQHqlH9xtDUhD7SQEAAA==
         """
     )
 
@@ -73,7 +73,7 @@
     private val MeasurableAndParentDataModifierStub = bytecodeStub(
         filename = "Measurable.kt",
         filepath = "androidx/compose/ui/layout",
-        checksum = 0xd1bf915a,
+        checksum = 0x1c810a26,
         """
             package androidx.compose.ui.layout
 
@@ -90,51 +90,51 @@
         """,
 """
         META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcIlnpiXUpSfmVKhl5yfW5BfnKpX
-        mqmXlp8vxOmWn++SWJLoXaLEoMUAAALEmjo+AAAA
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuEST8xLKcrPTKnQS87PLcgvTtUr
+        zdRLy88X4nTLz3dJLEn0LlFi0GIAAHSOuCo+AAAA
         """,
         """
         androidx/compose/ui/layout/Measurable.class:
-        H4sIAAAAAAAAAI1PwU7bQBB9YzuO65Li0AAJvVK1veAEcaInpAopUmirIKFK
-        OW2SJdrE2UXedURv+ZYe+hE9oChHPgoxRkhB7aV7eDPz5s3Om/uHP3cATtAi
-        vBd6nBs1vk1HZn5jrEwLlWbipylceiGFLXIxzGQVREimYiG4pyfpt+FUjlwV
-        PqE2ke67yKV2X4QThMbHT72/hZ8Jhz2TT9KpdMNcKG1TobVxwinD+dciy8ot
-        LKv3ZsZlSvNuJ8b8IXPefOGzXSqhQqAZU7eqrNqcjTuEzmq5FXtNL/aS1TL2
-        Ij+6bq6Wx16b+o3EOwia1KYf69/B+lcYHgSRnwTl4DHhQ++/zmcTIMQ3L86s
-        bbpHM0d41y+0U3PZ1QtlFbNnmwN59NIU+Uieq0wSWs/Sq3+EIdtCgPIRW6wg
-        5LV7XJWxytHD/hPuosnxlNmIVa8G8LuIu3jNiK0Sal28wfYAZJGgPkDFYsfi
-        rUXDlnn4CLI2KhoDAgAA
+        H4sIAAAAAAAA/41QwU7bQBB9YxsnMaQ1kNIQrkXApQ6IE5wqISRLgSKQEFJO
+        m2QbbeLsIu86glu+hQMfwQFFOfajqo5RJRBcepl58+bNvpn9/efpGcAhWoRt
+        oQe5UYO7pG8mt8bKpFBJJu5N4ZIzKWyRi14mKyBCPBJTwT09TH72RrLvKvAJ
+        9aF0FyKX2p0IJwiN3b3Oe+Ex4VvH5MNkJF0vF0rbRGhtnHDKMD4vsqx0Ydlq
+        Z2xcpjR7OzHgB5nzJlOf16Uy1MoAAo2Zv1Nl1WY02Cfsz2crkdf0Ii+ezyKv
+        6ld/NeezA69Nl43YawVNatPN4jFYPIRhK6j6cVAOHhB2Ov/1B7wJG0e3b26t
+        v3a/jx1h67LQTk1kqqfKKmZ/vF7Jo1emyPvyVGWSsPlPev1BGPJaCPByJ6+4
+        hJBtv3JV5gpnD82XuIFNzkfMVllV68JPEaVYTrGCOkN8SvEZcRdksYq1LpYs
+        1i0aFl9sicO/4SGINQgCAAA=
         """,
         """
         androidx/compose/ui/layout/ParentDataModifier$DefaultImpls.class:
-        H4sIAAAAAAAAAKVSW08TQRT+pqW01FZKtSii9UKVXoSVxCf7ZECTTdpKxPTF
-        p+nuUKbdnSGzsw3+Kx+JD8Znf5TxbGkQK0GJm+y5f9/MnHO+//jyFcBLOAyv
-        uPKNlv6J4+nwWEfCiaUT8E86ts4+N0LZPW55V/vyUApT2xOHPA6sGx4HURaM
-        oTTiE04ANXTeDUbCs1mkGRbskVAMYb1zLfr2peXn2cbVaYaNjjZDZyTswHCp
-        IocrpS23UpPd07YXB0F7ejkZ5ZBjqI61DaRyRpPQkcoKo3jguMoaAkuPHphn
-        qHhHwhvP0HRlHgoqZNisd+af3r4QOUhIhu1Gv4ACinncwE2GjKa+mBxKDLWr
-        nlJ7E4iQepNFmWHnXyrnBnObwb+89/PA/2t5ARms5lHBHQbnmrOm9v9tniud
-        2YC6wnKfwBRLhZM0LS9LRIaBjRODVi51IhPrBcPWte6RxQZD4WL7GIpdwaPY
-        8EEgtseWNmZX+4JhuSOV6MXhQJgPSY6h3NEeD/rcyMSfBdffx8rKULhqIiNJ
-        ode/1pAGP58936nfygquUsLsBjyKBLn5Ax0bT7yVyQFrM4r+H/TYQQoLSD6G
-        JRrOItLYJK9L8RTpSrO8dIrlVnmFZPMbbrVOcfczJVKok8yTLoD2h8AN8lfP
-        QMhhbUpaQQn3iLpJ9iLpLOkW/cXUzDmTaTyfktFUUMNTAm9Nj3iGbdJViq9T
-        zf2PSLt44KJKEg9dPMJjF09+As+nXNieBAAA
+        H4sIAAAAAAAA/6VSTU8TQRh+ZgvdthZKq6AI4gdVWhAWjCc5GVCzSVuNGC6e
+        ptuhnXZ3hszONvivPBIPxrM/yvguNIiVoI2Hfb+fZ+f9+P7jy1cAz/GM4QVX
+        HaNl58QLdHSsY+El0gv5J51Y7x03Qtl9bnlTd+SRFKa6L454Elo/Og5jF4xh
+        rs+HnACq671t90VgXWQYpmxPKIao1piIfvfK8ots/fo0w2pDm67XF7ZtuFSx
+        x5XSllupyW5p20rCkKqmNb3O5JBjWBloG0rl9YeRJ5UVRvHQ85U1hJYBdVhg
+        mA96IhiM4PRmHgkqZFirNcZ7370UOUhJurv1wyKKmCngBmYZqtc1UH0Viogm
+        4mKOYedfKsfWUWHoXD3xceD/DbqIadwq4CbmaZhV25Mxgzfhpmn2f9tmuTHa
+        TlNY3iEwxZxomKHTZanIpwIMbJAadHXOiUytbYbl66hdrDK4o0kwFC8PkWFz
+        oj5crDHMNAWPE8PbodgaEOPUnu4IhlJDKtFKorYwH9IcQ6WhAx4eciNTfxRc
+        ep8oKyPhq6GMJYVe/rpaupjx7MUF/lZW9JUSZi/kcSzILRzoxATitUx/sDii
+        OPyDHjtwMIXzMeZpq1lksE7eG4o7pEsblfwpSuvfUN44xcJnCjnYIFkgnYWL
+        WYI9JX/hvBy3ceeMroQcFol0k+wsaZf0Fn0zzsg5lxl4JO+SLqOKx9k8HVUZ
+        TwjqoHamt89+WaeXAiuESmuXPiLjY9nHPZ9i9308wEMfj34CPA2YO9cEAAA=
         """,
         """
         androidx/compose/ui/layout/ParentDataModifier.class:
-        H4sIAAAAAAAAAJVRTW/TQBB963w4mARSKJC0fLWNqoIEDhEnqh4QAdUogQok
-        Ljlt4k21ib0beddRc8vv4oBy5kchxgHUkgYQh52d9/xmdjzv67fPXwA8xx7D
-        E67CRMvwzB/oeKKN8FPpR3ymU+uf8EQo2+aWd3Uoh1IkLhhDdcSnnDTq1H/f
-        H4mBdZFjaKxr9Kuu8ToSMfVyUaD6OGNn590Zjg8668pTJa3fFspIOzvsrD57
-        +OgyRXN0dHLqj4TtJ1wq43OltOVWasrfpVHE+5Eg2d7fZNpmSlJtdMbaRlL5
-        XWF5SKMS58TTHG2PZYH+ho2JOpMZalIWPmM4Wsw3PafmLM9i7jnVLCzz0rC2
-        mLecJntbqzpb+Rpr5h47zXyrVC38QMf7WZMWg792I390hgbbX1uxagEJwbD7
-        730zeJMLFr34r3EabTHkaWSDeBIZF1sM5YsMQ6UruEmTzI2nY8uw/SFVVsYi
-        UFNpJLEvzw0hU1e/0os8FlYkv8nKgVIieRVxYwRB76NOk4F4IyPBUP/Z4tOl
-        9kXaOPK0lGJma57BRYmY+4SKxF6h+wGdikPAyyRLKoeHFD1C2yS+izp2CDu4
-        h126j4i/igLKPeQCVAJco4jrWagG2MCNHpjBTWz2UDS4ZXDbwDW4Y1AzqH8H
-        FbjiFqEDAAA=
+        H4sIAAAAAAAA/5VS328SQRD+9oA7QNCrVoW2/moRfyR6SHyy6YMRTc9ANZr4
+        wtMCS7Nwt0du90h54+/ywfDsH2Wcw5pWijU+7OzMd998Mzez3398/QbgJR4x
+        PONqEEdycOL1o3ASaeEl0gv4LEqM95HHQpkWN7wTDeRQitgBY3BHfMqJo469
+        D72R6BsHGYbaOqHfebW3gQhJy0GO8sMUnZ2pMxw+bq9LT5Q0XksoLc1sv71a
+        dv/JRYj6aEfxsTcSphdzqbTHlYoMNzIi/ygJAt4LBNH2LqNFJmUSa6M9jkwg
+        ldcRhg+oVcKscJqh6bHUFFIDBjYm/ESmUYO8wQuGg8V8s2hVrOVZzIuWm5ql
+        nx9WFvOm1WDvK661la2wRuap1cg2827uV3RYT0WaDN7asfx1PdRdfW3G6h6I
+        SF3v/nvoDMXJuT3tXCbuYJvBOa3A8Oq/Wq+1xJAngfHDSaAd3GUonUcYyh3B
+        dRKn63s+JvntT4kyMhS+mkotCX19tkF6BatfqSIPhRHxH7SSr5SI3wRca0Fh
+        8XOUxH3xTgaCoXoq8eWCvE3bQZYGaKfLz9JPI0/ILkU2oQW69+iULQqKy/eR
+        QhnUyF4noo0d3LELuEf+fVTxkHALD1Cn+4DYV5BDqYuMj7KPqz6uwSUXGz5l
+        3+iCaWziZhe2xi2N2xqORkWjqrH1E3XfjsnaAwAA
         """
     )
 
@@ -680,7 +680,7 @@
         val inlineAndValueClassStub = bytecodeStub(
             filename = "InlineAndValueClassStub.kt",
             filepath = "androidx/compose/ui/foo",
-            checksum = 0x16c1f1c4,
+            checksum = 0x402f4998,
             """
             package androidx.compose.ui.foo
 
@@ -701,111 +701,110 @@
                 return this.then(TestModifier)
             }
         """,
-            """
+    """
             META-INF/main.kotlin_module:
-            H4sIAAAAAAAAAGNgYGBmYGBgBGI2BijgsuEST8xLKcrPTKnQS87PLcgvTtUr
+            H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuEST8xLKcrPTKnQS87PLcgvTtUr
             zdRLy88XkvTMy8nMS3XMSwlLzClNdc5JLC4OLilN8i4RYgtJLS7xLlFi0GIA
-            APJuU+dWAAAA
+            AA4XavBWAAAA
             """,
             """
             androidx/compose/ui/foo/Inline.class:
-            H4sIAAAAAAAAAIVU3VMbVRT/3ZuvzbLAkvIVrJVCLQkfDdBqVVpaQGKDoShU
-            LMWvJVlgIdnF7IbhkfFF/wIffPSZ6eiMAmNHB+mbf5PjeO7dDWDI1Jlk7z3n
-            no/f+Z1z71///PYHgDvYZLhm2MWKYxX3MgWnvOO4ZqZqZdYdJ5OzS5ZtxsAY
-            9C1j18iUDHsjs7C2ZRa8GEIMyobpLRulqskQSqWzDJFdX2JZDTEocXDEGcLe
-            puUy9OZfnWiCodlzlryKZW+MWOWdEkNHKpvOn6f2z8iuq143XbVKRbMSQytD
-            9J5lW96kxLSsoQ0JFTquUHQ/T0qCvK+gg2yNnR3TLjKMpC7nuZw6SDOhoQvd
-            ImqS4WojjBcNXxOGV4XhzKsNrwnDN4jWGgsM7akG9Wu4jj5h20/cGpWNUQ3N
-            aFGJ7JtU5Kbhbs44RTOgMEzwcgyt51GyJceg/g1SopqthmGkVQxhRLKW05AS
-            MscoQ5P5ddUouUG4zlQ2Xz8LE+lnDGrVXnP2pJVGcxUV3m8xxCTZC+uilP/w
-            JFFQKXfxjkj8Ls3htuNRfzJbu+WMZXtmxTZKNBqiZtcquDFQ4xWjYs4KPAwD
-            qctAGkHTcB+TKu7hAc2n422aFYbEZUOaBb9QMXWN44zjtqhq1id1WUVYTJVe
-            cGzXq1QLnlO5wDndBqVGCEO/KP5/xl+M6gciwTxdoF0G7QLx1IdIKpsVRPOd
-            MfEZp17kLzA2t1s+u0ZttYN50zOKhmeQjpd3Q3TjmfhExQeUZZv0e5aQKAEv
-            UuDfT/YHVd7NVa6f7Kv043pM5UqE1iZaw7QqtIZobaGVK6ffPuw+2R/no2w6
-            kYjqvIePhl4es5P90x+jYSWsR+Z6dIWU8XFFV3vC3WyUPXr5fUieNunanK43
-            02kL6ZjUteo66dpIlzjTXdHbF9v80CQrBKsnrET12Ol3jPu5vuGETEmKIogY
-            Kq3HJ2PKLsoHaqZkuO6SV127te1Rf8TM053Ik8XjannNrDwx1kqmmAunYJSW
-            jYol5EDZvOQZhe15YyeQ1SWnWimYWUsIycWq7Vllc9lyLTqdsm3HMzyLRgJj
-            1Mqw5DkhHkPaiQ5HECXNGkkZ0QFaI4O/QH1OG46CaI5URlGUDtIATbQD4uKa
-            B853yVqcJV9AXzlCe6LzED19h3hdTx+i9xA3fpKZz4Mk8abEwMTjEQS5GSBQ
-            BIJjDNT7KGeJ6TkIfPprqPuOceugziFylmRYltcgyVi9z3kSul+Bz1OqTkxl
-            /9Cf4D8gEjoYOgE/xNuzlPW9G/Q/xkOpDx9I4kz6xsDjf6OLy9idpBRgfTxi
-            N4VpiWQG7wdZRIOEVVwgGzpG9hya7x4PoImddNe5uKOB+2Tgrg4e4dFg/69Q
-            f27YRD+WehZLldPAKGYOc0Gs3oAk3ve8jh7uz46exIfIB9YDRI44i78AX+k7
-            wuP6xsWxIJ3axEtc37jauLEGI5bER/g4cLgT1KcJzvt9zusZ0rAYEKxhSVbF
-            sS5RG9ig1abdE1o/oQzLqwjl8GkOT3NYwTPaYjWHz/D5KpiLL/DlKjpcaC6+
-            chGT35yLORcRF1EXM1Iz5WLcxW0Xw1JMuUi7uC73zS5a/gWm4bi81wgAAA==
+            H4sIAAAAAAAA/4VU3VMbVRT/3ZuvzbKEhQKF2FYaapvw0QBVq1KQjzY2GFqF
+            GqX4tUlWWEh2Y3bD8Mib/gXO2EdffJDp6IwCY2ccxDf/Jsfx3JsNYQJTZ3bu
+            vefcc87vnN85d//+9/c/ALyOAsM1wy7VHKu0my46larjmum6lf7KcdJZu2zZ
+            ZgSMQd8ydox02bA30o8LW2bRiyDAoGyYXt4o102GQDKVYQjtNCSW0RCBEgVH
+            lCHobVouw1Du5UDTDJ2es+rVLHtj3KpUywx9yUwq14Ju3JHd5XbdQt0ql8xa
+            BF0M4XuWbXmzMqe8hm70qNBxiaI3cJIyyRkFfWRrVKumXWIYT57HOQ/tw0xr
+            uIwBEXWQ4cpFOZ41fEUYXhGGiy83vCYMXyVamyww9CYvqF/DdSSE7TBxa9Q2
+            JjR0IqYS2TepyE3D3Vx0SqZPYZDSyzJ0taJkyo5B/RshoKathjGkVIxiXLKW
+            1ZAUMscEQ4f5dd0ou364/mQm1z4L06mnDGrdLji70kqjuQoL7zcYIqLVRo1m
+            IpTMZETku3hLIL1NGsfbNGsMPecjUmcasGIGLgLUMIU7AuPdRol5FUHRY73o
+            2K5Xqxc9p3aGAZpNpZkew7Bo2f8MoxiceQHwHo3zDoN2hoYJvxoqm1cnxTJF
+            zOS2HY9c01s7lfTSTuV0qLubF8umZ5QMzyAdr+wE6P0xsUTFAkLZJv2uJSQC
+            4CUK/NPx3ojKB7jK9eM9lT6uR1SuhGjvoD1Iu0J7gPYY7Vw5+WZu4Hhvik+w
+            ha6esM7jfCJw8kM4qAT10FJcV0iOTim6Gg8OsAn28K/vGrcdurak6510GyMd
+            k7ouXSddN+l6TnWX9N6V7tOoCmUUDyphPXLyLeMiZaKBCok3Sp+3S/LnsFg2
+            XHfVqxdub3vUDTFvNI85snhUrxTM2hOjUDbFFDhFo5w3apaQfWXnqmcUt5eN
+            qi+rq069VjQzlhAGV+q2Z1XMvOVadDtv245neBYNACapcUHJao/4EdFJ9DOE
+            MGk+JSkt+KY9NPIr1Od04PiM1rBUhvG5dJAG6KATNUk8Md/5LlmLu8EX0NcO
+            0dvTf4B44gBX9dQBhg5w42eJ3AoyiNdkDkw8XD/ITT8DRWRwhFvtPsopMD1F
+            32e4mXXiCLf32xxCpyBjsrwLQCbbfVog9Jp8nxWqTszg1dE/wZ8hFNgfPQY/
+            wJsPEjeO8M73QhPcl5R9QWsEPPoPurmM2k9K8vQzEadp3JM5zGDWjy9aI6yi
+            IqfRI8y1kmq4R/2kxEm661y8Rd991ndXRw6xMDL8G9RfLmxfI5Z6GkuVc8Ao
+            5iLu+7GGfHp44nkbMbwxNfogHiDjW98iWsRd9AX4WuIQD9tbFkVWOnWL/197
+            y5qDxi4YrkEs4X3fYd6vL5YYJrafIRL8EcFAi+8QuDZ3lq4Ycj7bMSzLEjm+
+            lObrMGi36fSI9sfk+sE6All8mMVKFqt4Qkd8lEUeH6+DufgEa+voc6G5eOoi
+            ItdFF/ddhFyEXcxIzbSLKRd3XIxJMeki5eK6PHe6iP0HcneOKFoIAAA=
             """,
             """
             androidx/compose/ui/foo/InlineAndValueClassStubKt.class:
-            H4sIAAAAAAAAAIVU31PbRhD+Tv4lZEMMJCQQIElxE+zEkSH0p9sk1IlTJcbt
-            xAwvPHTOsoDDssRIJ0/60mH6X/Sx/Qs6faJ96HjoW/+oTlayQ2qC8YP2dve+
-            29v9dk///vfX3wA28JJhjTstzxWtN7rpdo5c39IDoe+5rm44tnCsTae1w+3A
-            qtjc9xsyaL6SKTCG7CHvct3mzr7+XfPQMskbY5gS0aFiacP5Yeuly/BktXZR
-            /C23JfaE5ZWr+cv3GVZqrrevH1qy6XHh+Dp3HFdyKVzS666sB7ZNqExOHgg/
-            179ehcqw3HYlGfpht6MLR1qew22qSXoURJh+ChrDNfPAMtuDKN9zj3csAjLc
-            W62dL6/8P08jDLJfzu9kkMGkhjSmGHKjeNy2fPmunhSyDKpRb2xv1ivPGe5e
-            WP35U+UMZjA7gWlcZVi8jK8U5hji8sByGB6PoX4M8xncwHwa17FAXI5rUrJP
-            PAOrMswND0GuZe3xwJYMr8cNg/Eh7WPnY/ny+U3hDg2rSdMivcCUrlcUnSOb
-            SFqt5qsZrCCn4SN8nEECSQ0K7jFMdsOBL64VxSteNRnS/dmKvCoKDIlIpfEZ
-            Ar6vc2lUStFLSuGhBj28Mt+/co1hujaY1i1L8haXnApTOt0YPVIWimQoQPS2
-            Q0WhzTci1Eqktej8j73jq1rvWFNuKP1PjUVr73jhTpaEUmIF+tZVVembyj8n
-            rHdMgp3+loyrsWycgIkhXGglh2GpbPz0ZyVN4ee1hHr663KJhQmsM9weOcj9
-            NlA9t0ZCIloIsTDil/OwTaTGK26LOL9SI0Q96DQtb5s3bfLM1FyT2zvcE6E9
-            cN58HThSdCzD6QpfkGvz/W+D3ur53bO3PwSbbEhutrf40SCo1nADz7SqIjTm
-            BzF2PoiPNWpqPGwYyflwsBDDN2S9IL9C62xhZuIEVwp/4FoP1//ETQW/h21F
-            JWw1tTmJKTwjfa4Ph4rFKNwslrBM+88HuBStVfomlIGB7ARu4TZZ4X3rgzym
-            F+M//QI1c4K7zworJ1jt3/aCZAwsfXYtMEn55i/K9/6YfGeG8i2c5ftgfL7F
-            S/ItRfmuj8x3mtzfRpubMGitkPcRMb6xi5iBTwx8auAzfG7gC3xpoIyvdsF8
-            fI3Hu1B9LPlY9PHER8JH0scDH0995N8CsSzNZB0HAAA=
+            H4sIAAAAAAAA/4VUXVPbRhQ9K38JY4iBBAIBJy1uAm6NbJd+uk1KnThVMG4n
+            ZnjhIbOWBSyWJUZaefLUYfov+tj+gk6faB86HvrWH9Xpla0CJhg/6O7eu0d3
+            z557d//598+/AGyixlDkdst1ROutZjidE8czNV9oB46j6bYlbHPLbu1xyzcr
+            Fve8hvSb2zIBxpA+5l2uWdw+1L5vHpsGRSMM06L/U76wab/ZeeUwPFur3ZR/
+            x2mJA2G65er67esMqzXHPdSOTdl0ubA9jdu2I7kUDs3rjqz7lkWoVFYeCS87
+            2F6FypBpO5Ic7bjb0YQtTdfmFp1JupREGF4CSYZ7xpFptMMsP3CXd0wCMjxZ
+            q10/XvlKpBEkOSyv76WQwlQSk5hmyI7Scdf05P/nSSDNoOr1xu5WvfKC4fGN
+            p7/+VzmFWcxNYAZ3GZZv0yuBeYaoPDJthqdjpB+jfAr3sTiJBSwxLFxV941f
+            al3UNzOufPHBTwysyjA/3B7ZlnnAfUsyvB7XJvq7BRnbOZnbOzuB96mNDeoj
+            6fqGdNy86JxYJN9adb2aQhYfJLGKxynEEE9CwRrDVDe4CvliXmzzqsEwOdCl
+            H1XxIcPilUCgUzEwITjWj1LTDSW51GBlFN3+/UugkEQxoJMb0PmYYaYW9viO
+            KXmLS06HVjrdCF1tFpiJwICkbwcThRbfimBWoFmryNDpnd5N9k6Tyn1l8KmR
+            /tg7XcqkySgFlqOvpKrKwFX+PmO90/Nf41E1ko4SKDaECbz4JSSRjp7/pCSS
+            MfX8l0yBBZuWGB6NbPlBWegMD0dC+lIQYmnE47TRJiGjFadFOt+pEaLud5qm
+            u8ubFkVma47BrT3uisAPgw9e+7YUHVO3u8ITFNq6fGDoVl9fvXglhmBTDcmN
+            9g4/CZMmG47vGmZVBM5imGPvnfxUUAXRoEhkF4NGQwTPyXtJcYXGudzsxBnu
+            5H7HvR4W/sADBb8FpcQLsnEqbRzTqNJ8fgDHMlb66eaQwUNafxniEjR+F7SE
+            EjpIT+AR3iMv2K8U8phZjv74M9TUGZ48z62eYX2wm042AjZ5sS0wRXxzN/H9
+            aAzf2SG++Qu+G+P5arfwLfX5bo7kO0PhV/3FCrZprFD0E1L8031EdHym43Md
+            X+BLHWV8peNrPN0H8/AM3+xD9ZDxsOJhy0PMQ9zDhodvPeT+A2h8MqZHBwAA
             """,
             """
             androidx/compose/ui/foo/TestModifier.class:
-            H4sIAAAAAAAAAKVUW0/UQBg9Mwu7pRa5eOGmeGFFLkqB+AaSIGLSZFmNkE0M
-            T7PbAQfaDmmnhEfiT/EXSHzAaGI2+uaPMn4tCwlykcSH+W5zzrffnJnur99f
-            vwN4hmmGsoj8WCt/z23ocEcn0k2Vu6G1uyYTs6J9taFkXAJj6N4Su8INRLTp
-            vq5vyYYpoXAB/5hXXg5kKCNCtjMU51WkzAJDYWy85qAEy0YbOhjazHuVMIxW
-            rjLKXI6XEcPC2LmEE+D45dsMIxUdb7pb0tRjoaLEFVGkjTBKU1zVppoGAaFm
-            rnLA8ku5IdLAeOFOkJTQzeBfPt0xce6/zuCgE702enCDoV2TLDHD8L+Obc03
-            gvwmbPBMfsurrq4tVpeWHQzA6aDiIENPZVsbgrkr0ghfGEFEHu4W6NmwzBQz
-            Awa2TfU9lWX0mLg/Q7I2922b9/N8Nfetnx94f3N/lk+zFyWL//hY5N08g85e
-            dOVnNGIY9CIaRi5Gfk0EqVwKRJKsmrQ+tW0Yht6mkVGh9KJdlah6QLCTi6TX
-            sqR9ydBVIX41DesyXhOEYeit6IYIaiJWWd4qlv/u9UbEIpRGxqea2qs6jRvy
-            lco4Ay1O7cyvY5rUbCOZirQGMnnJj2fyke8iX6B9+hAom6DMzQQl3z5xCPuA
-            Ao7JFhi4hidknSMAZU6ufyeuU5OM/JzQnHzHRBPFyS+4+encBrePQK0GWXSL
-            aqenekqrxFqJhb6TAftyMrX6Bv7uEP2fMXSQFzimcjtGZ8j+WBju0JB311Hw
-            MOzhnof7eEAhHnoYQXkdLMEjjNJ+AifB4wTWH5GWtQCVBAAA
+            H4sIAAAAAAAA/6VUW0/UQBT+pgvbbi1y8cJN8cKKXJQC6osQEkRImiyrEbKJ
+            4Wl2O+BA2yHtlPBI/Cn+AokPGE0M0Td/lPG0LETkIokPM3Mu33dybu3PX1++
+            AXiKZwxlHvmxkv6O21DhlkqEm0p3TSl3RSR6SflyTYrYBGPo2ODb3A14tO6+
+            qm+IhjZROId/xCsvBCIUESFbGYozMpJ6lqEwPFJzYMKy0YISQ4t+JxOGocpl
+            UpnO8SJimB0+k3AMHLnYzTBYUfG6uyF0PeYySlweRUpzLRXJVaWraRAQavIy
+            BZZfijWeBtoLt4LERAeDf3F2R8Tp/6rBQRu6bHTiGkOrorbEDAP/KtuaaQT5
+            JGwYWfstr7q8MledX3DQC6dExj6Gzsqm0gRzl4TmPteciEa4XaC1YdlVyi4w
+            sE2y78hMmyDJn6S2HuzattFj5Odg1/rx3ug52J0yJtgL0zK+fygaHUYGnTpv
+            5Kd6xHDrIpyJYQazCWZw/pwFQ58XUR1iLvJrPEjFfMCTZFmn9fFNwva/SSMt
+            Q+FF2zKR9YBgxztAizavfMHQXiF+NQ3rIl7hhGHoqqgGD2o8lpneNJb/jvWa
+            xzwUWsQngjpeFIk4T0OQai+rNG6IRZmF6G2GqJ1KBhM0lxZqeJFObzYoeh9T
+            1zO9nd4C+emTIm2cNDcbDb2to/uw90gwyHQIBq5QMOQBCECak0+yDVcpSEZ+
+            TmgjQ4+Ofcb1j2eybx4imuxMukG2kylN0jFZU7HQfZxdd06mUF9hvN1Hzyf0
+            7+WGAqbo7iJ3ESMYLZZotYsYo3Kf5Fk8on9W9t+ihaDMb6+i4GHAwx0Pd3GP
+            RNz3MIjyKliCBxgifwInwcME1m+TOp2p9AQAAA==
             """,
             """
             androidx/compose/ui/foo/Value.class:
-            H4sIAAAAAAAAAH1UW1MjRRT+unObDAMMWW6Jew3rEm4bYFdXZRcXkLhBWBRW
-            XBZvk2SAgWQmZiYpHilf9Bf44KPP1JZWKVBuaSH75m+yLE93hoshRVXS3ef0
-            uXznO6fn739//xPAfWwyXDPsQsWxCjvpvFMqO66ZrlrpdcdJrxjFqhkBY9C3
-            jJqRLhr2Rnoxt2XmvQgCDMqG6UkbhkBqIMMQqtUlltEQgRIFR5Qh6G1aLsON
-            +UvzTDC0es6yV7HsjRGrVC4ydKUyA/Nnmet3ZNfTqJuuWsWCWYmgnSH80LIt
-            b1JCWtHQgZgKHVcYNJkmJSE+UtBFpka5bNoFhpHUxTQXM/tZJjT0oFcEjTNc
-            bQbxvOEbwvCqMJy53PC6MLxBpJ6QwNCZalK+hltICts+YtaobIxqaEWbSlTf
-            IQY3DXdzximYPoNBgpdlaD+Lkik6BnVvkBKd2GoYxoCKIYxI0rIaUkLmGGVo
-            Mb+pGkXXD9edysw3TsLEwAsGtWrnnB1ppdFQhYX3WwwRSfbiuijlfzxJFFTK
-            A7wjEr/LcH3b8YqWnd6qldKW7ZkV2yims7ao2bXybgTUd8WomLMCD0N/6iKQ
-            ZtA0PMKkiod4n6bT8TbNCkPsoiHNQr1QMXTN44zjnqhqtk7qioqgGCo979iu
-            V6nmPadyjnN6C8oJIQxJUfzlwy8G9UMRf4FeT42G9Rzv1IZQKpMRPPPymFjG
-            qRXz5wibq5WyNgniEXWcXCyYnlEwPIN0vFQL0GtnYgmLBZRlm/Q7lpAoAS9Q
-            4D+OdgdV3stVrh/tqvTjekTlSoj2FtqDtCu0B2hvo50rx9897j3aHeejbDoW
-            C+s8wUcDrw/Z0e7xT+GgEtRDcwldIWV0XNHVRLCXjbInr38IyNsWXZvT9Va6
-            bSMdk7p2XSddB+lip7oreudSRz00yQrBSgSVsB45/p7xeq5vOSFT4qIIIoZK
-            S9TJmLILktyZouG6y141d3fbo/aIkacnMU8WT6ulnFl5ZuSKphgLJ28UV4yK
-            JWRf2brsGfntBaPsy+qyU63kzYwlhPhS1faskrliuRbdTtm24xmeRROBMWpl
-            UPIcE19COokOhxAmTY6ktOgA7aHBX6G+pANHXjRHKqMoSAdpgBY6CR29ct/5
-            AVmLu/gr6KsH6Ix17yOR3Mc1fWAfN/dx+2eZ+SxIHG9KDEx8O/wgd3wEikBw
-            iP5GH+U0MX0NfJ++E9TJQ9zda3AInSYZluU1STLW6HOWhJ6X7/OcqhNT2Tf0
-            F/iPCAX2ho7A9/H2LGV97zb9D/FY6oN7kjiT1gh49B/0cBm7m5QCbB2POE1h
-            WiKZwQd+FtEgYRUVyIYOkTmDVneP+tDESbrrXLxR333Sd1cHD/BksO83qL80
-            bWI9lnoaS5XTwOg2izk/1k2fJJ582UAPr8+OHsdHmPet+4kcGf8V+GryAE8b
-            GxfFonTqEB/ixsadjBtrMmJxfIxPfIf7fn2a4LyvznkjQxqWfII1LMuqONYl
-            agMbtNt0ekb7p5RhZQ2BLD7L4nkWq3hBR6xl8Tm+WANz8SW+WkOXC83F1y4i
-            cs26mHMRchF2MSM1Uy7GXdxzMSzFlIsBF7fkudVF239hftWt0wgAAA==
+            H4sIAAAAAAAA/31U3VMbVRT/3ZuvzbKETQqUxGLbUNvw1QBVq1IqH21sMLQK
+            FaX4tUlWWEh2Y3bD8Mib/gXO2Edf+iDT0RkFxs44iG/+TY7juTcbYALDzM69
+            95x7zvmd8zvn7j///fEngDdRZOg37HLdscrb2ZJTrTmumW1Y2W8cJ7tsVBpm
+            BIxB3zC2jGzFsNeyT4obZsmLIMCgrJmetGEIZAZzDKGtpsRyGiJQouCIMgS9
+            dctluFq4EGeSodNzlry6Za+NWtVahaEnkxssnCA378jucrtutmFVymY9gi6G
+            8D3Ltrz7MqVlDXEkVOi4xKBJmIxMcUpBD5katZpplxlGM2dhziL7KJMaLqNP
+            BE0yXDkvxdOGrwnDK8Jw7mLD14XhVSK1RQJDd+ac8jVcR1rYDhCzRn1tTEMn
+            YipRfZMYXDfc9TmnbPoMBim9PEPXSZRcxTGoe0ME1LLVMIJBFcMYlaTlNWSE
+            zDHG0GF+2zAqrh+uN5MrtE/C5OAzBrVhF51taaXRUIWF91sMEdFoo04TEcrk
+            ciLyXbwjkN4ljeOtm3WGxNmI1JkmrBiB8wA1TOCOwHi/WeKyiqBosV5ybNer
+            N0qeUz/FAE2m0kqPIS1advEoirGZEfE/oFneotE5xcKYXwxVzWvjYpkgYgqb
+            jlex7OzGVjU7v1XN2ySIkY63LhZMzygbnkE6Xt0K0NtjYomKBYSySfptS0gE
+            wMsU+OfDnSGV93GV64c7Kn1cj6hcCdHeQXuQdoX2AO0x2rly9N103+HOBB9j
+            s12JsM5TfCxw9FM4qAT10HxKV0iOTii6mgr2sTH26O8fmrcdujav6510GyMd
+            k7ouXSddnHSJY90lvXsxfhxVoYxSQSWsR46+Z1ykTDRQIalm6TN2WVI5VzFc
+            d8lrFG9vetQMMW40jgWyeNyoFs36U6NYMcUQOCWjsmzULSH7ys4lzyhtLhg1
+            X1aXnEa9ZOYsISQXG7ZnVc1ly7Xodsa2Hc/wLOo/xqlxQclqQvyF6CT6GUKY
+            NJ+TlBV80x4a+g3qSzpwfEFrWCqj+FI6SAN00Eno6IX5znfJWtwlX0Ff2Ud3
+            oncPqfQe+vXBPVzbw41fJPJJkCTekDkw8W79IDf9DBSRwQFutfsox8D0En2f
+            gVbW6QPc3m1zCB2DjMjyzgEZb/c5AaHH5PssUnViBvuH/wJ/jlBgd/gQfA9v
+            P0zfOMB7PwpNcFdS9hWtEfDov4hzGbWXlOTpZyJOk7gnc5jCfT++aI2wioqc
+            hg8wfZJU0z3qJyVO0l3n4i367vd9d3VoH7NDA79D/fXc9jVjqcexVDkHjG7n
+            8MCPdc2nh6dfthHDm1OjJ/EQOd/6FtEi478CX0nv41F7y6LIS6e4+P21t6w1
+            aOyc4UpiHh/6DjN+fbH0ALH9HJHgCwQDJ3yHwLXp03TFUPDZjmFBlsjxtTRf
+            hUG7TafHtD8h149WEcjj4zwW81jCUzrikzyW8ekqmIvPsLKKHheai2cuInKd
+            c/HARchF2MWU1Ey6mHBxx8WIFDMuBl1cl+dOF7H/AVoTuh9WCAAA
             """
         )
 
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/MultipleAwaitPointerEventScopesDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/MultipleAwaitPointerEventScopesDetectorTest.kt
index 76d37c1..9112ac4 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/MultipleAwaitPointerEventScopesDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/MultipleAwaitPointerEventScopesDetectorTest.kt
@@ -43,7 +43,7 @@
     private val ForEachGestureStub: TestFile = bytecodeStub(
         filename = "ForEachGesture.kt",
         filepath = "androidx/compose/foundation/gestures",
-        checksum = 0xf41a4b04,
+        checksum = 0x1be9b2ef,
         """
             package androidx.compose.foundation.gestures
             import androidx.compose.ui.input.pointer.PointerInputScope
@@ -52,37 +52,35 @@
                 block()
             }
             """,
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2VMQQoCMRAbUQR7EOkDBMWThzl7F1dkL4J+oGzr7oDOlHYK
+        Pt/KejOQEBISAJgCwKRyAT+Yg9k59knIv7GTV5Qc8CGFvVMSxj5kLSlku2ok
+        nVw3nMegVXM0m79lISSORTEKsYZk17eSY2BP3F/H6PLtG3pWW0+WZqb10c7v
+        VVvdwh4+IfeLY6cAAAA=
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAH2NSwrCMBCGR0SErCToVrC4UsghtFakG0EvEJqxBmomJBOo
-                tzfS7gQXw//6YABgCgCTfPNRQaDYamcCWdOrhl6eIqoHJWc0W3KqxcgpYJSr
-                Muj2PKQSGRumULNcVBROunmOS26Wd+1/OLEXxb83nX5TYjk7UJ/ho9j8wMkq
-                63xi5ck6xiDXtxQ9OmNdex2qy3evbJdtzQXs4AM20YY08QAAAA==
-                """,
+        androidx/compose/foundation/gestures/ForEachGestureKt.class:
+        H4sIAAAAAAAA/7VUzU8bRxT/zdr4C0jMBlIgjUOK2/ARsoaGNq2jqBEx7aqO
+        QTGkqjhU4/XiDLZnrN1Zi944Veq/0UPPUU9tDxXKsX9U1Te2IYBpkCL1sLO/
+        9zHv/d57M/P3P3/+BeAhigzrXNYDJeqHjqfaHRX6zr6KZJ1roaTT8EMdBX7o
+        bKqgxL1XX/flb3USjCF7wLvcaXHZcLZqB75H2hjDtf1zvgw/L5SHckTCEbIT
+        aaejhNR+4Gz3/65RVj3V8YvlptItIZ2DbtvZj6RnCBGRAVo7tXsqUJEWklhu
+        KEkg6nEvLpYv0isyNvW/cHm88l5RV64o4fGpw64UuvikuDxc0pOr+jAU5LK+
+        IF9WQcM58HUt4IJK41IqzftlVqJWi9daPrnNv8tNaeNJXrl3dyuJDENCyK5q
+        0ul4tDDMZ1hzCekxjGF8FKO4xrA43ANqdkAUhRc67ik0BzfLcLPh642tF1u7
+        O26l9EN1t7pdqjwrPWOYXLg0kY0bGUxgkmH0TC+TuMmQcivVnaeVjRLD+LlG
+        j2EaM2l8gFkKm9evRJi/eDHW3+vUMIzUWsprMsxddUWIb95EbvlGPrPhv+4M
+        w8SJy3Nfc3oFOOmsdjdGzwUzS9osYGBNAywyHgqDCoTqqwz7x0e5zPFRxspa
+        GWva6sHpPrSyA+H4aLZIeNYqsCWrYK3dy8Zm51PMjtsk2Rk71UOsMGIn7Pg0
+        KyQK8Te/JKxU8ps3P31lUDZlsq0xQ8Q+IXy27NyJsnSofZq8kifWnR97LZw4
+        /6A9aGqG+Iaq01TGq5p7zee8s2MOPcP1MvWpErVrfjDQ2GXl8dZLHggjD5Tp
+        qmhI3h/srRcRNbXtu7IrQkHmp2/vCd21i9ZtHvC2T1M+55apqijw/E1hos8M
+        9rwciodVWIijP5UZjCBB0hpJHmIwk5laXrr/B67H8P3vmPoV8dff/YZbr8kQ
+        w6e0JsC2k7TlIeEMhTKaSSSxTmiuHwAf4nYvwRRyuENpDJrDXfL+zBwC8v68
+        Hwkp+j+i70aMhHSP09vVwhe9dRVf0n+TtB8R3/k9xFzkXXzs4hPcc7GARRdL
+        WN4DC3EfK3tIhxgJ8SDE7RC5EE6Iuz2xECLxLyV8urHMBgAA
         """
-                androidx/compose/foundation/gestures/ForEachGestureKt.class:
-                H4sIAAAAAAAAALVVz08bRxT+Zm1ss0BiNpACaRwS3IYfIWtoadM6Qo2ISVZ1
-                DIohVcWhGq8XZ7C9Y+3OWuSGcqjUf6OHnqOe0h4qRG/9o6q+sQ0BTIIUqZY8
-                870337z55s2b2X/+/fMvAF/iW4YV7lcDKar7tiubLRl69q6M/CpXQvp2zQtV
-                FHihvS6DAndfPuna36skGEN6j7e53eB+zd6o7HkueWMMV3bPcBl+mS32rREJ
-                W/itSNktKXzlBfZmt3e0s+zKlpcv1qVqCN/eazft3ch3tSAS0kPLJ+OuDGSk
-                hE8q16RPIOpoz88Vz8vLMzb+v2h5uPhRURcv2cLDE8K2L1R+Nb/Qv6XVy/LQ
-                F+SivCBblEHN3vNUJeCCtsZ9Xyre3WYpajR4peERbeZDNKk0k1iZD2crCZMh
-                Ify2rFN1PJjt19PvuUD0MIYxMoQhXGGY688BJTsgicINbecE6sJNM1yveWpt
-                4/nG9pZTKvxU3i5vFkqPC48ZxmYvXMjCNROjGGMYOpXLJK4zpJxSeetRaa3A
-                MHIm0cOYwOQgPsEUhc2qlyLMnr8YKx9VNQwDlYZ06wzTl10R0pvVkRuetk9N
-                eN+dYRg9pjzzFKdXgJPPaLZj9Fww3SQZWF0Dg/z7QqMcoeoSQ3h4kDEPD0wj
-                bZjGhNGBE11opHvG4cHUKuEpI8fmjZyxfDcdm5pJMStukWWZVqqDWG7ASljx
-                CZZL5OJHvyaMVPLp0c/f/f2WHR5oM506em3ETSM1qZdeZqQN1rHw09vPHDsL
-                +8qjCpD+8ejWq04qR88+bPfriiG+Jqt0OiNlxd36M97a0sXPcLVI+SpFzYoX
-                9DxWUbq88YIHQts952BZ1HzePeAbzyNKbtNz/LYIBQ0/endf6M6dH93kAW96
-                dNpnaGZZRoHrrQsdfbI350VfPCzBQBz6RzQMIEHWElkuYtDHNL4wf+8PXI3h
-                x7cY/w3xNz/8jhtvaCCGZWoTYJtJmvIFYZNCac8YkvSRAKa7AfApbnYWGEcG
-                t2gZjaZxm9gruiKI/VU3ElLUf03/azEyBjua3rUGHnTaHL6hfp28d0jvzA5i
-                DrIOPqMWnzu4i1kHc5jfAQuxgHs7GAwxEGIxxM0QmRD3Q9zumHaIxH8TzBqW
-                1AYAAA==
-                """
-
     )
 
     private val stubs = arrayOf(
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ReturnFromAwaitPointerEventScopeDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ReturnFromAwaitPointerEventScopeDetectorTest.kt
index faac842..1ee146d 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ReturnFromAwaitPointerEventScopeDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ReturnFromAwaitPointerEventScopeDetectorTest.kt
@@ -36,7 +36,7 @@
     private val ForEachGestureStub: TestFile = bytecodeStub(
         filename = "ForEachGesture.kt",
         filepath = "androidx/compose/foundation/gestures",
-        checksum = 0xf41a4b04,
+        checksum = 0x1be9b2ef,
         """
             package androidx.compose.foundation.gestures
             import androidx.compose.ui.input.pointer.PointerInputScope
@@ -45,37 +45,35 @@
                 block()
             }
             """,
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2VMQQoCMRAbUQR7EOkDBMWThzl7F1dkL4J+oGzr7oDOlHYK
+        Pt/KejOQEBISAJgCwKRyAT+Yg9k59knIv7GTV5Qc8CGFvVMSxj5kLSlku2ok
+        nVw3nMegVXM0m79lISSORTEKsYZk17eSY2BP3F/H6PLtG3pWW0+WZqb10c7v
+        VVvdwh4+IfeLY6cAAAA=
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAH2NSwrCMBCGR0SErCToVrC4UsghtFakG0EvEJqxBmomJBOo
-                tzfS7gQXw//6YABgCgCTfPNRQaDYamcCWdOrhl6eIqoHJWc0W3KqxcgpYJSr
-                Muj2PKQSGRumULNcVBROunmOS26Wd+1/OLEXxb83nX5TYjk7UJ/ho9j8wMkq
-                63xi5ck6xiDXtxQ9OmNdex2qy3evbJdtzQXs4AM20YY08QAAAA==
-                """,
+        androidx/compose/foundation/gestures/ForEachGestureKt.class:
+        H4sIAAAAAAAA/7VUzU8bRxT/zdr4C0jMBlIgjUOK2/ARsoaGNq2jqBEx7aqO
+        QTGkqjhU4/XiDLZnrN1Zi944Veq/0UPPUU9tDxXKsX9U1Te2IYBpkCL1sLO/
+        9zHv/d57M/P3P3/+BeAhigzrXNYDJeqHjqfaHRX6zr6KZJ1roaTT8EMdBX7o
+        bKqgxL1XX/flb3USjCF7wLvcaXHZcLZqB75H2hjDtf1zvgw/L5SHckTCEbIT
+        aaejhNR+4Gz3/65RVj3V8YvlptItIZ2DbtvZj6RnCBGRAVo7tXsqUJEWklhu
+        KEkg6nEvLpYv0isyNvW/cHm88l5RV64o4fGpw64UuvikuDxc0pOr+jAU5LK+
+        IF9WQcM58HUt4IJK41IqzftlVqJWi9daPrnNv8tNaeNJXrl3dyuJDENCyK5q
+        0ul4tDDMZ1hzCekxjGF8FKO4xrA43ANqdkAUhRc67ik0BzfLcLPh642tF1u7
+        O26l9EN1t7pdqjwrPWOYXLg0kY0bGUxgkmH0TC+TuMmQcivVnaeVjRLD+LlG
+        j2EaM2l8gFkKm9evRJi/eDHW3+vUMIzUWsprMsxddUWIb95EbvlGPrPhv+4M
+        w8SJy3Nfc3oFOOmsdjdGzwUzS9osYGBNAywyHgqDCoTqqwz7x0e5zPFRxspa
+        GWva6sHpPrSyA+H4aLZIeNYqsCWrYK3dy8Zm51PMjtsk2Rk71UOsMGIn7Pg0
+        KyQK8Te/JKxU8ps3P31lUDZlsq0xQ8Q+IXy27NyJsnSofZq8kifWnR97LZw4
+        /6A9aGqG+Iaq01TGq5p7zee8s2MOPcP1MvWpErVrfjDQ2GXl8dZLHggjD5Tp
+        qmhI3h/srRcRNbXtu7IrQkHmp2/vCd21i9ZtHvC2T1M+55apqijw/E1hos8M
+        9rwciodVWIijP5UZjCBB0hpJHmIwk5laXrr/B67H8P3vmPoV8dff/YZbr8kQ
+        w6e0JsC2k7TlIeEMhTKaSSSxTmiuHwAf4nYvwRRyuENpDJrDXfL+zBwC8v68
+        Hwkp+j+i70aMhHSP09vVwhe9dRVf0n+TtB8R3/k9xFzkXXzs4hPcc7GARRdL
+        WN4DC3EfK3tIhxgJ8SDE7RC5EE6Iuz2xECLxLyV8urHMBgAA
         """
-                androidx/compose/foundation/gestures/ForEachGestureKt.class:
-                H4sIAAAAAAAAALVVz08bRxT+Zm1ss0BiNpACaRwS3IYfIWtoadM6Qo2ISVZ1
-                DIohVcWhGq8XZ7C9Y+3OWuSGcqjUf6OHnqOe0h4qRG/9o6q+sQ0BTIIUqZY8
-                870337z55s2b2X/+/fMvAF/iW4YV7lcDKar7tiubLRl69q6M/CpXQvp2zQtV
-                FHihvS6DAndfPuna36skGEN6j7e53eB+zd6o7HkueWMMV3bPcBl+mS32rREJ
-                W/itSNktKXzlBfZmt3e0s+zKlpcv1qVqCN/eazft3ch3tSAS0kPLJ+OuDGSk
-                hE8q16RPIOpoz88Vz8vLMzb+v2h5uPhRURcv2cLDE8K2L1R+Nb/Qv6XVy/LQ
-                F+SivCBblEHN3vNUJeCCtsZ9Xyre3WYpajR4peERbeZDNKk0k1iZD2crCZMh
-                Ify2rFN1PJjt19PvuUD0MIYxMoQhXGGY688BJTsgicINbecE6sJNM1yveWpt
-                4/nG9pZTKvxU3i5vFkqPC48ZxmYvXMjCNROjGGMYOpXLJK4zpJxSeetRaa3A
-                MHIm0cOYwOQgPsEUhc2qlyLMnr8YKx9VNQwDlYZ06wzTl10R0pvVkRuetk9N
-                eN+dYRg9pjzzFKdXgJPPaLZj9Fww3SQZWF0Dg/z7QqMcoeoSQ3h4kDEPD0wj
-                bZjGhNGBE11opHvG4cHUKuEpI8fmjZyxfDcdm5pJMStukWWZVqqDWG7ASljx
-                CZZL5OJHvyaMVPLp0c/f/f2WHR5oM506em3ETSM1qZdeZqQN1rHw09vPHDsL
-                +8qjCpD+8ejWq04qR88+bPfriiG+Jqt0OiNlxd36M97a0sXPcLVI+SpFzYoX
-                9DxWUbq88YIHQts952BZ1HzePeAbzyNKbtNz/LYIBQ0/endf6M6dH93kAW96
-                dNpnaGZZRoHrrQsdfbI350VfPCzBQBz6RzQMIEHWElkuYtDHNL4wf+8PXI3h
-                x7cY/w3xNz/8jhtvaCCGZWoTYJtJmvIFYZNCac8YkvSRAKa7AfApbnYWGEcG
-                t2gZjaZxm9gruiKI/VU3ElLUf03/azEyBjua3rUGHnTaHL6hfp28d0jvzA5i
-                DrIOPqMWnzu4i1kHc5jfAQuxgHs7GAwxEGIxxM0QmRD3Q9zumHaIxH8TzBqW
-                1AYAAA==
-                """
-
     )
 
     private val stubs = arrayOf(
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/UiStubs.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/UiStubs.kt
index eef686d..4618e50 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/UiStubs.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/UiStubs.kt
@@ -24,34 +24,34 @@
     val Density: TestFile = bytecodeStub(
         filename = "Density.kt",
         filepath = "androidx/compose/ui/unit",
-        checksum = 0x8c5922ca,
+        checksum = 0xcc05f7d8,
         """
             package androidx.compose.ui.unit
 
             interface Density
         """,
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2VMQQoCMRAbUQR7EOkDBMWThzl7F1dkL4J+oGzr7oDOlHYK
+        Pt/KejOQEBISAJgCwKRyAT+Yg9k59knIv7GTV5Qc8CGFvVMSxj5kLSlku2ok
+        nVw3nMegVXM0m79lISSORTEKsYZk17eSY2BP3F/H6PLtG3pWW0+WZqb10c7v
+        VVvdwh4+IfeLY6cAAAA=
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAH2NSwrCMBCGR0SErCToVrC4UsghtFakG0EvEJqxBmomJBOo
-                tzfS7gQXw//6YABgCgCTfPNRQaDYamcCWdOrhl6eIqoHJWc0W3KqxcgpYJSr
-                Muj2PKQSGRumULNcVBROunmOS26Wd+1/OLEXxb83nX5TYjk7UJ/ho9j8wMkq
-                63xi5ck6xiDXtxQ9OmNdex2qy3evbJdtzQXs4AM20YY08QAAAA==
-                """,
+        androidx/compose/ui/unit/Density.class:
+        H4sIAAAAAAAA/4VOTUvDQBB9s9GmjV+pWqg38Qe4benNkyBCoCIoeMlpm6yy
+        bbor3U2pt/4uD9KzP0qcqHdn4M17M/DefH69fwAYo0c4V7ZcOlOuZeEWr85r
+        WRtZWxPkjbbehLcYREhnaqVkpeyLvJ/OdBFiRITuZO5CZay800GVKqgrglis
+        IvamBjoNgEBz3q9NowbMyiGht920E9EXiUiZPfe3m5EYUHMcES4m/z3FQeyb
+        /KnLeWDx6OploW9NpQlnD7UNZqGfjDfTSl9b64IKxlnf4gzs4LcETn7wGKc8
+        h2y5y93KEWWIM7QzdJAwxV6GfRzkII9DHOUQHqlH9xtDUhD7SQEAAA==
         """
-                androidx/compose/ui/unit/Density.class:
-                H4sIAAAAAAAAAIVOTUvDQBB9s9Gmxq/UD6g38Qe4benNkyBCoCIoeMlpm6wy
-                Tbor3U2pt/4uD9KzP0rcqHdn4M17M/DefH69fwAY44Rwrky5sFyuZGHnr9Zp
-                2bBsDHt5o41j/xaDCOlMLZWslXmR99OZLnyMiNCbVNbXbOSd9qpUXl0RxHwZ
-                BW9qISZQFVYrbtUgsHJION2su4noi0SkgT33N+uRGFB7HBEuJv/9EzJASP7U
-                ZeWDeLTNotC3XGvC2UNjPM/1Ezue1vraGOuVZ2tcJ2RgC78lcPSDPRyHOQyW
-                26E7OaIMcYZuQOy0kGTYxV4OctjHQQ7hcOiQfgOBbqTCRAEAAA==
-                """
     )
 
     val PointerEvent: TestFile = bytecodeStub(
         filename = "PointerEvent.kt",
         filepath = "androidx/compose/ui/input/pointer",
-        checksum = 0xbe2705da,
+        checksum = 0x7fd06e9b,
         """
             package androidx.compose.ui.input.pointer
 
@@ -65,60 +65,60 @@
                 val id: PointerId
             )
         """,
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2VMQQoCMRAbUQR7EOkDBMWThzl7F1dkL4J+oGzr7oDOlHYK
+        Pt/KejOQEBISAJgCwKRyAT+Yg9k59knIv7GTV5Qc8CGFvVMSxj5kLSlku2ok
+        nVw3nMegVXM0m79lISSORTEKsYZk17eSY2BP3F/H6PLtG3pWW0+WZqb10c7v
+        VVvdwh4+IfeLY6cAAAA=
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAH2NSwrCMBCGR0SErCToVrC4UsghtFakG0EvEJqxBmomJBOo
-                tzfS7gQXw//6YABgCgCTfPNRQaDYamcCWdOrhl6eIqoHJWc0W3KqxcgpYJSr
-                Muj2PKQSGRumULNcVBROunmOS26Wd+1/OLEXxb83nX5TYjk7UJ/ho9j8wMkq
-                63xi5ck6xiDXtxQ9OmNdex2qy3evbJdtzQXs4AM20YY08QAAAA==
-                """,
+        androidx/compose/ui/input/pointer/AwaitPointerEventScope.class:
+        H4sIAAAAAAAA/51Qu04CQRQ9d1F5+AAUFTvjBzhALIxWJGqyCUYjiQ3VsDua
+        gWVmw9xF7PguC0PtRxlntaGgspgz5965j3Pm6/vjE8AFjgmX0sRTq+O5iOwk
+        tU6JTAtt0oxFarVhNRXdN6n58S+4nSnD/cimqggi1EZyJkUizat4GI5UxEUU
+        CKfrZmZGs7hRxml+L2KTUO+NLSfaiHvFMpYsrwnBZFbwyiiHcg4g0Njn5zqP
+        Wp7FbUJjuShVgmaQn9JLc7noBC3K3zqEq95/Hfn9Z2ubV6X7oupq5/mYCZW+
+        zaaRutOJIpw8ZYb1RD1rp4eJ6hpjWbK2xm15idjwlrZyZ54f/mIDR/5u+7z/
+        F5QGKIQoh6iE2MaOp9gNsYfqAORQQ32AwGHf4eAHKmYZqccBAAA=
+        """,
         """
-                androidx/compose/ui/input/pointer/AwaitPointerEventScope.class:
-                H4sIAAAAAAAAAJ1QTU8CMRB9syiL+AEoGrwZf4AFwsHoiURNSDAaSbxwKrvV
-                FJZ2Q2cRb/wuD4azP8rY1QsHTjbpm77Xzsybfn1/fALo4IRwKU08szpeiMhO
-                U+uUyLTQJs1YpFYbVjPRfZOaH//I7VwZHkQ2VSGIUB3LuRSJNK/iYTRWEYco
-                EM421cyMZnGjjNP8HmKbUOtPLCfaiHvFMpYsrwnBdF7wziiHkEATLy10zpr+
-                FLcI9dWyVA4aQb5LL43Vsh00Kb9rE676/x3Gtz7fmLzu2j+qrGdeTJhQHths
-                Fqk7nSjC6VNmWE/Vs3Z6lKiuMZYla2tc0VvEFghF5CtA/RePcOxjy+v+S1Aa
-                otDDTg9lj9jNYa+HfRwMQQ4VVIcIHGoOhz/oLRV0wgEAAA==
-                """,
+        androidx/compose/ui/input/pointer/PointerId.class:
+        H4sIAAAAAAAA/5VQTW8SQRh+ZpZdlhVkwS+KH9XWQ4vRpY03TaM2mkBQm2q4
+        cBrYSZ0Cs4SdJT3yW7x7MNGYeDDEoz/K+M5CPHkxmXnmfd558rwfv35//wHg
+        Me4zPBA6nicqvohGyXSWpDLKVKT0LDPRLFHayHl0sn47cRGMITwXCxFNhD6L
+        3g7P5cgU4TB4T5VW5oihsNfd7zM4e/v9MlwUAxTgM7gLMckkA+uWEeBSCRxl
+        EpsPKmV42PuPJp4w+GfS9Nd+VKfLUOuNEzNROnotjYiFESTi04VDQzILJQug
+        6mPKXyjL2hTFBwzHq2U94A0e8HC1DOjwsBRw32msloe8zV5U6l7Im7zt/Pzo
+        8bBwWvvLfFI3C74betbqkNkC1U2bLxdSm0djQyMeJzH1We0pLd9k06GcvxfD
+        CWXqvWQkJn0xV5ZvksG7JJuP5CtlydZppo2ayr5KFf0+1zoxwqhEpzig/RXy
+        kep2nRRxil14hNvEjuDAThm0vqHU2v6Kyudcc5fQagAf9wivU45UuIyq3RBF
+        1o0WipDu2ivKvQG39QWVT/+0Ka8FGxuOnRzvYJfeZ3mTLq4M4HRwtYNrHSp7
+        g0I0OthCcwCW4iZuDVBMUU1xO0WQo5ciTFH7Azsv3rCuAgAA
+        """,
         """
-                androidx/compose/ui/input/pointer/PointerId.class:
-                H4sIAAAAAAAAAJVQTW8SQRh+ZpZdlhVkQa0UP6r20mJ0aeNN06iNJhD8SGu4
-                cBrYSTsFZgk7S3rkt3j3YKIx8WCIR3+U8Z2FePJiMvPM+7zz5Hk/fv3+/gPA
-                E+wyPBQ6nicqvoxGyXSWpDLKVKT0LDPRLFHayHn0fv124iIYQ3ghFiKaCH0W
-                vRteyJEpwmHwnimtzBFDYa+732dw9vb7ZbgoBijAZ3AXYpJJBtYtI8CVEjjK
-                JDbnKmV41PuPJp4y+GfS9Nd+VKfLUOuNEzNROnojjYiFESTi04VDQzILRSo8
-                ptSlsqxNUXzAcLxa1gPe4AEPV8uADg9LAfedxmp5yNvsZaXuhbzJ287Pjx4P
-                Cye1v8wndbPgu6FnrQ4ZlUF10+GrhdTm8djQdMdJTC1We0rLt9l0KOcfxHBC
-                mXovGYlJX8yV5ZtkcJpk85F8rSzZPsm0UVPZV6mi3xdaJ0YYlegUB7S6gh0M
-                dbtJijjFLjzCu8SO4MBOGbS+odTa+YrK51yzQ2g1gI97hFuUIxWuogrkkXWj
-                XSKku/aKcm/AbX1B5dM/bcprwcaG436Od/CA3ud5ky6uDeB0cL2DG4TYsnCz
-                gwa2B2Apmrg1QDFFNcXtFEGOXoowRe0P2i862KkCAAA=
-                """,
+        androidx/compose/ui/input/pointer/PointerInputChange.class:
+        H4sIAAAAAAAA/5VSXU8TURA9d7dfLAXaIlJA8QOUUoQthPiCMSrRZJO1EjC8
+        8HTbvSm3H3fJ7m3DI7/FX6CJRuODIT76o4xz2w0IvkiymTNnMnNmdub++v39
+        B4BtbDBscxVEoQxO3WbYOwlj4falK9VJX7snoVRaRO7eCD0T3D3mqiWyYAyF
+        Nh9wt0vcfddoi6bOwmbIPJNK6ucMtYr//9LBzuohw5IfRi23LXQj4lLFLlcq
+        1FzLkPx6qOv9bneHwZJBDjmGxU6ou1K57UHPHaoo3nU9pSMqlc04C4dhpnks
+        mp2kdo9HvCcokWGl4l+ffuevyIERadFMeeQx4WAckwx2xfA0Cg5SKDKs3+j/
+        8shhegwWbjGk9LGMGZ7eQOBy97SBdEtoL2BwK6s3moGh6CdLeys0D7jmZp+9
+        gU2vgRkzZgwYWIfip9KwGnnBJsPu+VnJscqWYxXOzxz6hn7OLp+fbVk19mqi
+        lClY81bN/vkhYxVS+8ULlqPs+VQuXcgYqS1mGkwlU70eCKU3OpphYb+vtOwJ
+        Tw1kLBtd8fLy+rSy3TAQVOZLJer9XkNE7znlMJT8sMm7hzyShifB5etaF6e/
+        IuochP2oKd5IUzOX1Bz+0x2bdLbUcC8lc0XCFWIZwiyhRZgmZqFCzCe0CAtr
+        pbFvmKp+Ram69gUzn4aZq2QnYVO2A/OspshWKXZ7VEM4aw5A3qjPGvlZljQq
+        ooy5pI1rjkSYrn7GzMcL7cwwOD7UzI8SEs2rEz8Z2sdYJ3xB0XnKWziC7eGO
+        h7seFnGPXNz38AAPj8BiLGH5CNkYszEexcjFmI6RiVGOMfcHIp5sr08EAAA=
         """
-                androidx/compose/ui/input/pointer/PointerInputChange.class:
-                H4sIAAAAAAAAAJVSXU8TURA9d9tul6XItogUUPwApRRxCyG+YIxKNGlSkYDh
-                hafb3Zty2+1dsnvb8Mhv8RdootH4YIiP/ijj7HYDgi+SbObMmcycmZ25v35/
-                /wFgE2sMm1z5USj9E9cL+8dhLNyBdKU6Hmj3OJRKi8jdHWEzCW4fcdURRTAG
-                p8uH3A2Iu+/aXeHpInIM5jOppH7O0Ki1/l/a31o5YFhshVHH7QrdjrhUscuV
-                CjXXMiR/J9Q7gyDYYjCkb8FiWOiFOpDK7Q77bqqieOA2lY6oVHpxETbDtHck
-                vF5Wu8sj3heUyLBca12dfuuvyH4i0qGZSihhwsY4bjDkagkvwLGRR5lh7Vr/
-                V4KFqTEYuMmQ10cyZnh6DYGL3dMGCh2hmz6DW1u51gwM5Va2tLdCc59rnuyz
-                P8zRa2CJKTKwHoVOZMIa5PnrDNtnpxXbqBq24Zyd2vSlvpWrnp1uGA32aqJi
-                Osac0cj9/GAaTn6vfM4syp7LWwXHTKQ2GLXBZDbQ66FQ+klPM8zvDZSWfdFU
-                QxnLdiBeXhyetrUd+oLKWlKJnUG/LaL3nHIYKq3Q48EBj2TCs+DSVa3zq18S
-                tffDQeSJNzKpmc1qDv7pjnW6WD7ZDirJAQkfETMJi4QGYYGYgWViLUKD0Fmt
-                jH3DZP0rKvXVL5j+lGbWyN5AjrJtJC9qkuwKxW6NaghngNQb9aln50gblVHF
-                bNbGRRIFCvXPmP54rm2mwfFUszRKyDQvT7ya2od4TPiConOUN3+IXBO3m7hD
-                FguJudvEPdw/BIvxAIuHKMaYibEUw4oxFcOMUY0x+wcqer7sSgQAAA==
-                """
     )
 
     val PointerInputScope: TestFile = bytecodeStub(
         filename = "SuspendingPointerInputFilter.kt",
         filepath = "androidx/compose/ui/input/pointer",
-        checksum = 0xd7db138c,
+        checksum = 0xa05e1a0a,
         """
             package androidx.compose.ui.input.pointer
             import androidx.compose.ui.unit.Density
@@ -135,59 +135,59 @@
                 block: suspend PointerInputScope.() -> Unit
             ): Modifier = Modifier
         """,
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2VMQQoCMRAbUQR7EOkDBMWThzl7F1dkL4J+oGzr7oDOlHYK
+        Pt/KejOQEBISAJgCwKRyAT+Yg9k59knIv7GTV5Qc8CGFvVMSxj5kLSlku2ok
+        nVw3nMegVXM0m79lISSORTEKsYZk17eSY2BP3F/H6PLtG3pWW0+WZqb10c7v
+        VVvdwh4+IfeLY6cAAAA=
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAH2NSwrCMBCGR0SErCToVrC4UsghtFakG0EvEJqxBmomJBOo
-                tzfS7gQXw//6YABgCgCTfPNRQaDYamcCWdOrhl6eIqoHJWc0W3KqxcgpYJSr
-                Muj2PKQSGRumULNcVBROunmOS26Wd+1/OLEXxb83nX5TYjk7UJ/ho9j8wMkq
-                63xi5ck6xiDXtxQ9OmNdex2qy3evbJdtzQXs4AM20YY08QAAAA==
-                """,
+        androidx/compose/ui/input/pointer/PointerInputScope.class:
+        H4sIAAAAAAAA/51Ty24TMRS9nsljklKYDlDSFtqSlpdQmRBg04SKClo1VYAq
+        idh05UzcyOnEjsae0O7yLSz4CBYo6pIf4S8Qd/JQSxsRxML28fXx9T328Y9f
+        374DwEt4SOAFFY1A8saJ68l2RyrmhtzlohNqtyO50CxwD4ZjKQpWPdlhSSAE
+        7BbtUtenoul+rLeYp5NgElidlC4UXLvvmFBcnyYhTmCefqZcj/LudJkY5iVQ
+        e1w+ltrnwm112+5RKDzNpVDu7gjlC+N1TwYy1Fww5b6VAkFII0LhSflyXQUC
+        P4uVzavxrWmHFTfK029ne6KUwsaUQosbtUphq/B0QlnTNI62TlS6XpZB020x
+        XQ8oRy1UCKnpUNeH0Pdp3WdIW/sbTeqIiay5cSHvmaYNqinGjHbXRO+QqEtF
+        HRAgxxg/4dEsh6jxnIDq97JpI2MMm2We46jZ/d4A9HvWUabfyxs5sv/aNhaN
+        PTMbs/o928w/smOLaxZxYo6RSzhpx4rQnplLOgknliE5Kxc/+5IwrNTe2dc3
+        EbLT0dF5Aq/+4dGuWBqVZSfuu+hdJJEKgXjdlx5KdsbXc+5OApv/bxn8PdPc
+        TaLrXh6zdk50VJgU4wJqp4M0K9VQdZhocNG8KHSX+wifHWsCqSpvCqrDAP/c
+        UiXEE9qsJLpccfTH9rkZ0FCXVw9oQNsME/1BS1dlGHgMj8CMC6M9n67kS+Ab
+        QQw1JCLjxAgkwQIT7uPMgBRkcUzgahrHNWyzBk5mBh6bGVDWB/0qPMCxjNFr
+        EIfZQzBLcL0EN0pgwxxCcEpwE24dAlFwG+YPYUbBHQUZBUkFCwoWFSwpuKvg
+        noJlBSsKrN90t5jzEwUAAA==
+        """,
         """
-                androidx/compose/ui/input/pointer/PointerInputScope.class:
-                H4sIAAAAAAAAAJ1T3U4TQRQ+s7vtLkV0WRULKGDBqDG4teoNJQSiEEqqkpZ4
-                w9V0uzRTtjPNzmyFu42P4oXPYLwwDd75Ir6F8Wx/AkJjjRdz5syZb84538w3
-                P359/QYAL+ABgeeU10PB6ieuJ1ptIX03Yi7j7Ui5bcG48kN3vz+XkmDVE23f
-                BELAbtIOdQPKG+67WtP3lAk6gaVR6SLOlPva55KpUxNSBGboB8rUIO92x+f9
-                vAQOHpWPhQoYd5udlnsUcU8xwaW7M/AKxeG+J0IRKcZ96b4SHJ2IJoDi4/Ll
-                vooEfq5X1q7GN8YVW18tj7+drZFUiqtjGl1fPagUN4pPRrQ1juPg6EimK2UR
-                Ntymr2ohZciFci4U7fN6GwUBrQU+wpb/BhMqQSJqetjIG1/ROlUUY1qro6N2
-                SGJMAuQYQycsWeXRqz8jEHfjXEbLav1h6ed+Muxu3HO6sXWU7cYFLU/2Nm1t
-                TtvVc4bVjW298NA25pYt4hiOlk87GcdKvF09bzppx8iSvJVPnX1Ka9bE7tnn
-                ze9fSDdOlnbm7KNmYMHZpI8CgZf/8HhXpI0McyPPXdQwgkiFQKoWCA/5O8Nr
-                OlcpgbX/lw7+onEqJ/gCsDBEbZ+opDHBhw0cnPbSLFYj2fZ5nfHGRaI7LED3
-                6bEiMFFlDU5VFOLfm69EWKHll3iHSYY62ToXBQrr8u4+DWnLx0R/wDJVEYWe
-                jyUw4+zgzPsr+dL4RmAgh3SiJYOACRbosIQrDSbgPs5p3M3gnMMxpeFiMoH2
-                rAbLPbsIKziXMXoNUjB1CHoJrpfgBlqwEzNdAgduHgKRcAtuH8KkhBkJdySY
-                ErISZiXMSZiXcFfCPQkLEqzfOHmKfRsFAAA=
-                """,
+        androidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt.class:
+        H4sIAAAAAAAA/61VW28bRRT+Zu34VkPcDSmJE9KUmObSpusYym2jiBJRycIN
+        BZe85Gm8nroTr2esnd0ofetv4RcgnhAPKOKR38JvQJzZOKnTBAehPuyZc/nm
+        3OYc+8+/f/sdwCfYZviKq26kZffYC/RgqI3wEulJNUxib6ilikXktRMzFKor
+        Ve/pqaZpzY9lSOy3cR6MoXLIj7gXctXzvuscioC0GYbycAzPMFxrXRXsie7K
+        51JEfutNJ36rr+NQKu/waOA9T1QQS62M93jENfz1yQ4Z/nrbIbc3r3R4sWHj
+        bWoHeij8zTO3gY50EksljLerFTEJt363zwE/Khn7O/69y5ntXF/uSktHPe9Q
+        xJ2IS0qbK6VjflrCno73kjAkVG0SiiC8EwqC5bbjF9LsFFBiWBrrSlqb4qHX
+        VHFE92Vg8igzzAYvRNAfhXnKIz4QBGRYXbuiy681beuk56/vl/Eupkt4BxWG
+        qU6og34BLsPipJrzeI+huEsGrih/hsnvXTtH+mXcwvtFzGKOwa3ZSmsXp3Xp
+        umZn++LlFl2+XB3D8nWTy3DzDPJExLzLY046Z3CUocVklhQtAQPrW8Yh47G0
+        XJ24LsU1J69qpZNXJWfOSY8KkZF4/lWckbn6NZmrTp1t0NcoVJxqdo7VM43V
+        Sra6UmBu1nXqObfkFlKuUM+7OTdF1Kf++CnnFIqWVko2dIPZrNyz7MdLevi/
+        dmOsW/+yHb59jRHkm+NY0MxpdRb42cvUx93/9u5527/bk37RHvTp8bO7uisY
+        pluUy14y6Ijomd0KW7cOeLjPI2nlkbLYlj3F4yQifuGHhBIfiKY6kkaS+dHr
+        7aLVe9N6vicXYOWmUiLaDbkxgsRSWydRICg/CjA/crF/yT224CCL07GZxxRy
+        JH1M0vekt6Mzs+He+BU377szRH/B/Almf7azRf8EIDDFxTQeEr98CkcVC6m7
+        GSziA7JbzsUS3fg0vZfHZ6ObBTo/t/bMSKCupNTyGXxBtETSFi3cLcrty/R6
+        Az6dLdLfpmyXD5Bp4k4THzaxgloTH+FuE6tYOwAzWMfGAW4YTBksGCwa3DNw
+        De4bbBo8SEXPIPcPJkHsLNsGAAA=
         """
-                androidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt.class:
-                H4sIAAAAAAAAAK1VW08bVxD+ztrYi0OLs5QWDCW0OOGSkHWcSyMtQq1QIllx
-                aFqnvPB0vD5xDl6fY+0FkTfUn5JfUPUpykOE0rf+lv6GqHOWhZhAjVTF0s7O
-                5Zs5M3Nm1n9/ePsOwD08ZPiRq06oZefA9XV/oCPhJtKVapDE7kBLFYvQbSXR
-                QKiOVN1nx5qGMT+WAbFP4iIYQ3mP73M34Krr/tzeEz5pcwwTgyE8w2CledFh
-                T3VHvpAi9JqfBvGaPR0HUrl7+333RaL8WGoVuY8zru6tjg7I8M/nPnJj/cKA
-                Zxs23KaWrwfCWz8J6+tQJ7FUInK3tCIm4SbuxingNyVjb9O7eT6zzcvLXWrq
-                sOvuibgdcklpc6V0zI9L2NbxdhIEhKqOQhGEtwNBsMJG/FJGmzZKDAtDXUlr
-                UzxwGyoOyV/6URETDNP+S+H3smOe8ZD3BQEZllcu6PJHTcsE6XqrOxP4EpMl
-                fIEyw1g70H7PhsMwP6rmIr5iGN8iA1eUP8Po+66eIr0JfI1vxjGNGQanaiqt
-                np3Whcuane+JV3fI+Xx1DIuXTS7D1RPIUxHzDo856az+fo4WkxlSZGA9w1ik
-                P5CGqxHXoSMPjw6rpaPDkjVjpa8ykUw8fcpWZq48InPFqrE1eup22arkZ1gt
-                V18u5ytLNnPyjlUrOCXHTjm7VnQKToqojb1/XbDs8b/esKNDw5ZL73+38iXL
-                njV51BklStVnVQyXdv9/7chQ1/5jSzxzKxnk0UEsaPa0Ojn4+as0xrVRX6vb
-                PbrY/JbuCIbJJsXfTvptET43E29q0T4PdngojZwpx1uyq3ichMTP/ZpQMn3R
-                UPsykmT+6ePm0Fp9aj3dgTOwUksnoS8oIYo4m/nsnIuHO7CQh/kRDGMokFQj
-                6RfSm2GYWnOuvMHVW84U0T8xe4TpP8y0kCMITF9fTKJO/OIxHBXMpeGmMI9v
-                yW44BwvkcTf1K9IfwrGnTe/7xp7LBGpDSu0U+CClLn6gd5O01yi7xV3kGviu
-                ge+JYqmBKq43cAPLu2ARVrC6iysRxiLMRZiPsBbBiXAzwq0I66l4O0LhX/yB
-                0s2YBgAA
-                """
     )
 
     val Alignment: TestFile = bytecodeStub(
         filename = "Alignment.kt",
         filepath = "androidx/compose/ui",
-        checksum = 0xd737b17c,
+        checksum = 0x72950571,
         """
             package androidx.compose.ui
             class Alignment {
@@ -196,47 +196,47 @@
                 }
             }
             """,
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2VMQQoCMRAbUQR7EOkDBMWThzl7F1dkL4J+oGzr7oDOlHYK
+        Pt/KejOQEBISAJgCwKRyAT+Yg9k59knIv7GTV5Qc8CGFvVMSxj5kLSlku2ok
+        nVw3nMegVXM0m79lISSORTEKsYZk17eSY2BP3F/H6PLtG3pWW0+WZqb10c7v
+        VVvdwh4+IfeLY6cAAAA=
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAH2NSwrCMBCGR0SErCToVrC4UsghtFakG0EvEJqxBmomJBOo
-                tzfS7gQXw//6YABgCgCTfPNRQaDYamcCWdOrhl6eIqoHJWc0W3KqxcgpYJSr
-                Muj2PKQSGRumULNcVBROunmOS26Wd+1/OLEXxb83nX5TYjk7UJ/ho9j8wMkq
-                63xi5ck6xiDXtxQ9OmNdex2qy3evbJdtzQXs4AM20YY08QAAAA==
-                """,
+        androidx/compose/ui/Alignment$Companion.class:
+        H4sIAAAAAAAA/5WTz08TQRTHv7PdtstSpeWH8kNFpEqL2gXiDWOEGpMmBRMg
+        vXAw0+1Yp93Okp1pw7En/xD/AjlpPBjC0T/K+LasQDQRvbx57/ve583svJ3v
+        P75+A/AMFYYVrlpRKFvHnh/2jkItvL70tgLZVj2hTLFKIlcyVFkwhnyHD7gX
+        cNX23jQ7wjdZpBgyz6WS5gVDqlRu5JBGxoWNLINt3kvNUK7/4x6bDONtYQ7C
+        o33DI8OwVLqGJWK5HkZtryNMM+JSaY8rFRpuqJ32dkOz2w8Cqrr71zZZ3GSY
+        4b4vtC5eOUHRP8ohj5yLCRQY1kv1bmgCqbzOoOdJZUSkeOC9Eu94PzBV2tFE
+        fd+E0Q6PuiLaLDdcWPFFTBX9y+Tb3ijLUPm/bgyFX8COMLzFDSfN6g1SNEsW
+        m7HYgIF1ST+WcbRGXmudYft0OO1as5Zr5U+HruVY54FjOWcfUrOnww1rjW1n
+        HevsY8bKW3uFfGreWrMpctzT4bztpPOZuNMGi/s7lxNavHY+YxfjZchdJCpd
+        gu1q2BIME3WpxG6/1xTRAW8GpEzWQ58HDR7JOE7Ehb2+MrInamogtSRp63LS
+        1LqmlIiqAddaUOjuh/3IF69lTM4lZOMPDus0IDu+NaTIo1+XPm+FIi++RlrT
+        q5/hnJBjoUQ2MxJtlMnmzgswBpfWAsZJsUZwJYHtL5j89BubvsLaCbuaZG8A
+        eUYVU8khntJqJYeYPhmNNoZvnYsJHHszpNHzw2OK3BE0gYeYw5PR5o+oEfCS
+        9NtUO3uIVA1zNczXsIA75OJuDfeweAimcR9Lh8hquBoPNDIayxpFjXGN3E/q
+        H9VdNgQAAA==
+        """,
         """
-                androidx/compose/ui/Alignment$Companion.class:
-                H4sIAAAAAAAAAJVTTW/TQBB96ziJ6waa9AP6AZTSQJNC67biVoRog5AipUVq
-                q1x6QBtnCZs468q7iXrMiR/CL4ATiAOKeuRHIcapaSuQKPgwO+/NvJlZj/39
-                x9dvAJ5ijWGFq2YUyuap54fdk1ALrye9nUC2VFcoU6wQyZUMVRaMId/mfe4F
-                XLW814228E0WKYbMM6mkec6QKpXrOaSRcWEjy2Cbd1IzlGv/2GObYbwlzFF4
-                cmh4ZBiWStdoSbFcC6OW1xamEXGptMeVCg03VE57+6HZ7wUBZd39a5ksbjLM
-                cN8XWhevTFD0T3LII+diAgWGzVKtE5pAKq/d73pSGREpHngvxVveC0yFOpqo
-                55sw2uNRR0Tb5boLK34RU0X/MvimO4oyrP9fNYbCL8GeMLzJDSfO6vZTtEsW
-                G+rEOkSdyhhtkNfcZNgdDqZda9Zyrfxw4FqOdQ4cyzl7n5odDrasDbabdayz
-                Dxkrbx0U8ql5a8Mm5LjDwbztpPOZuNIWoy5wLpezeO1qxi42y5C7CKx3SGxX
-                wqZgmKhJJfZ73YaIjngjIGayFvo8qPNIxjghFw56ysiuqKq+1JKoncslU+mq
-                UiKqBFxrQdA9DHuRL17JWDmXKOt/6LBJu7ERPyny6Kul6z0i5NFJd0V69TOc
-                T+RYWCGbGZE2SmRz5wkYg0tnAePEWCPxeiK2v2Dy42/a9BWtnWjLSfQGkGeU
-                MZUMsUanlQwxHQ/BRuJb52Qijr0Z4ujPwyohdySaQBFzeDxq/hBP6HxB/G3K
-                nT1Gqoq5KubJYiE2d6q4i3vHYBqLuH+MrIarsaSR0XigsawxrpH7CTHvlCUx
-                BAAA
-                """,
+        androidx/compose/ui/Alignment.class:
+        H4sIAAAAAAAA/4VSXU8TURA9d7ct7bJKqVIpHwJSpaCyQExMhJhgjUmTUhMh
+        JISn2+213nZ7l+y9bXjkt/gLRB5IJDHER3+UcbYU8COBl5mdc+fMnJnZn7++
+        fQfwAisM01w1olA2Dj0/7ByEWnhd6W0Gsqk6QpkhMIZsi/e4F3DV9N7XW8In
+        1GZIbUglzWsGu7S46yKJlIMEhhgS5pPUDDPVGyuvM4xx3xdaF5vC7IQH24ZH
+        pugfMMyVFm/lpi8ZLu7AycDCXQI3/GAgauHGAsUygVzJUA1hlGG1VG2Hhqhe
+        q9fxpDIiUjzw3oqPvBuYcqi0ibq+CaMtHrVFtH4x7z0HOdxnyFwVY7hF+HXf
+        dRd5PIh1jztkaG3z1TBqei1h6hGXSntcqdBwQ7naq4Wm1g0Cmnv0UumWMLzB
+        DSfM6vRsOieLTSY2YGBtwg9lHNGRrcYqQ/H8yHWsccuxsudHjpW2xs+PZu01
+        a4W9Yvab5I/PKStrxblrLK7gXqlebhuGyQ9dZWRHVFRPalkPxOa1Prp5OWwI
+        hpGqVKLW7dRFtMMphyFXDX0e7PJIxvEAdCtKiagccK0FkZ3tsBv54p2M3wqD
+        Prv/dcEqLSpBA1koxMsjjYsUpchPkp+If4R/MJt8sh8tUeTFeyGfXDpF+rhf
+        6OkgOU59Rta9SECGSiFbwHAficlT/Rcg8RUjX/or/pObRvaqzTL6N0D+DLk9
+        doqxExTOYO2dYuIEI8d/cYepl43nFMXSc6QoT8Mt97WVSDDwkvApypreh13B
+        wwpmKpjFHH3iUQXzKO6DaTzGk30kNByNBY2URv43qNs4vuQDAAA=
         """
-                androidx/compose/ui/Alignment.class:
-                H4sIAAAAAAAAAIVSXU8TQRQ9s9uWsqxSqlTKh4BUKagsEBMTISZYY9KkYCKE
-                hPA03Y512u0s2ZlteOS3+AtEHkgkMcRHf5TxbikQNIGXe/eeOffcc2f2958f
-                PwG8gscwxVUjCmXj0PPDzkGohRdLbyOQTdURygyAMeRavMu9gKum97HeEj6h
-                NkNmXSpp3jLY5YVdF2lkHKQwwJAyX6RmmK7dqrzGMMp9X2hdagqzEx5sGx6Z
-                kn/AMFteuLM3e9nh4h6cQVi4T+C6H/RNzd8qUKoQyJUM1QBGGFbKtXZoqNVr
-                dTueVEZEigfee/GZx4GphEqbKPZNGG3yqC2itYt9HzjI4yHD4JUYwx3Gr+eu
-                uSjgUeJ7zKFA1zZXC6Om1xKmHnGptMeVCg03xNXeVmi24iCgvUcunW4Kwxvc
-                cMKsTtem52RJICHWJuhQJtUyfTVWGErnR65jjVmOlTs/cqysNXZ+NGOvWsvs
-                DbPfpX99zVg5K+GuMtKBe2V4qW0YJj7FysiOqKqu1LIeiI1ra/TclbAhGIZr
-                UomtuFMX0Q4nDkO+Fvo82OWRTOo+6FaVElEl4FoLana2wzjyxQeZnBX7c3b/
-                m4IVuqMULWShmNwbeSxTlaE8QXk8+Qf+wWzK6V61QJVHmVZDevEU2eOe0GKf
-                nFCfU3QvCBgkKeSKGOohSfNk7wRIfcfwt+Sib/RmkbsaswS7xyycIb/HTjF6
-                guIZrL1TjJ9g+PhG7xDNsvGCqsR6nhwVaLmXPW/zpAS8JnySWFP7sKt4XMU0
-                RcwkYbaKJ5jbB9Mo4ek+UhqOxjONjEbhL7J1D8vfAwAA
-                """
     )
 }
diff --git a/compose/ui/ui-test/api/current.txt b/compose/ui/ui-test/api/current.txt
index b1cd79d..666a657 100644
--- a/compose/ui/ui-test/api/current.txt
+++ b/compose/ui/ui-test/api/current.txt
@@ -3,6 +3,8 @@
 
   public final class ActionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performClick(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performCustomAccessibilityActionLabelled(androidx.compose.ui.test.SemanticsNodeInteraction, String label);
+    method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performCustomAccessibilityActionWhere(androidx.compose.ui.test.SemanticsNodeInteraction, optional String? predicateDescription, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean> labelPredicate);
     method @Deprecated public static androidx.compose.ui.test.SemanticsNodeInteraction performGesture(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.GestureScope,kotlin.Unit> block);
     method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performKeyInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
     method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performMouseInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
diff --git a/compose/ui/ui-test/api/restricted_current.txt b/compose/ui/ui-test/api/restricted_current.txt
index 78faf62..b8f4e37 100644
--- a/compose/ui/ui-test/api/restricted_current.txt
+++ b/compose/ui/ui-test/api/restricted_current.txt
@@ -3,6 +3,8 @@
 
   public final class ActionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performClick(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performCustomAccessibilityActionLabelled(androidx.compose.ui.test.SemanticsNodeInteraction, String label);
+    method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performCustomAccessibilityActionWhere(androidx.compose.ui.test.SemanticsNodeInteraction, optional String? predicateDescription, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.Boolean> labelPredicate);
     method @Deprecated public static androidx.compose.ui.test.SemanticsNodeInteraction performGesture(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.GestureScope,kotlin.Unit> block);
     method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performKeyInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
     method @SuppressCompatibility @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performMouseInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
diff --git a/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/actions/CustomAccessibilityActionsTest.kt b/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/actions/CustomAccessibilityActionsTest.kt
new file mode 100644
index 0000000..4bffee2
--- /dev/null
+++ b/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/actions/CustomAccessibilityActionsTest.kt
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+package androidx.compose.ui.test.actions
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.CustomAccessibilityAction
+import androidx.compose.ui.semantics.customActions
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performCustomAccessibilityActionLabelled
+import androidx.compose.ui.test.performCustomAccessibilityActionWhere
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalTestApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CustomAccessibilityActionsTest {
+    @get:Rule
+    val rule = createComposeRule()
+
+    private val tag = "tag"
+
+    @Test
+    fun performCustomAccessibilityActionLabelled_failsWhenNoNodeMatches() {
+        rule.setContent {
+            Box(
+                Modifier.semantics {
+                    customActions = listOf(CustomAccessibilityAction("action") { true })
+                }
+            )
+        }
+
+        val interaction = rule.onNodeWithTag(tag)
+        val error = assertFailsWith<AssertionError> {
+            interaction.performCustomAccessibilityActionLabelled("action")
+        }
+        assertThat(error).hasMessageThat().contains("could not find any node that satisfies")
+    }
+
+    @Test
+    fun performCustomAccessibilityActionLabelled_failsWhenNoActionMatches() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(CustomAccessibilityAction("action") { true })
+                    }
+            )
+        }
+
+        val error = assertFailsWith<AssertionError> {
+            rule.onNodeWithTag(tag).performCustomAccessibilityActionLabelled("not action")
+        }
+        assertThat(error).hasMessageThat().startsWith(
+            "No custom accessibility actions matched [label is \"not action\"]"
+        )
+    }
+
+    @Test
+    fun performCustomAccessibilityActionLabelled_failsWhenMultipleActionsMatch() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(
+                            CustomAccessibilityAction("action") { true },
+                            CustomAccessibilityAction("action") { true },
+                        )
+                    }
+            )
+        }
+
+        val error = assertFailsWith<AssertionError> {
+            rule.onNodeWithTag(tag).performCustomAccessibilityActionLabelled("action")
+        }
+        assertThat(error).hasMessageThat().startsWith(
+            "Expected exactly one custom accessibility action to match [label is \"action\"], " +
+                "but found 2."
+        )
+    }
+
+    @Test
+    fun performCustomAccessibilityActionLabelled_invokesActionWhenExactlyOneActionMatches() {
+        var fooInvocationCount = 0
+        var barInvocationCount = 0
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(
+                            CustomAccessibilityAction("foo") { fooInvocationCount++; true },
+                            CustomAccessibilityAction("bar") { barInvocationCount++; true },
+                        )
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performCustomAccessibilityActionLabelled("foo")
+
+        assertThat(fooInvocationCount).isEqualTo(1)
+        assertThat(barInvocationCount).isEqualTo(0)
+    }
+
+    @Test
+    fun performCustomAccessibilityActionLabelled_doesntFailWhenActionReturnsFalse() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(
+                            CustomAccessibilityAction("action") { false },
+                        )
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performCustomAccessibilityActionLabelled("action")
+    }
+
+    @Test
+    fun performCustomAccessibilityActionWhere_failsWhenNoNodeMatches() {
+        rule.setContent {
+            Box(
+                Modifier.semantics {
+                    customActions = listOf(CustomAccessibilityAction("action") { true })
+                }
+            )
+        }
+
+        val interaction = rule.onNodeWithTag(tag)
+        val error = assertFailsWith<AssertionError> {
+            interaction.performCustomAccessibilityActionWhere("description") { true }
+        }
+        assertThat(error).hasMessageThat().contains("could not find any node that satisfies")
+    }
+
+    @Test
+    fun performCustomAccessibilityActionWhere_failsWhenNoActionMatches() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(CustomAccessibilityAction("action") { true })
+                    }
+            )
+        }
+
+        val error = assertFailsWith<AssertionError> {
+            rule.onNodeWithTag(tag).performCustomAccessibilityActionWhere("description") { false }
+        }
+        assertThat(error).hasMessageThat().startsWith(
+            "No custom accessibility actions matched [description]"
+        )
+    }
+
+    @Test
+    fun performCustomAccessibilityActionWhere_failsWhenMultipleActionsMatch() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(
+                            CustomAccessibilityAction("action") { true },
+                            CustomAccessibilityAction("action") { true },
+                        )
+                    }
+            )
+        }
+
+        val error = assertFailsWith<AssertionError> {
+            rule.onNodeWithTag(tag).performCustomAccessibilityActionWhere("description") { true }
+        }
+        assertThat(error).hasMessageThat().startsWith(
+            "Expected exactly one custom accessibility action to match [description], " +
+                "but found 2."
+        )
+    }
+
+    @Test
+    fun performCustomAccessibilityActionWhere_invokesActionWhenExactlyOneActionMatches() {
+        var fooInvocationCount = 0
+        var barInvocationCount = 0
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(
+                            CustomAccessibilityAction("foo") { fooInvocationCount++; true },
+                            CustomAccessibilityAction("bar") { barInvocationCount++; true },
+                        )
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performCustomAccessibilityActionWhere("description") { it == "foo" }
+
+        assertThat(fooInvocationCount).isEqualTo(1)
+        assertThat(barInvocationCount).isEqualTo(0)
+    }
+
+    @Test
+    fun performCustomAccessibilityActionWhere_doesntFailWhenActionReturnsFalse() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .testTag(tag)
+                    .semantics {
+                        customActions = listOf(
+                            CustomAccessibilityAction("action") { false },
+                        )
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performCustomAccessibilityActionWhere("description") { true }
+    }
+}
diff --git a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt
index 9994145..44d6f19 100644
--- a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt
+++ b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidInputDispatcher.android.kt
@@ -290,8 +290,23 @@
                 },
                 /* pointerCoords = */ Array(coordinates.size) { pointerIndex ->
                     PointerCoords().apply {
-                        x = positionInScreen.x + coordinates[pointerIndex][0].x
-                        y = positionInScreen.y + coordinates[pointerIndex][0].y
+
+                        val startOffset = coordinates[pointerIndex][0]
+
+                        // Allows for non-valid numbers/Offsets to be passed along to Compose to
+                        // test if it handles them properly (versus breaking here and we not knowing
+                        // if Compose properly handles these values).
+                        x = if (startOffset.isValid()) {
+                            positionInScreen.x + startOffset.x
+                        } else {
+                            Float.NaN
+                        }
+
+                        y = if (startOffset.isValid()) {
+                            positionInScreen.y + startOffset.y
+                        } else {
+                            Float.NaN
+                        }
                     }
                 },
                 /* metaState = */ 0,
@@ -311,8 +326,23 @@
                         /* eventTime = */ eventTimes[timeIndex],
                         /* pointerCoords = */ Array(coordinates.size) { pointerIndex ->
                             PointerCoords().apply {
-                                x = positionInScreen.x + coordinates[pointerIndex][timeIndex].x
-                                y = positionInScreen.y + coordinates[pointerIndex][timeIndex].y
+                                val currentOffset = coordinates[pointerIndex][timeIndex]
+
+                                // Allows for non-valid numbers/Offsets to be passed along to
+                                // Compose to test if it handles them properly (versus breaking
+                                // here and we not knowing if Compose properly handles these
+                                // values).
+                                x = if (currentOffset.isValid()) {
+                                    positionInScreen.x + currentOffset.x
+                                } else {
+                                    Float.NaN
+                                }
+
+                                y = if (currentOffset.isValid()) {
+                                    positionInScreen.y + currentOffset.y
+                                } else {
+                                    Float.NaN
+                                }
                             }
                         },
                         /* metaState = */ 0
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt
index 5f9f27e..a646fa88 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Actions.kt
@@ -22,8 +22,10 @@
 import androidx.compose.ui.layout.boundsInParent
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.semantics.AccessibilityAction
+import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.ScrollAxisRange
 import androidx.compose.ui.semantics.SemanticsActions
+import androidx.compose.ui.semantics.SemanticsActions.CustomActions
 import androidx.compose.ui.semantics.SemanticsActions.ScrollBy
 import androidx.compose.ui.semantics.SemanticsActions.ScrollToIndex
 import androidx.compose.ui.semantics.SemanticsNode
@@ -625,6 +627,70 @@
     return this
 }
 
+/**
+ * Finds the [CustomAccessibilityAction] in the node's [CustomActions] list whose label is equal
+ * to [label] and then invokes it.
+ *
+ * To use your own logic to find the action to perform instead of matching on the full label, use
+ * [performCustomAccessibilityActionWhere].
+ *
+ * @param label The exact label of the [CustomAccessibilityAction] to perform.
+ *
+ * @throws AssertionError If no [SemanticsNode] is found, or no [CustomAccessibilityAction] has
+ * [label], or more than one [CustomAccessibilityAction] has [label].
+ *
+ * @see performCustomAccessibilityActionWhere
+ */
+@ExperimentalTestApi
+fun SemanticsNodeInteraction.performCustomAccessibilityActionLabelled(
+    label: String
+): SemanticsNodeInteraction =
+    performCustomAccessibilityActionWhere("label is \"$label\"") { it == label }
+
+/**
+ * Finds the [CustomAccessibilityAction] in the node's [CustomActions] list whose label satisfies a
+ * predicate function and then invokes it.
+ *
+ * @param predicateDescription A description of [labelPredicate] that will be included in the error
+ * message if zero or >1 actions match.
+ * @param labelPredicate A predicate function used to select the [CustomAccessibilityAction] to
+ * perform.
+ *
+ * @throws AssertionError If no [SemanticsNode] is found, or no [CustomAccessibilityAction] matches
+ * [labelPredicate], or more than one [CustomAccessibilityAction] matches [labelPredicate].
+ *
+ * @see performCustomAccessibilityActionLabelled
+ */
+@ExperimentalTestApi
+fun SemanticsNodeInteraction.performCustomAccessibilityActionWhere(
+    predicateDescription: String? = null,
+    labelPredicate: (label: String) -> Boolean
+): SemanticsNodeInteraction {
+    val node = fetchSemanticsNode()
+    val actions = node.config[CustomActions]
+    val matchingActions = actions.filter { labelPredicate(it.label) }
+    if (matchingActions.isEmpty()) {
+        throw AssertionError(
+            buildGeneralErrorMessage(
+                "No custom accessibility actions matched [$predicateDescription].",
+                selector,
+                node
+            )
+        )
+    } else if (matchingActions.size > 1) {
+        throw AssertionError(
+            buildGeneralErrorMessage(
+                "Expected exactly one custom accessibility action to match" +
+                    " [$predicateDescription], but found ${matchingActions.size}.",
+                selector,
+                node
+            )
+        )
+    }
+    matchingActions[0].action()
+    return this
+}
+
 // TODO(200928505): get a more accurate indication if it is a lazy list
 private val SemanticsNode.isLazyList: Boolean
     get() = ScrollBy in config && ScrollToIndex in config
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MultiModalInjectionScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MultiModalInjectionScope.kt
index 7abc0fc..68fb132 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MultiModalInjectionScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MultiModalInjectionScope.kt
@@ -113,11 +113,21 @@
      * @return [position] transformed to coordinates relative to the containing root.
      */
     internal fun localToRoot(position: Offset): Offset {
-        return position + boundsInRoot.topLeft
+        return if (position.isValid()) {
+            position + boundsInRoot.topLeft
+        } else {
+            // Allows invalid position to still pass back through Compose (for testing)
+            position
+        }
     }
 
     internal fun rootToLocal(position: Offset): Offset {
-        return position - boundsInRoot.topLeft
+        return if (position.isValid()) {
+            position - boundsInRoot.topLeft
+        } else {
+            // Allows invalid position to still pass back through Compose (for testing)
+            position
+        }
     }
 
     override val viewConfiguration: ViewConfiguration
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
index d1f5822..e9a98c1 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
@@ -210,7 +210,15 @@
      */
     fun updatePointerBy(pointerId: Int, delta: Offset) {
         // Ignore currentPosition of null here, let updatePointerTo generate the error
-        val position = (currentPosition(pointerId) ?: Offset.Zero) + delta
+        val currentPosition = currentPosition(pointerId) ?: Offset.Zero
+
+        val position = if (currentPosition.isValid() && delta.isValid()) {
+            currentPosition + delta
+        } else {
+            // Allows invalid position to still pass back through Compose (for testing)
+            Offset.Unspecified
+        }
+
         updatePointerTo(pointerId, position)
     }
 
diff --git a/compose/ui/ui-text/api/current.ignore b/compose/ui/ui-text/api/current.ignore
new file mode 100644
index 0000000..8e2ec26
--- /dev/null
+++ b/compose/ui/ui-text/api/current.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+ChangedClass: androidx.compose.ui.text.input.PlatformImeOptions:
+    Class androidx.compose.ui.text.input.PlatformImeOptions changed class/interface declaration
+
+
+RemovedClass: androidx.compose.ui.text.input.AndroidImeOptions:
+    Removed class androidx.compose.ui.text.input.AndroidImeOptions
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index 9f723e7..7abd7ad 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -941,12 +941,6 @@
 
 package androidx.compose.ui.text.input {
 
-  public final class AndroidImeOptions implements androidx.compose.ui.text.input.PlatformImeOptions {
-    ctor public AndroidImeOptions(optional String? privateImeOptions);
-    method public String? getPrivateImeOptions();
-    property public final String? privateImeOptions;
-  }
-
   public final class BackspaceCommand implements androidx.compose.ui.text.input.EditCommand {
     ctor public BackspaceCommand();
     method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
@@ -1139,7 +1133,10 @@
     property public final char mask;
   }
 
-  public sealed interface PlatformImeOptions {
+  @androidx.compose.runtime.Immutable public final class PlatformImeOptions {
+    ctor public PlatformImeOptions(optional String? privateImeOptions);
+    method public String? getPrivateImeOptions();
+    property public final String? privateImeOptions;
   }
 
   public interface PlatformTextInputService {
diff --git a/compose/ui/ui-text/api/restricted_current.ignore b/compose/ui/ui-text/api/restricted_current.ignore
index 2c9640b..8e2ec26 100644
--- a/compose/ui/ui-text/api/restricted_current.ignore
+++ b/compose/ui/ui-text/api/restricted_current.ignore
@@ -1,3 +1,7 @@
 // Baseline format: 1.0
-AddedClass: androidx.compose.ui.text.platform.Synchronization_jvmKt:
-    Added class androidx.compose.ui.text.platform.Synchronization_jvmKt
+ChangedClass: androidx.compose.ui.text.input.PlatformImeOptions:
+    Class androidx.compose.ui.text.input.PlatformImeOptions changed class/interface declaration
+
+
+RemovedClass: androidx.compose.ui.text.input.AndroidImeOptions:
+    Removed class androidx.compose.ui.text.input.AndroidImeOptions
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index 707c653..36f0b32 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -941,12 +941,6 @@
 
 package androidx.compose.ui.text.input {
 
-  public final class AndroidImeOptions implements androidx.compose.ui.text.input.PlatformImeOptions {
-    ctor public AndroidImeOptions(optional String? privateImeOptions);
-    method public String? getPrivateImeOptions();
-    property public final String? privateImeOptions;
-  }
-
   public final class BackspaceCommand implements androidx.compose.ui.text.input.EditCommand {
     ctor public BackspaceCommand();
     method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
@@ -1139,7 +1133,10 @@
     property public final char mask;
   }
 
-  public sealed interface PlatformImeOptions {
+  @androidx.compose.runtime.Immutable public final class PlatformImeOptions {
+    ctor public PlatformImeOptions(optional String? privateImeOptions);
+    method public String? getPrivateImeOptions();
+    property public final String? privateImeOptions;
   }
 
   public interface PlatformTextInputService {
diff --git a/compose/ui/ui-text/lint-baseline.xml b/compose/ui/ui-text/lint-baseline.xml
index 26fe7b7..40b9c16 100644
--- a/compose/ui/ui-text/lint-baseline.xml
+++ b/compose/ui/ui-text/lint-baseline.xml
@@ -1,14 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-alpha04" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-alpha04)" variant="all" version="8.3.0-alpha04">
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 21): `android.graphics.Paint#getBlendMode`"
-        errorLine1="        assertThat(paragraph.textPaint.blendMode).isEqualTo(BlendMode.SrcOver)"
-        errorLine2="                                       ~~~~~~~~~">
-        <location
-            file="src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt"/>
-    </issue>
+<issues format="6" by="lint 8.3.0-alpha10" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-alpha10)" variant="all" version="8.3.0-alpha10">
 
     <issue
         id="NewApi"
@@ -40,10 +31,10 @@
     <issue
         id="NewApi"
         message="Call requires API level 29 (current min is 21): `android.graphics.Paint#getBlendMode`"
-        errorLine1="        assertThat(textPaint.blendMode).isEqualTo(BlendMode.SrcOver)"
-        errorLine2="                             ~~~~~~~~~">
+        errorLine1="        assertThat(paragraph.textPaint.blendMode).isEqualTo(BlendMode.SrcOver)"
+        errorLine2="                                       ~~~~~~~~~">
         <location
-            file="src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/platform/AndroidTextPaintTest.kt"/>
+            file="src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt"/>
     </issue>
 
     <issue
@@ -57,6 +48,15 @@
 
     <issue
         id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.graphics.Paint#getBlendMode`"
+        errorLine1="        assertThat(textPaint.blendMode).isEqualTo(BlendMode.SrcOver)"
+        errorLine2="                             ~~~~~~~~~">
+        <location
+            file="src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/platform/AndroidTextPaintTest.kt"/>
+    </issue>
+
+    <issue
+        id="NewApi"
         message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`"
         errorLine1="        textPaint.blendMode = BlendMode.DstOver"
         errorLine2="                  ~~~~~~~~~">
@@ -66,6 +66,15 @@
 
     <issue
         id="NewApi"
+        message="Cast from `BlendMode` to `Comparable` requires API level 29 (current min is 21)"
+        errorLine1="        assertThat(textPaint.blendMode).isEqualTo(BlendMode.DstOver)"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/platform/AndroidTextPaintTest.kt"/>
+    </issue>
+
+    <issue
+        id="NewApi"
         message="Call requires API level 29 (current min is 21): `android.graphics.Paint#getBlendMode`"
         errorLine1="        assertThat(textPaint.blendMode).isEqualTo(BlendMode.DstOver)"
         errorLine2="                             ~~~~~~~~~">
@@ -74,12 +83,93 @@
     </issue>
 
     <issue
-        id="NewApi"
-        message="Cast from `BlendMode` to `Comparable` requires API level 29 (current min is 21)"
-        errorLine1="        assertThat(textPaint.blendMode).isEqualTo(BlendMode.DstOver)"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~">
+        id="PrimitiveInCollection"
+        message="field paragraphEnds with type List&lt;Integer>: replace with IntList"
+        errorLine1="    private val paragraphEnds: List&lt;Int>"
+        errorLine2="                               ~~~~~~~~~">
         <location
-            file="src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/platform/AndroidTextPaintTest.kt"/>
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/LayoutHelper.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="variable lineFeeds with type List&lt;Integer>: replace with IntList"
+        errorLine1="        val lineFeeds = mutableListOf&lt;Int>()"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/LayoutHelper.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="return type List&lt;Integer> of breakInWords: replace with IntList"
+        errorLine1="    private fun breakInWords(layoutHelper: LayoutHelper): List&lt;Int> {"
+        errorLine2="                                                          ~~~~~~~~~">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="variable words with type List&lt;? extends Integer>: replace with IntList"
+        errorLine1="        val words = breakWithBreakIterator(text, BreakIterator.getLineInstance(Locale.getDefault()))"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="variable set with type TreeSet&lt;Integer>: replace with IntSet"
+        errorLine1="        val set = TreeSet&lt;Int>().apply {"
+        errorLine2="        ^">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="return type List&lt;Integer> of breakWithBreakIterator: replace with IntList"
+        errorLine1="    private fun breakWithBreakIterator(text: CharSequence, breaker: BreakIterator): List&lt;Int> {"
+        errorLine2="                                                                                    ~~~~~~~~~">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="variable res with type List&lt;Integer>: replace with IntList"
+        errorLine1="        val res = mutableListOf(0)"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="return type List&lt;Integer> of breakOffsets: replace with IntList"
+        errorLine1="    fun breakOffsets(layoutHelper: LayoutHelper, segmentType: SegmentType): List&lt;Int> {"
+        errorLine2="                                                                            ~~~~~~~~~">
+        <location
+            file="${:compose:ui:ui-text*debug*MAIN*sourceProvider*0*javaDir*4}/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="variable list with type List&lt;? extends Float>: replace with FloatList"
+        errorLine1="        @Suppress(&quot;UNCHECKED_CAST&quot;)"
+        errorLine2="        ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/text/Savers.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInCollection"
+        message="return type List&lt;FontStyle> of values: replace with IntList"
+        errorLine1="        fun values(): List&lt;FontStyle> = listOf(Normal, Italic)"
+        errorLine2="                      ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/text/font/FontStyle.kt"/>
     </issue>
 
     <issue
@@ -93,11 +183,11 @@
 
     <issue
         id="PrimitiveInCollection"
-        message="return type List&lt;FontStyle> of values: replace with IntList"
-        errorLine1="        fun values(): List&lt;FontStyle> = listOf(Normal, Italic)"
+        message="return type List&lt;TextAlign> of values: replace with IntList"
+        errorLine1="        fun values(): List&lt;TextAlign> = listOf(Left, Right, Center, Justify, Start, End)"
         errorLine2="                      ~~~~~~~~~~~~~~~">
         <location
-            file="src/commonMain/kotlin/androidx/compose/ui/text/font/FontStyle.kt"/>
+            file="src/commonMain/kotlin/androidx/compose/ui/text/style/TextAlign.kt"/>
     </issue>
 
     <issue
@@ -127,94 +217,4 @@
             file="src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt"/>
     </issue>
 
-    <issue
-        id="PrimitiveInCollection"
-        message="field paragraphEnds with type List&lt;Integer>: replace with IntList"
-        errorLine1="    private val paragraphEnds: List&lt;Int>"
-        errorLine2="                               ~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/LayoutHelper.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="variable lineFeeds with type List&lt;Integer>: replace with IntList"
-        errorLine1="        val lineFeeds = mutableListOf&lt;Int>()"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/LayoutHelper.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="variable list with type List&lt;? extends Float>: replace with FloatList"
-        errorLine1="        @Suppress(&quot;UNCHECKED_CAST&quot;)"
-        errorLine2="        ^">
-        <location
-            file="src/commonMain/kotlin/androidx/compose/ui/text/Savers.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="return type List&lt;Integer> of breakInWords: replace with IntList"
-        errorLine1="    private fun breakInWords(layoutHelper: LayoutHelper): List&lt;Int> {"
-        errorLine2="                                                          ~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="variable words with type List&lt;? extends Integer>: replace with IntList"
-        errorLine1="        val words = breakWithBreakIterator(text, BreakIterator.getLineInstance(Locale.getDefault()))"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="variable set with type TreeSet&lt;Integer>: replace with IntSet"
-        errorLine1="        val set = TreeSet&lt;Int>().apply {"
-        errorLine2="        ^">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="return type List&lt;Integer> of breakWithBreakIterator: replace with IntList"
-        errorLine1="    private fun breakWithBreakIterator(text: CharSequence, breaker: BreakIterator): List&lt;Int> {"
-        errorLine2="                                                                                    ~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="variable res with type List&lt;Integer>: replace with IntList"
-        errorLine1="        val res = mutableListOf(0)"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="return type List&lt;Integer> of breakOffsets: replace with IntList"
-        errorLine1="    fun breakOffsets(layoutHelper: LayoutHelper, segmentType: SegmentType): List&lt;Int> {"
-        errorLine2="                                                                            ~~~~~~~~~">
-        <location
-            file="../../../text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
-    </issue>
-
-    <issue
-        id="PrimitiveInCollection"
-        message="return type List&lt;TextAlign> of values: replace with IntList"
-        errorLine1="        fun values(): List&lt;TextAlign> = listOf(Left, Right, Center, Justify, Start, End)"
-        errorLine2="                      ~~~~~~~~~~~~~~~">
-        <location
-            file="src/commonMain/kotlin/androidx/compose/ui/text/style/TextAlign.kt"/>
-    </issue>
-
 </issues>
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.android.kt
index e274e69..68ef3fb 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.android.kt
@@ -16,10 +16,7 @@
 
 package androidx.compose.ui.text.input
 
-/**
- * Used to configure the platform specific IME options.
- */
-actual sealed interface PlatformImeOptions
+import androidx.compose.runtime.Immutable
 
 /**
  * Used to configure Android platform IME options.
@@ -27,10 +24,13 @@
  * @param privateImeOptions defines a [String] for supplying additional information options that
  * are private to a particular IME implementation.
  */
-class AndroidImeOptions(val privateImeOptions: String? = null) : PlatformImeOptions {
+@Immutable
+actual class PlatformImeOptions(
+    val privateImeOptions: String? = null,
+) {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
-        if (other !is AndroidImeOptions) return false
+        if (other !is PlatformImeOptions) return false
 
         if (privateImeOptions != other.privateImeOptions) return false
 
@@ -42,6 +42,6 @@
     }
 
     override fun toString(): String {
-        return "AndroidImeOptions(privateImeOptions=$privateImeOptions)"
+        return "PlatformImeOptions(privateImeOptions=$privateImeOptions)"
     }
 }
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
index bfc47eb..708f622 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTextPaint.android.kt
@@ -18,6 +18,8 @@
 
 import android.text.TextPaint
 import androidx.annotation.VisibleForTesting
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.geometry.isSpecified
 import androidx.compose.ui.graphics.BlendMode
@@ -25,6 +27,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Paint
 import androidx.compose.ui.graphics.PaintingStyle
+import androidx.compose.ui.graphics.Shader
 import androidx.compose.ui.graphics.ShaderBrush
 import androidx.compose.ui.graphics.Shadow
 import androidx.compose.ui.graphics.SolidColor
@@ -36,7 +39,9 @@
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.text.platform.extensions.correctBlurRadius
 import androidx.compose.ui.text.style.TextDecoration
-import kotlin.math.roundToInt
+import androidx.compose.ui.text.style.modulate
+import androidx.compose.ui.util.fastCoerceIn
+import androidx.compose.ui.util.fastRoundToInt
 
 internal class AndroidTextPaint(flags: Int, density: Float) : TextPaint(flags) {
     init {
@@ -51,6 +56,14 @@
     @VisibleForTesting
     internal var shadow: Shadow = Shadow.None
 
+    @VisibleForTesting
+    internal var brush: Brush? = null
+
+    internal var shaderState: State<Shader?>? = null
+
+    @VisibleForTesting
+    internal var brushSize: Size? = null
+
     private var drawStyle: DrawStyle? = null
 
     fun setTextDecoration(textDecoration: TextDecoration?) {
@@ -82,24 +95,41 @@
     fun setColor(color: Color) {
         if (color.isSpecified) {
             composePaint.color = color
-            composePaint.shader = null
+            clearShader()
         }
     }
 
     fun setBrush(brush: Brush?, size: Size, alpha: Float = Float.NaN) {
-        // if size is unspecified and brush is not null, nothing should be done.
-        // it basically means brush is given but size is not yet calculated at this time.
-        if ((brush is SolidColor && brush.value.isSpecified) ||
-            (brush is ShaderBrush && size.isSpecified)) {
-            // alpha is always applied even if Float.NaN is passed to applyTo function.
-            // if it's actually Float.NaN, we simply send the current value
-            brush.applyTo(
-                size,
-                composePaint,
-                if (alpha.isNaN()) composePaint.alpha else alpha.coerceIn(0f, 1f)
-            )
-        } else if (brush == null) {
-            composePaint.shader = null
+        when (brush) {
+            // null brush should just clear the shader and leave `color` as the final decider
+            // while painting
+            null -> {
+                clearShader()
+            }
+            // SolidColor brush can be treated just like setting a color.
+            is SolidColor -> {
+                setColor(brush.value.modulate(alpha))
+            }
+            // This is the brush type that we mostly refer to when we talk about brush support.
+            // Below code is almost equivalent to;
+            // val this.shaderState = remember(brush, brushSize) {
+            //     derivedStateOf {
+            //         brush.createShader(size)
+            //     }
+            // }
+            is ShaderBrush -> {
+                if (this.brush != brush || this.brushSize != size) {
+                    if (size.isSpecified) {
+                        this.brush = brush
+                        this.brushSize = size
+                        this.shaderState = derivedStateOf {
+                            brush.createShader(size)
+                        }
+                    }
+                }
+                composePaint.shader = this.shaderState?.value
+                setAlpha(alpha)
+            }
         }
     }
 
@@ -129,6 +159,16 @@
     // BlendMode is only available to DrawScope.drawText.
     // not intended to be used by TextStyle/SpanStyle.
     var blendMode: BlendMode by composePaint::blendMode
+
+    /**
+     * Clears all shader related cache parameters and native shader property.
+     */
+    private fun clearShader() {
+        this.shaderState = null
+        this.brush = null
+        this.brushSize = null
+        composePaint.shader = null
+    }
 }
 
 /**
@@ -137,7 +177,7 @@
  */
 internal fun TextPaint.setAlpha(alpha: Float) {
     if (!alpha.isNaN()) {
-        val alphaInt = alpha.coerceIn(0f, 1f).times(255).roundToInt()
+        val alphaInt = alpha.fastCoerceIn(0f, 1f).times(255).fastRoundToInt()
         setAlpha(alphaInt)
     }
 }
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
index d215853..f000264 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
@@ -37,8 +37,8 @@
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.text.style.modulate
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.ceil
-import kotlin.math.roundToInt
 
 object TextPainter {
 
@@ -375,9 +375,9 @@
     val isWidthNaN = size.isUnspecified || size.width.isNaN()
     if (isWidthNaN) {
         minWidth = 0
-        maxWidth = ceil(this.size.width - topLeft.x).roundToInt()
+        maxWidth = ceil(this.size.width - topLeft.x).fastRoundToInt()
     } else {
-        val fixedWidth = ceil(size.width).roundToInt()
+        val fixedWidth = ceil(size.width).fastRoundToInt()
         minWidth = fixedWidth
         maxWidth = fixedWidth
     }
@@ -387,9 +387,9 @@
     val isHeightNaN = size.isUnspecified || size.height.isNaN()
     if (isHeightNaN) {
         minHeight = 0
-        maxHeight = ceil(this.size.height - topLeft.y).roundToInt()
+        maxHeight = ceil(this.size.height - topLeft.y).fastRoundToInt()
     } else {
-        val fixedHeight = ceil(size.height).roundToInt()
+        val fixedHeight = ceil(size.height).fastRoundToInt()
         minHeight = fixedHeight
         maxHeight = fixedHeight
     }
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt
index a9ade23..c7be9a2 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.kt
@@ -16,7 +16,10 @@
 
 package androidx.compose.ui.text.input
 
+import androidx.compose.runtime.Immutable
+
 /**
  * Used to configure the platform specific IME options.
  */
-expect sealed interface PlatformImeOptions
+@Immutable
+expect class PlatformImeOptions
diff --git a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.desktop.kt b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.desktop.kt
index 60607ca..a5bc839 100644
--- a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.desktop.kt
+++ b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/input/PlatformImeOptions.desktop.kt
@@ -16,7 +16,10 @@
 
 package androidx.compose.ui.text.input
 
+import androidx.compose.runtime.Immutable
+
 /**
  * Used to configure the platform specific IME options.
  */
-actual sealed interface PlatformImeOptions
+@Immutable
+actual class PlatformImeOptions
diff --git a/compose/ui/ui-tooling-preview/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview.kt b/compose/ui/ui-tooling-preview/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview.desktop.kt
similarity index 100%
rename from compose/ui/ui-tooling-preview/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview.kt
rename to compose/ui/ui-tooling-preview/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview.desktop.kt
diff --git a/compose/ui/ui-tooling/src/androidInstrumentedTest/kotlin/androidx/compose/ui/tooling/animation/clock/TransitionClockTest.kt b/compose/ui/ui-tooling/src/androidInstrumentedTest/kotlin/androidx/compose/ui/tooling/animation/clock/TransitionClockTest.kt
index bffd5f9..ce1ad15 100644
--- a/compose/ui/ui-tooling/src/androidInstrumentedTest/kotlin/androidx/compose/ui/tooling/animation/clock/TransitionClockTest.kt
+++ b/compose/ui/ui-tooling/src/androidInstrumentedTest/kotlin/androidx/compose/ui/tooling/animation/clock/TransitionClockTest.kt
@@ -599,8 +599,7 @@
             clock.setStateParameters(10.dp, 10.dp)
         }
         rule.runOnIdle {
-            // When initial == target state, no animation is active.
-            assertEquals(0, clock.getAnimatedProperties().size)
+            assertEquals(2, clock.getAnimatedProperties().size)
             clock.setStateParameters(20.dp, 40.dp)
         }
         rule.runOnIdle {
@@ -620,8 +619,7 @@
         rule.runOnIdle {
             // Default clock state.
             clock.getTransitions(100).let {
-                // When initial == target state, no animation is active.
-                assertEquals(0, it.size)
+                assertEquals(2, it.size)
             }
             // Change state
             clock.setStateParameters(20.dp, 40.dp)
diff --git a/compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/NonInteractivePreviewFacade.kt b/compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/NonInteractivePreviewFacade.desktop.kt
similarity index 100%
rename from compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/NonInteractivePreviewFacade.kt
rename to compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/NonInteractivePreviewFacade.desktop.kt
diff --git a/compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/PreviewRunner.kt b/compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/PreviewRunner.desktop.kt
similarity index 100%
rename from compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/PreviewRunner.kt
rename to compose/ui/ui-tooling/src/desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/runtime/PreviewRunner.desktop.kt
diff --git a/compose/ui/ui-unit/api/current.ignore b/compose/ui/ui-unit/api/current.ignore
new file mode 100644
index 0000000..0e3bda5
--- /dev/null
+++ b/compose/ui/ui-unit/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedClass: androidx.compose.ui.unit.FontScalingKt:
+    Removed class androidx.compose.ui.unit.FontScalingKt
diff --git a/compose/ui/ui-unit/api/current.txt b/compose/ui/ui-unit/api/current.txt
index eba7f2c..d359775 100644
--- a/compose/ui/ui-unit/api/current.txt
+++ b/compose/ui/ui-unit/api/current.txt
@@ -199,15 +199,9 @@
     property public abstract float fontScale;
   }
 
-  public final class FontScalingKt {
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getDisableNonLinearFontScalingInCompose();
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static void setDisableNonLinearFontScalingInCompose(boolean);
-    property @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static final boolean DisableNonLinearFontScalingInCompose;
-  }
-
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class IntOffset {
-    method @androidx.compose.runtime.Stable public operator int component1();
-    method @androidx.compose.runtime.Stable public operator int component2();
+    method @androidx.compose.runtime.Stable public inline operator int component1();
+    method @androidx.compose.runtime.Stable public inline operator int component2();
     method public long copy(optional int x, optional int y);
     method @androidx.compose.runtime.Stable public operator long div(float operand);
     method public int getX();
diff --git a/compose/ui/ui-unit/api/restricted_current.ignore b/compose/ui/ui-unit/api/restricted_current.ignore
new file mode 100644
index 0000000..0e3bda5
--- /dev/null
+++ b/compose/ui/ui-unit/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedClass: androidx.compose.ui.unit.FontScalingKt:
+    Removed class androidx.compose.ui.unit.FontScalingKt
diff --git a/compose/ui/ui-unit/api/restricted_current.txt b/compose/ui/ui-unit/api/restricted_current.txt
index e9b932e..96e479d 100644
--- a/compose/ui/ui-unit/api/restricted_current.txt
+++ b/compose/ui/ui-unit/api/restricted_current.txt
@@ -199,15 +199,9 @@
     property public abstract float fontScale;
   }
 
-  public final class FontScalingKt {
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getDisableNonLinearFontScalingInCompose();
-    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static void setDisableNonLinearFontScalingInCompose(boolean);
-    property @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static final boolean DisableNonLinearFontScalingInCompose;
-  }
-
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class IntOffset {
-    method @androidx.compose.runtime.Stable public operator int component1();
-    method @androidx.compose.runtime.Stable public operator int component2();
+    method @androidx.compose.runtime.Stable public inline operator int component1();
+    method @androidx.compose.runtime.Stable public inline operator int component2();
     method public long copy(optional int x, optional int y);
     method @androidx.compose.runtime.Stable public operator long div(float operand);
     method public int getX();
diff --git a/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/AndroidDensity.android.kt b/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/AndroidDensity.android.kt
index c52998f..37e1c09 100644
--- a/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/AndroidDensity.android.kt
+++ b/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/AndroidDensity.android.kt
@@ -17,7 +17,6 @@
 package androidx.compose.ui.unit
 
 import android.content.Context
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.unit.fontscaling.FontScaleConverter
 import androidx.compose.ui.unit.fontscaling.FontScaleConverterFactory
 
@@ -26,16 +25,12 @@
  *
  * @param context density values will be extracted from this [Context]
  */
-@OptIn(ExperimentalComposeUiApi::class)
 fun Density(context: Context): Density {
     val fontScale = context.resources.configuration.fontScale
-    val converter = if (DisableNonLinearFontScalingInCompose) LinearFontScaleConverter(fontScale)
-        else FontScaleConverterFactory.forScale(fontScale) ?: LinearFontScaleConverter(fontScale)
-
     return DensityWithConverter(
         context.resources.displayMetrics.density,
         fontScale,
-        converter
+        FontScaleConverterFactory.forScale(fontScale) ?: LinearFontScaleConverter(fontScale)
     )
 }
 
diff --git a/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/FontScaling.android.kt b/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/FontScaling.android.kt
index e9f3565..e18c850 100644
--- a/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/FontScaling.android.kt
+++ b/compose/ui/ui-unit/src/androidMain/kotlin/androidx/compose/ui/unit/FontScaling.android.kt
@@ -18,7 +18,6 @@
 
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.unit.fontscaling.FontScaleConverterFactory
 import androidx.compose.ui.unit.internal.JvmDefaultWithCompatibility
 
@@ -31,7 +30,6 @@
  */
 @Immutable
 @JvmDefaultWithCompatibility
-@OptIn(ExperimentalComposeUiApi::class)
 actual interface FontScaling {
     /**
      * Current user preference for the scaling factor for fonts.
@@ -44,8 +42,7 @@
      */
     @Stable
     actual fun Dp.toSp(): TextUnit {
-        if (!FontScaleConverterFactory.isNonLinearFontScalingActive(fontScale) ||
-            DisableNonLinearFontScalingInCompose) {
+        if (!FontScaleConverterFactory.isNonLinearFontScalingActive(fontScale)) {
             return (value / fontScale).sp
         }
 
@@ -60,8 +57,7 @@
     @Stable
     actual fun TextUnit.toDp(): Dp {
         check(type == TextUnitType.Sp) { "Only Sp can convert to Px" }
-        if (!FontScaleConverterFactory.isNonLinearFontScalingActive(fontScale) ||
-            DisableNonLinearFontScalingInCompose) {
+        if (!FontScaleConverterFactory.isNonLinearFontScalingActive(fontScale)) {
             return Dp(value * fontScale)
         }
 
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt
index 59cd655..186ba34 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt
@@ -22,7 +22,7 @@
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.geometry.isSpecified
 import androidx.compose.ui.unit.internal.JvmDefaultWithCompatibility
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * A density of the screen. Used for convert [Dp] to pixels.
@@ -66,7 +66,7 @@
     @Stable
     fun Dp.roundToPx(): Int {
         val px = toPx()
-        return if (px.isInfinite()) Constraints.Infinity else px.roundToInt()
+        return if (px.isInfinite()) Constraints.Infinity else px.fastRoundToInt()
     }
 
     /**
@@ -83,7 +83,7 @@
      * Convert Sp to [Int] by rounding
      */
     @Stable
-    fun TextUnit.roundToPx(): Int = toPx().roundToInt()
+    fun TextUnit.roundToPx(): Int = toPx().fastRoundToInt()
 
     /**
      * Convert an [Int] pixel value to [Dp].
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt
index eda14a5..b63b301 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Dp.kt
@@ -41,21 +41,19 @@
  * @sample androidx.compose.ui.unit.samples.ToPxSample
  */
 @Immutable
[email protected]
+@JvmInline
 value class Dp(val value: Float) : Comparable<Dp> {
     /**
      * Add two [Dp]s together.
      */
     @Stable
-    inline operator fun plus(other: Dp) =
-        Dp(value = this.value + other.value)
+    inline operator fun plus(other: Dp) = Dp(this.value + other.value)
 
     /**
      * Subtract a Dp from another one.
      */
     @Stable
-    inline operator fun minus(other: Dp) =
-        Dp(value = this.value - other.value)
+    inline operator fun minus(other: Dp) = Dp(this.value - other.value)
 
     /**
      * This is the same as multiplying the Dp by -1.0.
@@ -67,12 +65,10 @@
      * Divide a Dp by a scalar.
      */
     @Stable
-    inline operator fun div(other: Float): Dp =
-        Dp(value = value / other)
+    inline operator fun div(other: Float): Dp = Dp(value / other)
 
     @Stable
-    inline operator fun div(other: Int): Dp =
-        Dp(value = value / other)
+    inline operator fun div(other: Int): Dp = Dp(value / other)
 
     /**
      * Divide by another Dp to get a scalar.
@@ -84,12 +80,10 @@
      * Multiply a Dp by a scalar.
      */
     @Stable
-    inline operator fun times(other: Float): Dp =
-        Dp(value = value * other)
+    inline operator fun times(other: Float): Dp = Dp(value * other)
 
     @Stable
-    inline operator fun times(other: Int): Dp =
-        Dp(value = value * other)
+    inline operator fun times(other: Int): Dp = Dp(value * other)
 
     /**
      * Support comparing Dimensions with comparison operators.
@@ -106,19 +100,19 @@
          * space, but will draw a single pixel, independent of the device's resolution and density.
          */
         @Stable
-        val Hairline = Dp(value = 0f)
+        val Hairline = Dp(0f)
 
         /**
          * Infinite dp dimension.
          */
         @Stable
-        val Infinity = Dp(value = Float.POSITIVE_INFINITY)
+        val Infinity = Dp(Float.POSITIVE_INFINITY)
 
         /**
          * Constant that means unspecified Dp
          */
         @Stable
-        val Unspecified = Dp(value = Float.NaN)
+        val Unspecified = Dp(Float.NaN)
     }
 }
 
@@ -151,7 +145,7 @@
  *     val y = 10.dp
  */
 @Stable
-inline val Int.dp: Dp get() = Dp(value = this.toFloat())
+inline val Int.dp: Dp get() = Dp(this.toFloat())
 
 /**
  * Create a [Dp] using a [Double]:
@@ -161,7 +155,7 @@
  *     val y = 10.0.dp
  */
 @Stable
-inline val Double.dp: Dp get() = Dp(value = this.toFloat())
+inline val Double.dp: Dp get() = Dp(this.toFloat())
 
 /**
  * Create a [Dp] using a [Float]:
@@ -171,7 +165,7 @@
  *     val y = 10f.dp
  */
 @Stable
-inline val Float.dp: Dp get() = Dp(value = this)
+inline val Float.dp: Dp get() = Dp(this)
 
 @Stable
 inline operator fun Float.times(other: Dp) =
@@ -186,10 +180,10 @@
     Dp(this * other.value)
 
 @Stable
-inline fun min(a: Dp, b: Dp): Dp = Dp(value = min(a.value, b.value))
+inline fun min(a: Dp, b: Dp): Dp = Dp(min(a.value, b.value))
 
 @Stable
-inline fun max(a: Dp, b: Dp): Dp = Dp(value = max(a.value, b.value))
+inline fun max(a: Dp, b: Dp): Dp = Dp(max(a.value, b.value))
 
 /**
  * Ensures that this value lies in the specified range [minimumValue]..[maximumValue].
@@ -199,7 +193,7 @@
  */
 @Stable
 inline fun Dp.coerceIn(minimumValue: Dp, maximumValue: Dp): Dp =
-    Dp(value = value.coerceIn(minimumValue.value, maximumValue.value))
+    Dp(value.coerceIn(minimumValue.value, maximumValue.value))
 
 /**
  * Ensures that this value is not less than the specified [minimumValue].
@@ -208,7 +202,7 @@
  */
 @Stable
 inline fun Dp.coerceAtLeast(minimumValue: Dp): Dp =
-    Dp(value = value.coerceAtLeast(minimumValue.value))
+    Dp(value.coerceAtLeast(minimumValue.value))
 
 /**
  * Ensures that this value is not greater than the specified [maximumValue].
@@ -218,7 +212,7 @@
  */
 @Stable
 inline fun Dp.coerceAtMost(maximumValue: Dp): Dp =
-    Dp(value = value.coerceAtMost(maximumValue.value))
+    Dp(value.coerceAtMost(maximumValue.value))
 
 /**
  *
@@ -257,17 +251,16 @@
  * A two-dimensional offset using [Dp] for units
  */
 @Immutable
[email protected]
+@JvmInline
 value class DpOffset internal constructor(@PublishedApi internal val packedValue: Long) {
-
     /**
      * The horizontal aspect of the offset in [Dp]
      */
     @Stable
-        /*inline*/ val x: Dp
+    val x: Dp
         get() {
             // Explicitly compare against packed values to avoid auto-boxing of DpOffset.Unspecified
-            check(this.packedValue != Unspecified.packedValue) {
+            checkPrecondition(this.packedValue != UnspecifiedPackedFloats) {
                 "DpOffset is unspecified"
             }
             return unpackFloat1(packedValue).dp
@@ -277,10 +270,10 @@
      * The vertical aspect of the offset in [Dp]
      */
     @Stable
-        /*inline*/ val y: Dp
+    val y: Dp
         get() {
             // Explicitly compare against packed values to avoid auto-boxing of DpOffset.Unspecified
-            check(this.packedValue != Unspecified.packedValue) {
+            checkPrecondition(this.packedValue != UnspecifiedPackedFloats) {
                 "DpOffset is unspecified"
             }
             return unpackFloat2(packedValue).dp
@@ -334,14 +327,14 @@
  */
 @Stable
 inline val DpOffset.isSpecified: Boolean
-    get() = packedValue != DpOffset.Unspecified.packedValue
+    get() = packedValue != 0x7fc00000_7fc00000L // Keep UnspecifiedPackedFloats internal
 
 /**
  * `true` when this is [DpOffset.Unspecified].
  */
 @Stable
 inline val DpOffset.isUnspecified: Boolean
-    get() = packedValue == DpOffset.Unspecified.packedValue
+    get() = packedValue == 0x7fc00000_7fc00000L // Keep UnspecifiedPackedFloats internal
 
 /**
  * If this [DpOffset]&nbsp;[isSpecified] then this is returned, otherwise [block] is executed
@@ -375,17 +368,16 @@
  * A two-dimensional Size using [Dp] for units
  */
 @Immutable
[email protected]
+@JvmInline
 value class DpSize internal constructor(@PublishedApi internal val packedValue: Long) {
-
     /**
      * The horizontal aspect of the Size in [Dp]
      */
     @Stable
-        /*inline*/ val width: Dp
+    val width: Dp
         get() {
             // Explicitly compare against packed values to avoid auto-boxing of DpSize.Unspecified
-            check(this.packedValue != Unspecified.packedValue) {
+            checkPrecondition(packedValue != UnspecifiedPackedFloats) {
                 "DpSize is unspecified"
             }
             return unpackFloat1(packedValue).dp
@@ -395,10 +387,10 @@
      * The vertical aspect of the Size in [Dp]
      */
     @Stable
-        /*inline*/ val height: Dp
+    val height: Dp
         get() {
             // Explicitly compare against packed values to avoid auto-boxing of DpSize.Unspecified
-            check(this.packedValue != Unspecified.packedValue) {
+            checkPrecondition(packedValue != UnspecifiedPackedFloats) {
                 "DpSize is unspecified"
             }
             return unpackFloat2(packedValue).dp
@@ -470,14 +462,14 @@
  */
 @Stable
 inline val DpSize.isSpecified: Boolean
-    get() = packedValue != DpSize.Unspecified.packedValue
+    get() = packedValue != 0x7fc00000_7fc00000L // Keep UnspecifiedPackedFloats internal
 
 /**
  * `true` when this is [DpSize.Unspecified].
  */
 @Stable
 inline val DpSize.isUnspecified: Boolean
-    get() = packedValue == DpSize.Unspecified.packedValue
+    get() = packedValue == 0x7fc00000_7fc00000L // Keep UnspecifiedPackedFloats internal
 
 /**
  * If this [DpSize]&nbsp;[isSpecified] then this is returned, otherwise [block] is executed
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/FontScaling.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/FontScaling.kt
index 65d23a8..68c3238 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/FontScaling.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/FontScaling.kt
@@ -19,30 +19,9 @@
 import androidx.annotation.RestrictTo
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.unit.internal.JvmDefaultWithCompatibility
 
 /**
- * Flag indicating if [Density] will use non-linear font scaling for Compose.
- *
- * Set this flag to true to keep the old linear font scaling behavior. Note that this only affects
- * Compose. Views always use non-linear font scaling in Android 14 and later.
- *
- * <b>This flag will be removed in Compose 1.6.0-beta01.</b> If you encounter any issues with the
- * new behavior, please file an issue at: issuetracker.google.com/issues/new?component=779818
- */
-// TODO(b/300538470): Remove flag before beta
-@Suppress("GetterSetterNames", "OPT_IN_MARKER_ON_WRONG_TARGET")
-@get:Suppress("GetterSetterNames")
-@set:ExperimentalComposeUiApi
-@get:ExperimentalComposeUiApi
-@ExperimentalComposeUiApi
-var DisableNonLinearFontScalingInCompose by mutableStateOf(false)
-
-/**
  * Converts [TextUnit] to [Dp] and vice-versa.
  *
  * If you are implementing this interface yourself on Android, please check the docs for important
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/InlineClassHelper.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/InlineClassHelper.kt
index e053acf..42101b0 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/InlineClassHelper.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/InlineClassHelper.kt
@@ -19,6 +19,9 @@
 import kotlin.contracts.ExperimentalContracts
 import kotlin.contracts.contract
 
+// Same as DpOffset/DpSize.Unspecified.packedValue, but avoids a getstatic
+internal const val UnspecifiedPackedFloats = 0x7fc00000_7fc00000L // NaN_NaN
+
 // This function exists so we do *not* inline the throw. It keeps
 // the call site much smaller and since it's the slow path anyway,
 // we don't mind the extra function call
@@ -37,3 +40,20 @@
         throwIllegalArgumentException(lazyMessage())
     }
 }
+
+// See above
+internal fun throwIllegalStateException(message: String) {
+    throw IllegalStateException(message)
+}
+
+// Like Kotlin's check() but without the .toString() call
+@Suppress("BanInlineOptIn") // same opt-in as using Kotlin's check()
+@OptIn(ExperimentalContracts::class)
+internal inline fun checkPrecondition(value: Boolean, lazyMessage: () -> String) {
+    contract {
+        returns() implies value
+    }
+    if (!value) {
+        throwIllegalStateException(lazyMessage())
+    }
+}
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt
index 4c7bd77..3daf858 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntOffset.kt
@@ -14,22 +14,18 @@
  * limitations under the License.
  */
 
-@file:Suppress(
-    "NOTHING_TO_INLINE",
-    "",
-    "EXPERIMENTAL_FEATURE_WARNING"
-)
+@file:Suppress("NOTHING_TO_INLINE")
 
 package androidx.compose.ui.unit
 
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.compose.ui.util.lerp
 import androidx.compose.ui.util.packInts
 import androidx.compose.ui.util.unpackInt1
 import androidx.compose.ui.util.unpackInt2
-import kotlin.math.roundToInt
 
 /**
  * Constructs a [IntOffset] from [x] and [y] position [Int] values.
@@ -42,7 +38,7 @@
  * A two-dimensional position using [Int] pixels for units
  */
 @Immutable
[email protected]
+@JvmInline
 value class IntOffset internal constructor(@PublishedApi internal val packedValue: Long) {
 
     /**
@@ -60,36 +56,42 @@
         get() = unpackInt2(packedValue)
 
     @Stable
-    operator fun component1(): Int = x
+    inline operator fun component1(): Int = x
 
     @Stable
-    operator fun component2(): Int = y
+    inline operator fun component2(): Int = y
 
     /**
      * Returns a copy of this IntOffset instance optionally overriding the
      * x or y parameter
      */
-    fun copy(x: Int = this.x, y: Int = this.y) = IntOffset(x, y)
+    fun copy(x: Int = unpackInt1(packedValue), y: Int = unpackInt2(packedValue)) = IntOffset(x, y)
 
     /**
      * Subtract a [IntOffset] from another one.
      */
     @Stable
     inline operator fun minus(other: IntOffset) =
-        IntOffset(x - other.x, y - other.y)
+        IntOffset(
+            unpackInt1(packedValue) - unpackInt1(other.packedValue),
+            unpackInt2(packedValue) - unpackInt2(other.packedValue)
+        )
 
     /**
      * Add a [IntOffset] to another one.
      */
     @Stable
     inline operator fun plus(other: IntOffset) =
-        IntOffset(x + other.x, y + other.y)
+        IntOffset(
+            unpackInt1(packedValue) + unpackInt1(other.packedValue),
+            unpackInt2(packedValue) + unpackInt2(other.packedValue)
+        )
 
     /**
      * Returns a new [IntOffset] representing the negation of this point.
      */
     @Stable
-    inline operator fun unaryMinus() = IntOffset(-x, -y)
+    inline operator fun unaryMinus() = IntOffset(-unpackInt1(packedValue), -unpackInt2(packedValue))
 
     /**
      * Multiplication operator.
@@ -100,8 +102,8 @@
      */
     @Stable
     operator fun times(operand: Float): IntOffset = IntOffset(
-        (x * operand).roundToInt(),
-        (y * operand).roundToInt()
+        (unpackInt1(packedValue) * operand).fastRoundToInt(),
+        (unpackInt2(packedValue) * operand).fastRoundToInt()
     )
 
     /**
@@ -113,8 +115,8 @@
      */
     @Stable
     operator fun div(operand: Float): IntOffset = IntOffset(
-        (x / operand).roundToInt(),
-        (y / operand).roundToInt()
+        (unpackInt1(packedValue) / operand).fastRoundToInt(),
+        (unpackInt2(packedValue) / operand).fastRoundToInt()
     )
 
     /**
@@ -125,7 +127,10 @@
      * right-hand-side operand (an Int).
      */
     @Stable
-    operator fun rem(operand: Int) = IntOffset(x % operand, y % operand)
+    operator fun rem(operand: Int) = IntOffset(
+        unpackInt1(packedValue) % operand,
+        unpackInt2(packedValue) % operand
+    )
 
     @Stable
     override fun toString(): String = "($x, $y)"
@@ -176,4 +181,4 @@
  * Round a [Offset] down to the nearest [Int] coordinates.
  */
 @Stable
-inline fun Offset.round(): IntOffset = IntOffset(x.roundToInt(), y.roundToInt())
+inline fun Offset.round(): IntOffset = IntOffset(x.fastRoundToInt(), y.fastRoundToInt())
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntRect.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntRect.kt
index 92e9791..6b3e922 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntRect.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/IntRect.kt
@@ -23,9 +23,9 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.geometry.translate
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.compose.ui.util.lerp
 import kotlin.math.absoluteValue
-import kotlin.math.roundToInt
 
 /**
  * An immutable, 2D, axis-aligned, integer bounds rectangle whose coordinates are relative
@@ -327,8 +327,8 @@
  */
 @Stable
 fun Rect.roundToIntRect(): IntRect = IntRect(
-    left = left.roundToInt(),
-    top = top.roundToInt(),
-    right = right.roundToInt(),
-    bottom = bottom.roundToInt()
+    left = left.fastRoundToInt(),
+    top = top.fastRoundToInt(),
+    right = right.fastRoundToInt(),
+    bottom = bottom.fastRoundToInt()
 )
diff --git a/compose/ui/ui-util/api/current.txt b/compose/ui/ui-util/api/current.txt
index 7347ac5..3dc1165 100644
--- a/compose/ui/ui-util/api/current.txt
+++ b/compose/ui/ui-util/api/current.txt
@@ -17,6 +17,8 @@
 
   public final class InlineClassHelperKt {
     method public static double doubleFromBits(long bits);
+    method public static int fastRoundToInt(double);
+    method public static int fastRoundToInt(float);
     method public static float floatFromBits(int bits);
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -30,6 +32,8 @@
 
   public final class InlineClassHelper_jvmKt {
     method public static inline double doubleFromBits(long bits);
+    method public static inline int fastRoundToInt(double);
+    method public static inline int fastRoundToInt(float);
     method public static inline float floatFromBits(int bits);
   }
 
@@ -63,6 +67,13 @@
   }
 
   public final class MathHelpersKt {
+    method public static float fastCbrt(float x);
+    method public static inline double fastCoerceAtLeast(double, double minimumValue);
+    method public static inline float fastCoerceAtLeast(float, float minimumValue);
+    method public static inline double fastCoerceAtMost(double, double maximumValue);
+    method public static inline float fastCoerceAtMost(float, float maximumValue);
+    method public static inline double fastCoerceIn(double, double minimumValue, double maximumValue);
+    method public static inline float fastCoerceIn(float, float minimumValue, float maximumValue);
     method public static float lerp(float start, float stop, float fraction);
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
diff --git a/compose/ui/ui-util/api/restricted_current.txt b/compose/ui/ui-util/api/restricted_current.txt
index 7347ac5..3dc1165 100644
--- a/compose/ui/ui-util/api/restricted_current.txt
+++ b/compose/ui/ui-util/api/restricted_current.txt
@@ -17,6 +17,8 @@
 
   public final class InlineClassHelperKt {
     method public static double doubleFromBits(long bits);
+    method public static int fastRoundToInt(double);
+    method public static int fastRoundToInt(float);
     method public static float floatFromBits(int bits);
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -30,6 +32,8 @@
 
   public final class InlineClassHelper_jvmKt {
     method public static inline double doubleFromBits(long bits);
+    method public static inline int fastRoundToInt(double);
+    method public static inline int fastRoundToInt(float);
     method public static inline float floatFromBits(int bits);
   }
 
@@ -63,6 +67,13 @@
   }
 
   public final class MathHelpersKt {
+    method public static float fastCbrt(float x);
+    method public static inline double fastCoerceAtLeast(double, double minimumValue);
+    method public static inline float fastCoerceAtLeast(float, float minimumValue);
+    method public static inline double fastCoerceAtMost(double, double maximumValue);
+    method public static inline float fastCoerceAtMost(float, float maximumValue);
+    method public static inline double fastCoerceIn(double, double minimumValue, double maximumValue);
+    method public static inline float fastCoerceIn(float, float minimumValue, float maximumValue);
     method public static float lerp(float start, float stop, float fraction);
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
diff --git a/compose/ui/ui-util/src/androidUnitTest/kotlin/androidx/compose/ui/util/MathHelpersTest.kt b/compose/ui/ui-util/src/androidUnitTest/kotlin/androidx/compose/ui/util/MathHelpersTest.kt
index 93d8958..ab429d6 100644
--- a/compose/ui/ui-util/src/androidUnitTest/kotlin/androidx/compose/ui/util/MathHelpersTest.kt
+++ b/compose/ui/ui-util/src/androidUnitTest/kotlin/androidx/compose/ui/util/MathHelpersTest.kt
@@ -17,13 +17,15 @@
 package androidx.compose.ui.util
 
 import com.google.common.truth.Truth.assertThat
+import kotlin.math.abs
+import kotlin.math.cbrt
+import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
 @RunWith(JUnit4::class)
 class MathHelpersTest {
-
     // `f = 16777216f` is the first value where `f + 1 == f` due to float imprecision, so that's
     // where testing floating point errors becomes interesting
     val testStart = 16777216L
@@ -97,4 +99,37 @@
             assertThat(lerp(from, to, 1.00f)).isEqualTo((4 * multiplier).toLong())
         }
     }
+
+    @Test
+    fun testNegativeFastCbrt() {
+        for (i in 0..65_536) {
+            val v = i / 8_192.0f // v is in the range 0f..8f
+            // We do an == test ourselves to avoid any fuzzy float comparison
+            assertTrue(-fastCbrt(v) == fastCbrt(-v))
+        }
+    }
+
+    @Test
+    fun testNonFiniteFastCbrt() {
+        assertTrue(fastCbrt(Float.NaN).isNaN())
+        assertTrue(fastCbrt(Float.POSITIVE_INFINITY).isNaN())
+        assertTrue(fastCbrt(Float.NEGATIVE_INFINITY).isNaN())
+    }
+
+    @Test
+    fun testZeroFastCbrt() {
+        val zeroError = 8.35E-7f
+        assertTrue(fastCbrt(0.0f) <= zeroError)
+        assertTrue(fastCbrt(-0.0f) >= -zeroError)
+    }
+
+    @Test
+    fun testFastCbrtError() {
+        val maxError = 1.76E-6f
+        for (i in 0..65_536) {
+            val v = i / 8_192.0f // v is in the range 0f..8f
+            val error = abs(fastCbrt(v) - cbrt(v))
+            assertTrue(error <= maxError)
+        }
+    }
 }
diff --git a/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/InlineClassHelper.kt b/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/InlineClassHelper.kt
index f1a5207..fc06db4 100644
--- a/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/InlineClassHelper.kt
+++ b/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/InlineClassHelper.kt
@@ -35,6 +35,28 @@
 expect fun doubleFromBits(bits: Long): Double
 
 /**
+ * Returns the closest integer to the argument, tying rounding to positive
+ * infinity. Some values are treated differently:
+ * - NaN becomes 0
+ * - -Infinity or any value less than Integer.MIN_VALUE becomes
+ *   Integer.MIN_VALUE.toFloat()
+ * - +Infinity or any value greater than Integer.MAX_VALUE becomes
+ *   Integer.MAX_VALUE.toFloat()
+ */
+expect fun Float.fastRoundToInt(): Int
+
+/**
+ * Returns the closest integer to the argument, tying rounding to positive
+ * infinity. Some values are treated differently:
+ * - NaN becomes 0
+ * - -Infinity or any value less than Integer.MIN_VALUE becomes
+ *   Integer.MIN_VALUE.toFloat()
+ * - +Infinity or any value greater than Integer.MAX_VALUE becomes
+ *   Integer.MAX_VALUE.toFloat()
+ */
+expect fun Double.fastRoundToInt(): Int
+
+/**
  * Packs two Float values into one Long value for use in inline classes.
  */
 inline fun packFloats(val1: Float, val2: Float): Long {
diff --git a/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/MathHelpers.kt b/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/MathHelpers.kt
index ebf47195..72cbb55 100644
--- a/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/MathHelpers.kt
+++ b/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/MathHelpers.kt
@@ -15,7 +15,6 @@
  */
 package androidx.compose.ui.util
 
-import kotlin.math.roundToInt
 import kotlin.math.roundToLong
 
 /**
@@ -29,7 +28,7 @@
  * Linearly interpolate between [start] and [stop] with [fraction] fraction between them.
  */
 fun lerp(start: Int, stop: Int, fraction: Float): Int {
-    return start + ((stop - start) * fraction.toDouble()).roundToInt()
+    return start + ((stop - start) * fraction.toDouble()).fastRoundToInt()
 }
 
 /**
@@ -38,3 +37,184 @@
 fun lerp(start: Long, stop: Long, fraction: Float): Long {
     return start + ((stop - start) * fraction.toDouble()).roundToLong()
 }
+
+/**
+ * Returns this float value clamped in the inclusive range defined by
+ * [minimumValue] and [maximumValue]. Unlike [Float.coerceIn], the range
+ * is not validated: the caller must ensure that [minimumValue] is less than
+ * [maximumValue].
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun Float.fastCoerceIn(minimumValue: Float, maximumValue: Float) =
+    this.fastCoerceAtLeast(minimumValue).fastCoerceAtMost(maximumValue)
+
+/**
+ * Ensures that this value is not less than the specified [minimumValue].
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun Float.fastCoerceAtLeast(minimumValue: Float): Float {
+    return if (this < minimumValue) minimumValue else this
+}
+
+/**
+ * Ensures that this value is not greater than the specified [maximumValue].
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun Float.fastCoerceAtMost(maximumValue: Float): Float {
+    return if (this > maximumValue) maximumValue else this
+}
+
+/**
+ * Returns this double value clamped in the inclusive range defined by
+ * [minimumValue] and [maximumValue]. Unlike [Float.coerceIn], the range
+ * is not validated: the caller must ensure that [minimumValue] is less than
+ * [maximumValue].
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun Double.fastCoerceIn(minimumValue: Double, maximumValue: Double) =
+    this.fastCoerceAtLeast(minimumValue).fastCoerceAtMost(maximumValue)
+
+/**
+ * Ensures that this value is not less than the specified [minimumValue].
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun Double.fastCoerceAtLeast(minimumValue: Double): Double {
+    return if (this < minimumValue) minimumValue else this
+}
+
+/**
+ * Ensures that this value is not greater than the specified [maximumValue].
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun Double.fastCoerceAtMost(maximumValue: Double): Double {
+    return if (this > maximumValue) maximumValue else this
+}
+
+/**
+ * Fast, approximate cube root function. Returns the cube root
+ * of [x]; for any [x] `fastCbrt(-x) == -fastCbrt(x)`.
+ *
+ * When [x] is:
+ * - [Float.NaN], returns [Float.NaN]
+ * - [Float.POSITIVE_INFINITY], returns [Float.NaN]
+ * - [Float.NEGATIVE_INFINITY], returns [Float.NaN]
+ * - Zero, returns a value close to 0 (~8.3e-14) with the same sign
+ *
+ * The maximum error compared to [kotlin.math.cbrt] is:
+ * - 8.3446500E-7 in the range -1f..1f
+ * - 6.6757200E-6 in the range -256f..256f
+ * - 1.0681152E-4 in the range -65_536f..65_536f
+ * - 2.1362305E-4 in the range -16_777_216..16_777_216f
+ */
+fun fastCbrt(x: Float): Float {
+    // Our fast cube root approximation is implemented using the binary
+    // representation of a float as a log space (log2 in our case). In
+    // log space, we can reason about the cube root function in a
+    // different way:
+    //
+    // log2(cbrt(x)) = log2(x^1/3) = 1/3 * log2(x)
+    //
+    // Assuming x is a positive normal number, it can be written as:
+    //
+    // x = 2^e_x * (1 + m_x)
+    //
+    // Therefore:
+    //
+    // log2(x) = e_x + log2(1 + m_x)
+    //
+    // Since the m_x is in the range [0, 1), we can apply the following
+    // approximation:
+    //
+    // log2(1 + m_x) ~= m_x + σ
+    //
+    // All together, we end up with:
+    //
+    // log2(x) = e_x + m_x + σ
+    //
+    // Using the binary/integer representation I_x of a float:
+    //
+    // I_x = E_x * L + M_x
+    //
+    // Where:
+    // - B is the exponent bias, or B = 127 for single precision floats
+    // - E_x is the biased exponent, or E_x = e_x + B
+    // - L is the magnitude of the significand, or L = 2^23
+    // - M_x is the significand M_x = m_x * L
+    //
+    // I_x = E_x * L + M_x
+    //     = L * (e_x + B) + L * m_x
+    //     = L * (e_x + m_x + B)
+    //     = L * (e_x + m_x + σ + B - σ)
+    //    ~= L * (log2(x) + B - σ)
+    //    ~= L * log2(x) + L * (B - σ)
+    //
+    // We have thus:
+    //
+    // log2(x) ~= I_x / L - (B - σ)
+    //
+    // With:
+    //
+    // y = x^(1/3)
+    //
+    // We have:
+    //
+    // log2(y) = 1/3 * log2(x)
+    //
+    // I_y / L - (B - σ) ~!= 1/3 * (I_x / L - (B - σ))
+    //
+    // By simplification:
+    //
+    // I_y ~= 1/3 * L * (B - σ) + 1/3 * I_x
+    //
+    // We now need to find a good value for 1/3 * L * (B - σ),
+    // which is equivalent to finding a good σ since L and B are fixed.
+    //
+    // Reusing the previous simplification, the approximation for the
+    // cube root of 1 would be:
+    //
+    // I(1^1/3) ~= 1/3 * L * (B - σ) + 1/3 * I(1)
+    //
+    // 1/3 * L * (B - σ) ~= I(1^1/3) - 1/3 * I(1)
+    //
+    // Since I(1^1/3) == I(1):
+    //
+    // 1/3 * L * (B - σ) ~= 2/3 * I(1)
+    //
+    // For single precision floats:
+    //
+    // I(1) = 0x3f800000
+    //
+    // 2/3 * I(1) = 0x2a555555
+    //
+    // All together, we get:
+    //
+    // I_y = 0x2a555555 + I_x / 3
+    //
+    // Finally by going going back from an integer representation to a single
+    // precision float, we obtain our first approximation of the cube root.
+    //
+    // We further improve that approximation by using two rounds of the Newton-
+    // Rhapson method. One round proved not precise enough for our needs, and
+    // more rounds don't improve the results significantly given our use cases.
+    //
+    // Note: the constant 0x2a555555 we computed earlier is only a standalone
+    // approximation that doesn't account for the subsequent Newton-Rhapson
+    // refinements. The approximation can be improved for Newton-Rhapson by
+    // debiasing it. To debias 0x2a555555 we follow the solution used by the
+    // now famous "Quake 3 inverse square root". Instead of using 0x5f400000
+    // as the "magic constant" (following our derivation above, you can compute
+    // the constant for an inverse square root using (1 - -1/2) * I(1)), the
+    // Quake 3 solution uses 0x5f3759df. To improve our constant we simply
+    // apply the same ratio:
+    //
+    // magic = 0x2a555555 * 0x5f3759df / 0x5f400000
+    //       = 0x2a517d40
+    val v = x.toRawBits().toLong() and 0x1ffffffffL
+    var estimate = floatFromBits((0x2a517d40L + v / 3).toInt())
+
+    // 2 rounds of the Newton-Rhapson method to improve accuracy
+    estimate -= (estimate - x / (estimate * estimate)) * (1.0f / 3.0f)
+    estimate -= (estimate - x / (estimate * estimate)) * (1.0f / 3.0f)
+
+    return estimate
+}
diff --git a/compose/ui/ui-util/src/jvmMain/kotlin/androidx/compose/ui/util/InlineClassHelper.jvm.kt b/compose/ui/ui-util/src/jvmMain/kotlin/androidx/compose/ui/util/InlineClassHelper.jvm.kt
index b93f1e7..94e9bb1 100644
--- a/compose/ui/ui-util/src/jvmMain/kotlin/androidx/compose/ui/util/InlineClassHelper.jvm.kt
+++ b/compose/ui/ui-util/src/jvmMain/kotlin/androidx/compose/ui/util/InlineClassHelper.jvm.kt
@@ -18,7 +18,11 @@
 
 package androidx.compose.ui.util
 
-// See explanation in FastFloatParser.kt
+// See explanation in InlineClassHelper.kt
 actual inline fun floatFromBits(bits: Int): Float = java.lang.Float.intBitsToFloat(bits)
 
 actual inline fun doubleFromBits(bits: Long): Double = java.lang.Double.longBitsToDouble(bits)
+
+actual inline fun Float.fastRoundToInt(): Int = Math.round(this)
+
+actual inline fun Double.fastRoundToInt(): Int = Math.round(this).toInt()
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/ModifiersBenchmark.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/ModifiersBenchmark.kt
index 3a4f723..990c4d4 100644
--- a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/ModifiersBenchmark.kt
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/ModifiersBenchmark.kt
@@ -19,8 +19,7 @@
 package androidx.compose.ui.benchmark
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.Indication
-import androidx.compose.foundation.IndicationInstance
+import androidx.compose.foundation.IndicationNodeFactory
 import androidx.compose.foundation.MutatePriority
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
@@ -42,7 +41,6 @@
 import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.foundation.selection.toggleable
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.runtime.Composable
 import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawWithCache
@@ -56,6 +54,8 @@
 import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DrawModifierNode
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
@@ -111,7 +111,14 @@
             *modifier("testTag") { Modifier.testTag("$it") },
             *modifier("selectableGroup") { Modifier.selectableGroup() },
             *modifier("indication") {
-                Modifier.indication(interactionSource, if (it) indication else null)
+                Modifier.indication(
+                    interactionSource,
+                    if (it) {
+                        ColorIndicationNodeFactory(Color.Blue)
+                    } else {
+                        ColorIndicationNodeFactory(Color.Red)
+                    }
+                )
             },
             *modifier("draggable") {
                 Modifier.draggable(
@@ -155,18 +162,34 @@
 
         private val focusRequester = FocusRequester()
         private val interactionSource = MutableInteractionSource()
-        private val indication = object : Indication {
-            @Composable
-            override fun rememberUpdatedInstance(
-                interactionSource: InteractionSource
-            ): IndicationInstance {
-                return object : IndicationInstance {
-                    override fun ContentDrawScope.drawIndication() {
+
+        /**
+         * Simple IndicationNodeFactory implementation that just draws a color overlay - it
+         * purposefully does not observe interactions in order to keep the scope of the benchmark
+         * low: we want to track the performance cost of Modifier.indication, not implementations.
+         * (ripple performance is tracked separately)
+         */
+        private class ColorIndicationNodeFactory(private val color: Color) : IndicationNodeFactory {
+            override fun create(interactionSource: InteractionSource): DelegatableNode {
+                return object : Modifier.Node(), DrawModifierNode {
+                    override fun ContentDrawScope.draw() {
                         drawContent()
+                        drawRect(color = color.copy(alpha = 0.3f), size = size)
                     }
                 }
             }
+            override fun equals(other: Any?): Boolean {
+                if (this === other) return true
+                if (other !is ColorIndicationNodeFactory) return false
+
+                return color == other.color
+            }
+
+            override fun hashCode(): Int {
+                return color.hashCode()
+            }
         }
+
         private val draggableState = object : DraggableState {
             override suspend fun drag(
                 dragPriority: MutatePriority,
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadScopeSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadScopeSample.kt
index a7086c8..a77df1b 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadScopeSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadScopeSample.kt
@@ -127,10 +127,11 @@
     // given LookaheadScope, whenever the relative position changes.
     fun Modifier.animatePlacementInScope(lookaheadScope: LookaheadScope) = composed {
         // Creates an offset animation
-        var offsetAnimation: Animatable<IntOffset, AnimationVector2D>? by mutableStateOf(
-            null
-        )
-        var targetOffset: IntOffset? by mutableStateOf(null)
+        var offsetAnimation: Animatable<IntOffset, AnimationVector2D>? by remember {
+            mutableStateOf(
+                null
+            )
+        }
 
         this.intermediateLayout { measurable, constraints ->
             val placeable = measurable.measure(constraints)
@@ -142,7 +143,7 @@
                     val target = with(lookaheadScope) {
                         lookaheadScopeCoordinates
                             .localLookaheadPositionOf(coordinates)
-                            .round().also { targetOffset = it }
+                            .round()
                     }
 
                     // Uses the target offset to start an offset animation
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
index 4c4d99f..ece23e5 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
@@ -45,6 +45,7 @@
 import android.widget.Button
 import android.widget.LinearLayout
 import android.widget.TextView
+import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.clickable
@@ -71,6 +72,8 @@
 import androidx.compose.foundation.selection.toggleable
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.text2.BasicSecureTextField
+import androidx.compose.foundation.text2.input.rememberTextFieldState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.BottomAppBar
 import androidx.compose.material.Button
@@ -82,6 +85,7 @@
 import androidx.compose.material.Icon
 import androidx.compose.material.IconButton
 import androidx.compose.material.Scaffold
+import androidx.compose.material.Surface
 import androidx.compose.material.Text
 import androidx.compose.material.TopAppBar
 import androidx.compose.material.icons.Icons
@@ -356,6 +360,38 @@
         }
     }
 
+    @OptIn(ExperimentalFoundationApi::class)
+    @Test
+    fun testCreateAccessibilityNodeInfo_forSecureTextField() {
+        // Arrange.
+        setContent {
+            Surface {
+                // BasicSecureTextField is considered a password field.
+                BasicSecureTextField(
+                    state = rememberTextFieldState(),
+                    modifier = Modifier.testTag(tag)
+                )
+            }
+        }
+
+        val passwordFieldId = rule.onNodeWithTag(tag, true).semanticsId
+
+        // Act.
+        val info = rule.runOnIdle { createAccessibilityNodeInfo(passwordFieldId) }
+
+        // Assert.
+        rule.runOnIdle {
+            with(AccessibilityNodeInfoCompat.wrap(info)) {
+                assertThat(className).isEqualTo("android.widget.EditText")
+                assertThat(isPassword).isTrue()
+                assertThat(isFocusable).isTrue()
+                assertThat(isFocused).isFalse()
+                assertThat(isEditable).isTrue()
+                assertThat(isVisibleToUser).isTrue()
+            }
+        }
+    }
+
     @Test
     fun testCreateAccessibilityNodeInfo_forDropdown() {
         // Arrange.
@@ -2363,12 +2399,17 @@
         // Arrange.
         val focusRequester = FocusRequester()
         setContent {
-            Box(
-                Modifier
-                    .testTag(tag)
-                    .focusRequester(focusRequester)
-                    .focusable()) {
-                BasicText("focusable")
+            Row {
+                // Initially focused item.
+                Box(Modifier.size(10.dp).focusable())
+                Box(
+                    Modifier
+                        .testTag(tag)
+                        .focusRequester(focusRequester)
+                        .focusable()
+                ) {
+                    BasicText("focusable")
+                }
             }
         }
         rule.runOnIdle { focusRequester.requestFocus() }
@@ -2514,11 +2555,15 @@
     fun testTextField_testFocusClearFocusAction() {
         // Arrange.
         setContent {
-            BasicTextField(
-                modifier = Modifier.testTag(tag),
-                value = "value",
-                onValueChange = {}
-            )
+            Row {
+                // Initially focused item.
+                Box(Modifier.size(10.dp).focusable())
+                BasicTextField(
+                    modifier = Modifier.testTag(tag),
+                    value = "value",
+                    onValueChange = {}
+                )
+            }
         }
         val textFieldId = rule.onNodeWithTag(tag)
             .assert(expectValue(Focused, false))
@@ -3390,7 +3435,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.R)
     fun viewInteropIsInvisibleToUser() {
         setContent {
-             AndroidView({ TextView(it).apply { text = "Test"; isScreenReaderFocusable = true } })
+            AndroidView({ TextView(it).apply { text = "Test"; isScreenReaderFocusable = true } })
         }
         Espresso
             .onView(instanceOf(TextView::class.java))
@@ -4186,8 +4231,8 @@
                     textPositionOnScreenY,
                     textPositionOnScreenX + size,
                     textPositionOnScreenY + size
+                )
             )
-        )
     }
 
     @Test
@@ -5185,7 +5230,7 @@
                 Modifier
                     .progressSemantics(0.5f)
                     .testTag("box")) {
-                 BasicText("test", Modifier.testTag("child"))
+                BasicText("test", Modifier.testTag("child"))
             }
         }
         val boxId = rule.onNodeWithTag("box", useUnmergedTree = true).semanticsId
@@ -5212,7 +5257,7 @@
                 Modifier
                     .progressSemantics()
                     .testTag("box")) {
-                 BasicText("test", Modifier.testTag("child"))
+                BasicText("test", Modifier.testTag("child"))
             }
         }
         val boxId = rule.onNodeWithTag("box", useUnmergedTree = true).semanticsId
@@ -5310,11 +5355,11 @@
     private fun getAccessibilityEventSourceSemanticsNodeId(
         event: android.view.accessibility.AccessibilityEvent
     ): Int = Class
-            .forName("android.view.accessibility.AccessibilityRecord")
-            .getDeclaredMethod("getSourceNodeId").run {
-                isAccessible = true
-                invoke(event) as Long shr 32
-            }.toInt()
+        .forName("android.view.accessibility.AccessibilityRecord")
+        .getDeclaredMethod("getSourceNodeId").run {
+            isAccessible = true
+            invoke(event) as Long shr 32
+        }.toInt()
 
     private fun createMovementGranularityCharacterArgs(): Bundle {
         return Bundle().apply {
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
index 5b4c70b..015999c 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
@@ -23,43 +23,25 @@
 import android.os.Build.VERSION_CODES.P
 import android.os.Build.VERSION_CODES.R
 import android.text.SpannableString
-import android.util.LongSparseArray
 import android.view.View
-import android.view.ViewStructure
 import android.view.accessibility.AccessibilityEvent
-import android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE
 import android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED
-import android.view.accessibility.AccessibilityEvent.TYPE_VIEW_SCROLLED
 import android.view.accessibility.AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
 import android.view.accessibility.AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
 import android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
 import android.view.accessibility.AccessibilityNodeInfo
 import android.view.accessibility.AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_FLOAT
-import android.view.translation.TranslationRequestValue
-import android.view.translation.TranslationResponseValue
-import android.view.translation.ViewTranslationRequest
-import android.view.translation.ViewTranslationRequest.ID_TEXT
-import android.view.translation.ViewTranslationResponse
-import androidx.annotation.RequiresApi
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.size
-import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
-import androidx.compose.runtime.snapshots.Snapshot
-import androidx.compose.runtime.structuralEqualityPolicy
-import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.platform.AndroidComposeView
 import androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat
 import androidx.compose.ui.platform.LocalClipboardManager
 import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.platform.coreshims.ContentCaptureSessionCompat
-import androidx.compose.ui.platform.coreshims.ViewStructureCompat
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.LiveRegionMode
 import androidx.compose.ui.semantics.ProgressBarRangeInfo
 import androidx.compose.ui.semantics.Role
@@ -67,11 +49,9 @@
 import androidx.compose.ui.semantics.SemanticsPropertyKey
 import androidx.compose.ui.semantics.SemanticsPropertyReceiver
 import androidx.compose.ui.semantics.clearAndSetSemantics
-import androidx.compose.ui.semantics.clearTextSubstitution
 import androidx.compose.ui.semantics.collapse
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.copyText
-import androidx.compose.ui.semantics.customActions
 import androidx.compose.ui.semantics.cutText
 import androidx.compose.ui.semantics.disabled
 import androidx.compose.ui.semantics.dismiss
@@ -84,7 +64,6 @@
 import androidx.compose.ui.semantics.heading
 import androidx.compose.ui.semantics.horizontalScrollAxisRange
 import androidx.compose.ui.semantics.invisibleToUser
-import androidx.compose.ui.semantics.isShowingTextSubstitution
 import androidx.compose.ui.semantics.liveRegion
 import androidx.compose.ui.semantics.onClick
 import androidx.compose.ui.semantics.onLongClick
@@ -96,55 +75,37 @@
 import androidx.compose.ui.semantics.setProgress
 import androidx.compose.ui.semantics.setSelection
 import androidx.compose.ui.semantics.setText
-import androidx.compose.ui.semantics.setTextSubstitution
-import androidx.compose.ui.semantics.showTextSubstitution
 import androidx.compose.ui.semantics.stateDescription
 import androidx.compose.ui.semantics.testTag
 import androidx.compose.ui.semantics.testTagsAsResourceId
 import androidx.compose.ui.semantics.text
 import androidx.compose.ui.semantics.textSelectionRange
-import androidx.compose.ui.semantics.textSubstitution
-import androidx.compose.ui.semantics.verticalScrollAxisRange
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.TestActivity
 import androidx.compose.ui.test.junit4.ComposeContentTestRule
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
 import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION
-import androidx.core.view.accessibility.AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_CLICK
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_COLLAPSE
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_DISMISS
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_EXPAND
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_PASTE
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
-import androidx.core.view.doOnDetach
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Correspondence
 import com.google.common.truth.Truth.assertThat
-import java.util.function.Consumer
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.clearInvocations
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyNoMoreInteractions
-import org.mockito.kotlin.whenever
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
@@ -154,11 +115,8 @@
 
     private val tag = "tag"
     private lateinit var androidComposeView: AndroidComposeView
-    private lateinit var contentCaptureSessionCompat: ContentCaptureSessionCompat
-    private lateinit var viewStructureCompat: ViewStructureCompat
     private val dispatchedAccessibilityEvents = mutableListOf<AccessibilityEvent>()
     private val accessibilityEventLoopIntervalMs = 100L
-    private val contentCaptureEventLoopIntervalMs = 100L
 
     @Test
     @OptIn(ExperimentalComposeUiApi::class)
@@ -1058,358 +1016,6 @@
     }
 
     @Test
-    fun sendScrollEvent_byStateObservation_horizontal() {
-        // Arrange.
-        var scrollValue by mutableStateOf(0f, structuralEqualityPolicy())
-        val scrollMaxValue = 100f
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Row(
-                Modifier
-                    .size(20.toDp(), 10.toDp())
-                    .semantics(mergeDescendants = false) {
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            { scrollValue },
-                            { scrollMaxValue }
-                        )
-                    }
-            ) {
-                Text("foo", Modifier.size(10.toDp()))
-                Text("bar",
-                    Modifier
-                        .size(10.toDp())
-                        .testTag(tag))
-            }
-        }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
-        rule.runOnIdle { dispatchedAccessibilityEvents.clear() }
-
-        // Act.
-        try {
-            androidComposeView.snapshotObserver.startObserving()
-            rule.runOnIdle {
-                androidComposeView.accessibilityNodeProvider
-                    .performAction(virtualViewId, ACTION_ACCESSIBILITY_FOCUS, null)
-                Snapshot.notifyObjectsInitialized()
-                scrollValue = 2f
-                Snapshot.sendApplyNotifications()
-            }
-        } finally {
-            androidComposeView.snapshotObserver.stopObserving()
-        }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            val focusedANI = androidComposeView.accessibilityNodeProvider
-                .findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY)
-            assertThat(Rect().also { focusedANI?.getBoundsInScreen(it) })
-                .isEqualTo(Rect(10, 0, 20, 10))
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_VIEW_ACCESSIBILITY_FOCUSED
-                    },
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_SUBTREE
-                    },
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_VIEW_SCROLLED
-                        scrollX = 2
-                        maxScrollX = 100
-                    },
-                )
-        }
-    }
-
-    @Test
-    fun sendScrollEvent_byStateObservation_vertical() {
-        // Arrange.
-        var scrollValue by mutableStateOf(0f, structuralEqualityPolicy())
-        val scrollMaxValue = 100f
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        verticalScrollAxisRange = ScrollAxisRange(
-                            { scrollValue },
-                            { scrollMaxValue }
-                        )
-                    }
-            )
-        }
-
-        // TODO(b/272068594): We receive an extra TYPE_WINDOW_CONTENT_CHANGED event 100ms after
-        //  setup. So we wait an extra 100ms here so that this test is not affected by that extra
-        //  event.
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-        dispatchedAccessibilityEvents.clear()
-
-        // Act.
-        try {
-            androidComposeView.snapshotObserver.startObserving()
-            rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-            rule.runOnIdle {
-                Snapshot.notifyObjectsInitialized()
-                scrollValue = 2f
-                Snapshot.sendApplyNotifications()
-            }
-        } finally {
-            androidComposeView.snapshotObserver.stopObserving()
-        }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_SUBTREE
-                    },
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_VIEW_SCROLLED
-                        scrollY = 2
-                        maxScrollY = 100
-                    },
-                )
-        }
-    }
-
-    @Test
-    fun sendWindowContentChangeUndefinedEventByDefault_whenPropertyAdded() {
-        // Arrange.
-        var addProperty by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        if (addProperty) disabled()
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { addProperty = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
-                    }
-                )
-        }
-    }
-
-    @Test
-    fun sendWindowContentChangeUndefinedEventByDefault_whenPropertyRemoved() {
-        // Arrange.
-        var removeProperty by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        if (!removeProperty) disabled()
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { removeProperty = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
-                    }
-                )
-        }
-    }
-
-    @Test
-    @Ignore("b/307823561")
-    fun sendWindowContentChangeUndefinedEventByDefault_onlyOnce_whenMultiplePropertiesChange() {
-        // Arrange.
-        var propertiesChanged by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        if (!propertiesChanged) {
-                            disabled()
-                        } else {
-                            onClick { true }
-                        }
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { propertiesChanged = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
-                    }
-                )
-        }
-    }
-
-    @Test
-    fun sendWindowContentChangeUndefinedEventByDefault_standardActionWithTheSameLabel() {
-        // Arrange.
-        var newAction by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        if (!newAction) {
-                            onClick(label = "action") { true }
-                        } else {
-                            onClick(label = "action") { true }
-                        }
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { newAction = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle { assertThat(dispatchedAccessibilityEvents).isEmpty() }
-    }
-
-    @Test
-    fun sendWindowContentChangeUndefinedEventByDefault_standardActionWithDifferentLabels() {
-        // Arrange.
-        var newAction by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        if (!newAction) {
-                            onClick(label = "action1") { true }
-                        } else {
-                            onClick(label = "action2") { true }
-                        }
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { newAction = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
-                    }
-                )
-        }
-    }
-
-    @Test
-    fun sendWindowContentChangeUndefinedEventByDefault_customActionWithTheSameLabel() {
-        // Arrange.
-        var newAction by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        customActions = if (!newAction) {
-                            listOf(CustomAccessibilityAction("action") { true })
-                        } else {
-                            listOf(CustomAccessibilityAction("action") { false })
-                        }
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { newAction = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle { assertThat(dispatchedAccessibilityEvents).isEmpty() }
-    }
-
-    @Test
-    fun sendWindowContentChangeUndefinedEventByDefault_customActionWithDifferentLabels() {
-        // Arrange.
-        var newAction by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics(mergeDescendants = false) {
-                        customActions = if (!newAction) {
-                            listOf(CustomAccessibilityAction("action1") { true })
-                        } else {
-                            listOf(CustomAccessibilityAction("action2") { true })
-                        }
-                    }
-            )
-        }
-
-        // Act.
-        rule.runOnIdle { newAction = true }
-        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(dispatchedAccessibilityEvents)
-                .comparingElementsUsing(AccessibilityEventComparator)
-                .containsExactly(
-                    AccessibilityEvent().apply {
-                        eventType = TYPE_WINDOW_CONTENT_CHANGED
-                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
-                    }
-                )
-        }
-    }
-
-    @Test
     fun testUncoveredNodes_notPlacedNodes_notIncluded() {
         // Arrange.
         rule.setContentWithAccessibilityEnabled {
@@ -1489,294 +1095,6 @@
         }
     }
 
-    @Test
-    fun canScroll_returnsFalse_whenPositionInvalid() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.dp)
-                    .semantics(mergeDescendants = true) {
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 0f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(-1)).isFalse()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsTrue_whenHorizontalScrollableNotAtLimit() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 0.5f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            // Should be scrollable in both directions.
-            assertThat(androidComposeView.canScrollHorizontally(1)).isTrue()
-            assertThat(androidComposeView.canScrollHorizontally(0)).isTrue()
-            assertThat(androidComposeView.canScrollHorizontally(-1)).isTrue()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsTrue_whenVerticalScrollableNotAtLimit() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        verticalScrollAxisRange = ScrollAxisRange(
-                            value = { 0.5f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            // Should be scrollable in both directions.
-            assertThat(androidComposeView.canScrollVertically(1)).isTrue()
-            assertThat(androidComposeView.canScrollVertically(0)).isTrue()
-            assertThat(androidComposeView.canScrollVertically(-1)).isTrue()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsFalse_whenHorizontalScrollable_whenScrolledRightAndAtLimit() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 1f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(-1)).isTrue()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsFalse_whenHorizontalScrollable_whenScrolledLeftAndAtLimit() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 0f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollHorizontally(1)).isTrue()
-            assertThat(androidComposeView.canScrollHorizontally(0)).isTrue()
-            assertThat(androidComposeView.canScrollHorizontally(-1)).isFalse()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsFalse_whenVerticalScrollable_whenScrolledDownAndAtLimit() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        verticalScrollAxisRange = ScrollAxisRange(
-                            value = { 1f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollVertically(1)).isFalse()
-            assertThat(androidComposeView.canScrollVertically(0)).isFalse()
-            assertThat(androidComposeView.canScrollVertically(-1)).isTrue()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsFalse_whenVerticalScrollable_whenScrolledUpAndAtLimit() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        verticalScrollAxisRange = ScrollAxisRange(
-                            value = { 0f },
-                            maxValue = { 1f },
-                            reverseScrolling = false
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollVertically(1)).isTrue()
-            assertThat(androidComposeView.canScrollVertically(0)).isTrue()
-            assertThat(androidComposeView.canScrollVertically(-1)).isFalse()
-        }
-    }
-
-    @Test
-    fun canScroll_respectsReverseDirection() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 0f },
-                            maxValue = { 1f },
-                            reverseScrolling = true
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(-1)).isTrue()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsFalse_forVertical_whenScrollableIsHorizontal() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(100.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 0.5f },
-                            maxValue = { 1f },
-                            reverseScrolling = true
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollVertically(1)).isFalse()
-            assertThat(androidComposeView.canScrollVertically(0)).isFalse()
-            assertThat(androidComposeView.canScrollVertically(-1)).isFalse()
-        }
-    }
-
-    @Test
-    fun canScroll_returnsFalse_whenTouchIsOutsideBounds() {
-        // Arrange.
-        rule.setContentWithAccessibilityEnabled {
-            Box(
-                Modifier
-                    .size(50.toDp())
-                    .semantics(mergeDescendants = true) {
-                        testTag = tag
-                        horizontalScrollAxisRange = ScrollAxisRange(
-                            value = { 0.5f },
-                            maxValue = { 1f },
-                            reverseScrolling = true
-                        )
-                    }
-            )
-        }
-
-        // Act.
-        rule.onNodeWithTag(tag).performTouchInput { down(Offset(100f, 100f)) }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
-            assertThat(androidComposeView.canScrollHorizontally(-1)).isFalse()
-        }
-    }
-
     // TODO(b/272068594): Asserting that a list does not contain an element can be an incorrect test
     //  because this would pass even if the event was present, (For example when isEnabled = false).
     //  Keeping this here to show parity for code review. This can be removed because the test
@@ -2031,525 +1349,6 @@
         }
     }
 
-    @Test
-    @SdkSuppress(minSdkVersion = 29)
-    fun testInitContentCaptureSemanticsStructureChangeEvents_onStart() {
-        // Arrange.
-        rule.setContentWithContentCaptureEnabled(retainInteractionsDuringInitialization = true) {}
-
-        // Act - Wait for initialization that is triggered by onStart().
-
-        // Assert = verify the root node appeared.
-        rule.runOnIdle {
-            verify(contentCaptureSessionCompat).newVirtualViewStructure(any(), any())
-            verify(contentCaptureSessionCompat).notifyViewsAppeared(any())
-            verify(viewStructureCompat).setDimens(any(), any(), any(), any(), any(), any())
-            verify(viewStructureCompat).toViewStructure()
-            verifyNoMoreInteractions(contentCaptureSessionCompat)
-            verifyNoMoreInteractions(viewStructureCompat)
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 29)
-    fun testInitContentCaptureSemanticsStructureChangeEvents_onStop() {
-        // Arrange.
-        rule.setContentWithContentCaptureEnabled {}
-
-        // Act.
-        rule.runOnIdle {
-            androidComposeView.doOnDetach {
-
-                // Assert.
-                verify(contentCaptureSessionCompat).notifyViewsDisappeared(any())
-                verifyNoMoreInteractions(contentCaptureSessionCompat)
-                verifyNoMoreInteractions(viewStructureCompat)
-            }
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 29)
-    fun testSendContentCaptureSemanticsStructureChangeEvents_appeared() {
-        // Arrange.
-        var appeared by mutableStateOf(false)
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Row(
-                Modifier
-                    .size(100.dp)
-                    .semantics {}) {
-                if (appeared) {
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { text = AnnotatedString("foo") })
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { text = AnnotatedString("bar") })
-                }
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { appeared = true }
-        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
-        //  invocations of boundsUpdatesEventLoop.
-        repeat(2) {
-            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-            rule.waitForIdle()
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            with(argumentCaptor<CharSequence>()) {
-                verify(viewStructureCompat, times(2)).setText(capture())
-                assertThat(firstValue).isEqualTo("foo")
-                assertThat(secondValue).isEqualTo("bar")
-            }
-            verify(contentCaptureSessionCompat, times(0)).notifyViewsDisappeared(any())
-            with(argumentCaptor<List<ViewStructure>>()) {
-                verify(contentCaptureSessionCompat, times(1)).notifyViewsAppeared(capture())
-                assertThat(firstValue.count()).isEqualTo(2)
-            }
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 29)
-    fun testSendContentCaptureSemanticsStructureChangeEvents_disappeared() {
-        // Arrange.
-        var disappeared by mutableStateOf(false)
-
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            if (!disappeared) {
-                Row(
-                    Modifier
-                        .size(100.dp)
-                        .semantics { }) {
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { })
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { })
-                }
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { disappeared = true }
-
-        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
-        //  invocations of boundsUpdatesEventLoop.
-        repeat(2) {
-            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-            rule.waitForIdle()
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            with(argumentCaptor<LongArray>()) {
-                verify(contentCaptureSessionCompat, times(1)).notifyViewsDisappeared(capture())
-                assertThat(firstValue.count()).isEqualTo(3)
-            }
-            verify(contentCaptureSessionCompat, times(0)).notifyViewsAppeared(any())
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 29)
-    fun testSendContentCaptureSemanticsStructureChangeEvents_appearedAndDisappeared() {
-        // Arrange.
-        var appeared by mutableStateOf(false)
-
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            if (appeared) {
-                Row(
-                    Modifier
-                        .size(100.dp)
-                        .semantics { }) {
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { })
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { })
-                }
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { appeared = true }
-        // TODO(b/272068594): This test was written to ensure that if the items appeared and
-        //  disappeared before the 100ms, it would still report the items that were added and the
-        //  items that were removed The items were (As long as the items had different IDs). However
-        //  it is not possible for a items with different IDs to disappear as they are not existing.
-        //  The mocks also limit us to write this test since we can't mock AutofillIDs since
-        //  AutofillId is a final class, and these tests just use the autofill id of the parent
-        //  view.
-        rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-        rule.runOnIdle { appeared = false }
-
-        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for
-        //  two invocations of boundsUpdatesEventLoop.
-        repeat(2) {
-            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-            rule.waitForIdle()
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            with(argumentCaptor<LongArray>()) {
-                verify(contentCaptureSessionCompat, times(1)).notifyViewsDisappeared(capture())
-                assertThat(firstValue.count()).isEqualTo(3)
-            }
-            with(argumentCaptor<List<ViewStructure>>()) {
-                verify(contentCaptureSessionCompat, times(1)).notifyViewsAppeared(capture())
-                assertThat(firstValue.count()).isEqualTo(3)
-            }
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 29)
-    fun testSendContentCaptureSemanticsStructureChangeEvents_sameNodeAppearedThenDisappeared() {
-        // Arrange.
-        var appeared by mutableStateOf(false)
-
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { }) {
-                if (appeared) {
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics { })
-                }
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { appeared = true }
-
-        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
-        //  invocations of boundsUpdatesEventLoop.
-        repeat(2) {
-            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-            rule.waitForIdle()
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            verify(contentCaptureSessionCompat, times(0)).notifyViewsDisappeared(any())
-            with(argumentCaptor<List<ViewStructure>>()) {
-                verify(contentCaptureSessionCompat, times(1)).notifyViewsAppeared(capture())
-                assertThat(firstValue.count()).isEqualTo(1)
-            }
-            clearInvocations(contentCaptureSessionCompat)
-        }
-
-        rule.runOnIdle { appeared = false }
-
-        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
-        //  invocations of boundsUpdatesEventLoop.
-        repeat(2) {
-            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-            rule.waitForIdle()
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            verify(contentCaptureSessionCompat, times(0)).notifyViewsDisappeared(any())
-            verify(contentCaptureSessionCompat, times(0)).notifyViewsAppeared(any())
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testUpdateTranslationOnAppeared_showOriginal() {
-        // Arrange.
-        var appeared by mutableStateOf(false)
-        var result = true
-
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { }) {
-                if (appeared) {
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics {
-                                text = AnnotatedString("foo")
-                                isShowingTextSubstitution = true
-                                showTextSubstitution {
-                                    result = it
-                                    true
-                                }
-                            }
-                    )
-                }
-            }
-        }
-        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onHideTranslation() }
-
-        // Act.
-        rule.runOnIdle { appeared = true }
-        rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle { assertThat(result).isFalse() }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testUpdateTranslationOnAppeared_showTranslated() {
-        // Arrange.
-        var appeared by mutableStateOf(false)
-        var result = false
-
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { }) {
-                if (appeared) {
-                    Box(
-                        Modifier
-                            .size(10.dp)
-                            .semantics {
-                                text = AnnotatedString("foo")
-                                isShowingTextSubstitution = false
-                                showTextSubstitution {
-                                    result = it
-                                    true
-                                }
-                            }
-                    )
-                }
-            }
-        }
-        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onShowTranslation() }
-
-        // Act.
-        rule.runOnIdle { appeared = true }
-        rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
-
-        // Assert.
-        rule.runOnIdle { assertThat(result).isTrue() }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testOnCreateVirtualViewTranslationRequests() {
-        // Arrange.
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { text = AnnotatedString("bar") }) {
-                Box(
-                    Modifier
-                        .size(10.dp)
-                        .semantics {
-                            testTag = tag
-                            text = AnnotatedString("foo")
-                        }
-                )
-            }
-        }
-        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
-
-        val ids = LongArray(1).apply { this[0] = virtualViewId.toLong() }
-        val requestsCollector: Consumer<ViewTranslationRequest?> = mock()
-
-        // Act.
-        rule.runOnIdle {
-            androidComposeView.onCreateVirtualViewTranslationRequests(
-                ids,
-                IntArray(0),
-                requestsCollector
-            )
-        }
-
-        // Assert.
-        rule.runOnIdle {
-            with(argumentCaptor<ViewTranslationRequest>()) {
-                verify(requestsCollector).accept(capture())
-                assertThat(firstValue).isEqualTo(
-                    ViewTranslationRequest
-                        .Builder(androidComposeView.autofillId, virtualViewId.toLong())
-                        .setValue(ID_TEXT, TranslationRequestValue.forText(AnnotatedString("foo")))
-                        .build()
-                )
-            }
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testOnVirtualViewTranslationResponses() {
-        // Arrange.
-        var result: AnnotatedString? = null
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { text = AnnotatedString("bar") }) {
-                Box(
-                    Modifier
-                        .size(10.dp)
-                        .semantics {
-                            testTag = tag
-                            text = AnnotatedString("foo")
-                            setTextSubstitution {
-                                result = it
-                                true
-                            }
-                        }
-                )
-            }
-        }
-        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
-
-        // Act.
-        rule.runOnIdle {
-            androidComposeView.onVirtualViewTranslationResponses(
-                LongSparseArray<ViewTranslationResponse?>().apply {
-                    append(
-                        virtualViewId.toLong(),
-                        ViewTranslationResponse
-                            .Builder(androidComposeView.autofillId)
-                            .setValue(
-                                ID_TEXT,
-                                TranslationResponseValue.Builder(0).setText("bar").build()
-                            )
-                            .build()
-                    )
-                }
-            )
-        }
-
-        // Assert.
-        rule.runOnIdle { assertThat(result).isEqualTo(AnnotatedString("bar")) }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testOnShowTranslation() {
-        // Arrange.
-        var result = false
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { text = AnnotatedString("bar") }) {
-                Box(
-                    Modifier
-                        .size(10.dp)
-                        .semantics {
-                            textSubstitution = AnnotatedString("foo")
-                            isShowingTextSubstitution = false
-                            showTextSubstitution {
-                                result = it
-                                true
-                            }
-                        }
-                )
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onShowTranslation() }
-
-        // Assert.
-        rule.runOnIdle { assertThat(result).isTrue() }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testOnHideTranslation() {
-        // Arrange.
-        var result = true
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { text = AnnotatedString("bar") }) {
-                Box(
-                    Modifier
-                        .size(10.dp)
-                        .semantics {
-                            text = AnnotatedString("bar")
-                            textSubstitution = AnnotatedString("foo")
-                            isShowingTextSubstitution = true
-                            showTextSubstitution {
-                                result = it
-                                true
-                            }
-                        }
-                )
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onHideTranslation() }
-
-        // Assert.
-        rule.runOnIdle { assertThat(result).isFalse() }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 31)
-    fun testOnClearTranslation() {
-        // Arrange.
-        var result = false
-        rule.mainClock.autoAdvance = false
-        rule.setContentWithContentCaptureEnabled {
-            Box(
-                Modifier
-                    .size(10.dp)
-                    .semantics { text = AnnotatedString("bar") }) {
-                Box(
-                    Modifier
-                        .size(10.dp)
-                        .semantics {
-                            text = AnnotatedString("bar")
-                            isShowingTextSubstitution = true
-                            clearTextSubstitution {
-                                result = true
-                                true
-                            }
-                        }
-                )
-            }
-        }
-
-        // Act.
-        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onClearTranslation() }
-
-        // Assert.
-        rule.runOnIdle { assertThat(result).isTrue() }
-    }
-
     private fun Int.toDp(): Dp = with(rule.density) { [email protected]() }
 
     private fun ComposeContentTestRule.setContentWithAccessibilityEnabled(
@@ -2570,47 +1369,6 @@
         runOnIdle { dispatchedAccessibilityEvents.clear() }
     }
 
-    @RequiresApi(Build.VERSION_CODES.O)
-    private fun ComposeContentTestRule.setContentWithContentCaptureEnabled(
-        retainInteractionsDuringInitialization: Boolean = false,
-        content: @Composable () -> Unit
-    ) {
-        contentCaptureSessionCompat = mock()
-        viewStructureCompat = mock()
-        val viewStructure: ViewStructure = mock()
-
-        whenever(contentCaptureSessionCompat.newVirtualViewStructure(any(), any()))
-            .thenReturn(viewStructureCompat)
-        whenever(viewStructureCompat.toViewStructure())
-            .thenReturn(viewStructure)
-
-        setContent {
-            androidComposeView = LocalView.current as AndroidComposeView
-            with(androidComposeView.composeAccessibilityDelegate) {
-                accessibilityForceEnabledForTesting = true
-                contentCaptureForceEnabledForTesting = true
-                contentCaptureSession = contentCaptureSessionCompat
-                onSendAccessibilityEvent = { dispatchedAccessibilityEvents += it; false }
-            }
-
-            whenever(contentCaptureSessionCompat.newAutofillId(any())).thenAnswer {
-                androidComposeView.autofillId
-            }
-
-            content()
-        }
-
-        // Advance the clock past the first accessibility event loop, and clear the initial
-        // as we are want the assertions to check the events that were generated later.
-        runOnIdle { mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs) }
-
-        runOnIdle {
-            if (!retainInteractionsDuringInitialization) {
-                clearInvocations(contentCaptureSessionCompat, viewStructureCompat)
-            }
-        }
-    }
-
     private fun AndroidComposeView.createAccessibilityNodeInfo(
         semanticsId: Int
     ): AccessibilityNodeInfoCompat {
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/ContentCaptureTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/ContentCaptureTest.kt
new file mode 100644
index 0000000..60c607a
--- /dev/null
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/ContentCaptureTest.kt
@@ -0,0 +1,674 @@
+
+/*
+ * 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.
+ */
+
+package androidx.compose.ui
+
+import android.os.Build
+import android.util.LongSparseArray
+import android.view.View
+import android.view.ViewStructure
+import android.view.accessibility.AccessibilityEvent
+import android.view.translation.TranslationRequestValue
+import android.view.translation.TranslationResponseValue
+import android.view.translation.ViewTranslationRequest
+import android.view.translation.ViewTranslationRequest.ID_TEXT
+import android.view.translation.ViewTranslationResponse
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.platform.AndroidComposeView
+import androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.coreshims.ContentCaptureSessionCompat
+import androidx.compose.ui.platform.coreshims.ViewStructureCompat
+import androidx.compose.ui.semantics.clearTextSubstitution
+import androidx.compose.ui.semantics.isShowingTextSubstitution
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.setTextSubstitution
+import androidx.compose.ui.semantics.showTextSubstitution
+import androidx.compose.ui.semantics.testTag
+import androidx.compose.ui.semantics.text
+import androidx.compose.ui.semantics.textSubstitution
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.TestActivity
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.unit.dp
+import androidx.core.view.ViewCompat
+import androidx.core.view.doOnDetach
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import java.util.function.Consumer
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyNoMoreInteractions
+import org.mockito.kotlin.whenever
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class ContentCaptureTest {
+    @get:Rule
+    val rule = createAndroidComposeRule<TestActivity>()
+
+    private val tag = "tag"
+    private lateinit var androidComposeView: AndroidComposeView
+    private lateinit var contentCaptureSessionCompat: ContentCaptureSessionCompat
+    private lateinit var viewStructureCompat: ViewStructureCompat
+    private val dispatchedAccessibilityEvents = mutableListOf<AccessibilityEvent>()
+    private val contentCaptureEventLoopIntervalMs = 100L
+
+    @Test
+    @SdkSuppress(minSdkVersion = 29)
+    fun testInitContentCaptureSemanticsStructureChangeEvents_onStart() {
+        // Arrange.
+        rule.setContentWithContentCaptureEnabled(retainInteractionsDuringInitialization = true) {}
+
+        // Act - Wait for initialization that is triggered by onStart().
+
+        // Assert = verify the root node appeared.
+        rule.runOnIdle {
+            verify(contentCaptureSessionCompat).newVirtualViewStructure(any(), any())
+            verify(contentCaptureSessionCompat).notifyViewsAppeared(any())
+            verify(viewStructureCompat).setDimens(any(), any(), any(), any(), any(), any())
+            verify(viewStructureCompat).toViewStructure()
+            verifyNoMoreInteractions(contentCaptureSessionCompat)
+            verifyNoMoreInteractions(viewStructureCompat)
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 29)
+    fun testInitContentCaptureSemanticsStructureChangeEvents_onStop() {
+        // Arrange.
+        rule.setContentWithContentCaptureEnabled {}
+
+        // Act.
+        rule.runOnIdle {
+            androidComposeView.doOnDetach {
+
+                // Assert.
+                verify(contentCaptureSessionCompat).notifyViewsDisappeared(any())
+                verifyNoMoreInteractions(contentCaptureSessionCompat)
+                verifyNoMoreInteractions(viewStructureCompat)
+            }
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 29)
+    fun testSendContentCaptureSemanticsStructureChangeEvents_appeared() {
+        // Arrange.
+        var appeared by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Row(
+                Modifier
+                    .size(100.dp)
+                    .semantics {}
+            ) {
+                if (appeared) {
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { text = AnnotatedString("foo") }
+                    )
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { text = AnnotatedString("bar") }
+                    )
+                }
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { appeared = true }
+        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
+        //  invocations of boundsUpdatesEventLoop.
+        repeat(2) {
+            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+            rule.waitForIdle()
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            with(argumentCaptor<CharSequence>()) {
+                verify(viewStructureCompat, times(2)).setText(capture())
+                assertThat(firstValue).isEqualTo("foo")
+                assertThat(secondValue).isEqualTo("bar")
+            }
+            verify(contentCaptureSessionCompat, times(0)).notifyViewsDisappeared(any())
+            with(argumentCaptor<List<ViewStructure>>()) {
+                verify(contentCaptureSessionCompat, times(1)).notifyViewsAppeared(capture())
+                assertThat(firstValue.count()).isEqualTo(2)
+            }
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 29)
+    fun testSendContentCaptureSemanticsStructureChangeEvents_disappeared() {
+        // Arrange.
+        var disappeared by mutableStateOf(false)
+
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            if (!disappeared) {
+                Row(
+                    Modifier
+                        .size(100.dp)
+                        .semantics { }
+                ) {
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { }
+                    )
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { }
+                    )
+                }
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { disappeared = true }
+
+        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
+        //  invocations of boundsUpdatesEventLoop.
+        repeat(2) {
+            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+            rule.waitForIdle()
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            with(argumentCaptor<LongArray>()) {
+                verify(contentCaptureSessionCompat, times(1)).notifyViewsDisappeared(capture())
+                assertThat(firstValue.count()).isEqualTo(3)
+            }
+            verify(contentCaptureSessionCompat, times(0)).notifyViewsAppeared(any())
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 29)
+    fun testSendContentCaptureSemanticsStructureChangeEvents_appearedAndDisappeared() {
+        // Arrange.
+        var appeared by mutableStateOf(false)
+
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            if (appeared) {
+                Row(
+                    Modifier
+                        .size(100.dp)
+                        .semantics { }
+                ) {
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { }
+                    )
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { }
+                    )
+                }
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { appeared = true }
+        // TODO(b/272068594): This test was written to ensure that if the items appeared and
+        //  disappeared before the 100ms, it would still report the items that were added and the
+        //  items that were removed The items were (As long as the items had different IDs). However
+        //  it is not possible for a items with different IDs to disappear as they are not existing.
+        //  The mocks also limit us to write this test since we can't mock AutofillIDs since
+        //  AutofillId is a final class, and these tests just use the autofill id of the parent
+        //  view.
+        rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+        rule.runOnIdle { appeared = false }
+
+        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for
+        //  two invocations of boundsUpdatesEventLoop.
+        repeat(2) {
+            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+            rule.waitForIdle()
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            with(argumentCaptor<LongArray>()) {
+                verify(contentCaptureSessionCompat, times(1)).notifyViewsDisappeared(capture())
+                assertThat(firstValue.count()).isEqualTo(3)
+            }
+            with(argumentCaptor<List<ViewStructure>>()) {
+                verify(contentCaptureSessionCompat, times(1)).notifyViewsAppeared(capture())
+                assertThat(firstValue.count()).isEqualTo(3)
+            }
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 29)
+    fun testSendContentCaptureSemanticsStructureChangeEvents_sameNodeAppearedThenDisappeared() {
+        // Arrange.
+        var appeared by mutableStateOf(false)
+
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { }
+            ) {
+                if (appeared) {
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics { }
+                    )
+                }
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { appeared = true }
+
+        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
+        //  invocations of boundsUpdatesEventLoop.
+        repeat(2) {
+            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+            rule.waitForIdle()
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            verify(contentCaptureSessionCompat, times(0)).notifyViewsDisappeared(any())
+            with(argumentCaptor<List<ViewStructure>>()) {
+                verify(contentCaptureSessionCompat, times(1)).notifyViewsAppeared(capture())
+                assertThat(firstValue.count()).isEqualTo(1)
+            }
+            clearInvocations(contentCaptureSessionCompat)
+        }
+
+        rule.runOnIdle { appeared = false }
+
+        // TODO(b/272068594): After refactoring this code, ensure that we don't need to wait for two
+        //  invocations of boundsUpdatesEventLoop.
+        repeat(2) {
+            rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+            rule.waitForIdle()
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            verify(contentCaptureSessionCompat, times(0)).notifyViewsDisappeared(any())
+            verify(contentCaptureSessionCompat, times(0)).notifyViewsAppeared(any())
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testUpdateTranslationOnAppeared_showOriginal() {
+        // Arrange.
+        var appeared by mutableStateOf(false)
+        var result = true
+
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { }
+            ) {
+                if (appeared) {
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics {
+                                text = AnnotatedString("foo")
+                                isShowingTextSubstitution = true
+                                showTextSubstitution {
+                                    result = it
+                                    true
+                                }
+                            }
+                    )
+                }
+            }
+        }
+        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onHideTranslation() }
+
+        // Act.
+        rule.runOnIdle { appeared = true }
+        rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle { assertThat(result).isFalse() }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testUpdateTranslationOnAppeared_showTranslated() {
+        // Arrange.
+        var appeared by mutableStateOf(false)
+        var result = false
+
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { }
+            ) {
+                if (appeared) {
+                    Box(
+                        Modifier
+                            .size(10.dp)
+                            .semantics {
+                                text = AnnotatedString("foo")
+                                isShowingTextSubstitution = false
+                                showTextSubstitution {
+                                    result = it
+                                    true
+                                }
+                            }
+                    )
+                }
+            }
+        }
+        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onShowTranslation() }
+
+        // Act.
+        rule.runOnIdle { appeared = true }
+        rule.mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle { assertThat(result).isTrue() }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testOnCreateVirtualViewTranslationRequests() {
+        // Arrange.
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { text = AnnotatedString("bar") }
+            ) {
+                Box(
+                    Modifier
+                        .size(10.dp)
+                        .semantics {
+                            testTag = tag
+                            text = AnnotatedString("foo")
+                        }
+                )
+            }
+        }
+        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
+
+        val ids = LongArray(1).apply { this[0] = virtualViewId.toLong() }
+        val requestsCollector: Consumer<ViewTranslationRequest?> = mock()
+
+        // Act.
+        rule.runOnIdle {
+            androidComposeView.onCreateVirtualViewTranslationRequests(
+                ids,
+                IntArray(0),
+                requestsCollector
+            )
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            with(argumentCaptor<ViewTranslationRequest>()) {
+                verify(requestsCollector).accept(capture())
+                assertThat(firstValue).isEqualTo(
+                    ViewTranslationRequest
+                        .Builder(androidComposeView.autofillId, virtualViewId.toLong())
+                        .setValue(ID_TEXT, TranslationRequestValue.forText(AnnotatedString("foo")))
+                        .build()
+                )
+            }
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testOnVirtualViewTranslationResponses() {
+        // Arrange.
+        var result: AnnotatedString? = null
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { text = AnnotatedString("bar") }
+            ) {
+                Box(
+                    Modifier
+                        .size(10.dp)
+                        .semantics {
+                            testTag = tag
+                            text = AnnotatedString("foo")
+                            setTextSubstitution {
+                                result = it
+                                true
+                            }
+                        }
+                )
+            }
+        }
+        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
+
+        // Act.
+        rule.runOnIdle {
+            androidComposeView.onVirtualViewTranslationResponses(
+                LongSparseArray<ViewTranslationResponse?>().apply {
+                    append(
+                        virtualViewId.toLong(),
+                        ViewTranslationResponse
+                            .Builder(androidComposeView.autofillId)
+                            .setValue(
+                                ID_TEXT,
+                                TranslationResponseValue.Builder(0).setText("bar").build()
+                            )
+                            .build()
+                    )
+                }
+            )
+        }
+
+        // Assert.
+        rule.runOnIdle { assertThat(result).isEqualTo(AnnotatedString("bar")) }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testOnShowTranslation() {
+        // Arrange.
+        var result = false
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { text = AnnotatedString("bar") }
+            ) {
+                Box(
+                    Modifier
+                        .size(10.dp)
+                        .semantics {
+                            textSubstitution = AnnotatedString("foo")
+                            isShowingTextSubstitution = false
+                            showTextSubstitution {
+                                result = it
+                                true
+                            }
+                        }
+                )
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onShowTranslation() }
+
+        // Assert.
+        rule.runOnIdle { assertThat(result).isTrue() }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testOnHideTranslation() {
+        // Arrange.
+        var result = true
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { text = AnnotatedString("bar") }
+            ) {
+                Box(
+                    Modifier
+                        .size(10.dp)
+                        .semantics {
+                            text = AnnotatedString("bar")
+                            textSubstitution = AnnotatedString("foo")
+                            isShowingTextSubstitution = true
+                            showTextSubstitution {
+                                result = it
+                                true
+                            }
+                        }
+                )
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onHideTranslation() }
+
+        // Assert.
+        rule.runOnIdle { assertThat(result).isFalse() }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 31)
+    fun testOnClearTranslation() {
+        // Arrange.
+        var result = false
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithContentCaptureEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics { text = AnnotatedString("bar") }
+            ) {
+                Box(
+                    Modifier
+                        .size(10.dp)
+                        .semantics {
+                            text = AnnotatedString("bar")
+                            isShowingTextSubstitution = true
+                            clearTextSubstitution {
+                                result = true
+                                true
+                            }
+                        }
+                )
+            }
+        }
+
+        // Act.
+        rule.runOnIdle { androidComposeView.composeAccessibilityDelegate.onClearTranslation() }
+
+        // Assert.
+        rule.runOnIdle { assertThat(result).isTrue() }
+    }
+
+    @RequiresApi(Build.VERSION_CODES.O)
+    private fun ComposeContentTestRule.setContentWithContentCaptureEnabled(
+        retainInteractionsDuringInitialization: Boolean = false,
+        content: @Composable () -> Unit
+    ) {
+        contentCaptureSessionCompat = mock()
+        viewStructureCompat = mock()
+        val viewStructure: ViewStructure = mock()
+
+        whenever(contentCaptureSessionCompat.newVirtualViewStructure(any(), any()))
+            .thenReturn(viewStructureCompat)
+        whenever(viewStructureCompat.toViewStructure())
+            .thenReturn(viewStructure)
+
+        setContent {
+            androidComposeView = LocalView.current as AndroidComposeView
+            with(androidComposeView.composeAccessibilityDelegate) {
+                accessibilityForceEnabledForTesting = true
+                contentCaptureForceEnabledForTesting = true
+                contentCaptureSession = contentCaptureSessionCompat
+                onSendAccessibilityEvent = { dispatchedAccessibilityEvents += it; false }
+            }
+
+            whenever(contentCaptureSessionCompat.newAutofillId(any())).thenAnswer {
+                androidComposeView.autofillId
+            }
+
+            content()
+        }
+
+        // Advance the clock past the first accessibility event loop, and clear the initial
+        // as we are want the assertions to check the events that were generated later.
+        runOnIdle { mainClock.advanceTimeBy(contentCaptureEventLoopIntervalMs) }
+
+        runOnIdle {
+            if (!retainInteractionsDuringInitialization) {
+                clearInvocations(contentCaptureSessionCompat, viewStructureCompat)
+            }
+        }
+    }
+
+    private val View.composeAccessibilityDelegate: AndroidComposeViewAccessibilityDelegateCompat
+        get() = ViewCompat.getAccessibilityDelegate(this)
+            as AndroidComposeViewAccessibilityDelegateCompat
+
+    // TODO(b/272068594): Add api to fetch the semantics id from SemanticsNodeInteraction directly.
+    private val SemanticsNodeInteraction.semanticsId: Int get() = fetchSemanticsNode().id
+}
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/accessibility/ScrollingTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/accessibility/ScrollingTest.kt
new file mode 100644
index 0000000..04494ed
--- /dev/null
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/accessibility/ScrollingTest.kt
@@ -0,0 +1,573 @@
+
+/*
+ * 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.
+ */
+
+package androidx.compose.ui.accessibility
+
+import android.graphics.Rect
+import android.os.Build.VERSION.SDK_INT
+import android.os.Build.VERSION_CODES.P
+import android.os.Build.VERSION_CODES.R
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE
+import android.view.accessibility.AccessibilityEvent.TYPE_VIEW_SCROLLED
+import android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+import android.view.accessibility.AccessibilityNodeInfo
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.runtime.snapshots.Snapshot
+import androidx.compose.runtime.structuralEqualityPolicy
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.platform.AndroidComposeView
+import androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.ScrollAxisRange
+import androidx.compose.ui.semantics.horizontalScrollAxisRange
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.testTag
+import androidx.compose.ui.semantics.verticalScrollAxisRange
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.TestActivity
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.core.view.ViewCompat
+import androidx.core.view.accessibility.AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Correspondence
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class ScrollingTest {
+    @get:Rule
+    val rule = createAndroidComposeRule<TestActivity>()
+
+    private val tag = "tag"
+    private lateinit var androidComposeView: AndroidComposeView
+    private val dispatchedAccessibilityEvents = mutableListOf<AccessibilityEvent>()
+    private val accessibilityEventLoopIntervalMs = 100L
+
+    @Test
+    fun sendScrollEvent_byStateObservation_horizontal() {
+        // Arrange.
+        var scrollValue by mutableStateOf(0f, structuralEqualityPolicy())
+        val scrollMaxValue = 100f
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Row(
+                Modifier
+                    .size(20.toDp(), 10.toDp())
+                    .semantics(mergeDescendants = false) {
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            { scrollValue },
+                            { scrollMaxValue }
+                        )
+                    }
+            ) {
+                Text("foo", Modifier.size(10.toDp()))
+                Text("bar",
+                    Modifier
+                        .size(10.toDp())
+                        .testTag(tag))
+            }
+        }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+        val virtualViewId = rule.onNodeWithTag(tag).semanticsId
+        rule.runOnIdle { dispatchedAccessibilityEvents.clear() }
+
+        // Act.
+        try {
+            androidComposeView.snapshotObserver.startObserving()
+            rule.runOnIdle {
+                androidComposeView.accessibilityNodeProvider
+                    .performAction(virtualViewId, ACTION_ACCESSIBILITY_FOCUS, null)
+                Snapshot.notifyObjectsInitialized()
+                scrollValue = 2f
+                Snapshot.sendApplyNotifications()
+            }
+        } finally {
+            androidComposeView.snapshotObserver.stopObserving()
+        }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            val focusedANI = androidComposeView.accessibilityNodeProvider
+                .findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY)
+            assertThat(Rect().also { focusedANI?.getBoundsInScreen(it) })
+                .isEqualTo(Rect(10, 0, 20, 10))
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_VIEW_ACCESSIBILITY_FOCUSED
+                    },
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_SUBTREE
+                    },
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_VIEW_SCROLLED
+                        scrollX = 2
+                        maxScrollX = 100
+                    },
+                )
+        }
+    }
+
+    @Test
+    fun sendScrollEvent_byStateObservation_vertical() {
+        // Arrange.
+        var scrollValue by mutableStateOf(0f, structuralEqualityPolicy())
+        val scrollMaxValue = 100f
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        verticalScrollAxisRange = ScrollAxisRange(
+                            { scrollValue },
+                            { scrollMaxValue }
+                        )
+                    }
+            )
+        }
+
+        // TODO(b/272068594): We receive an extra TYPE_WINDOW_CONTENT_CHANGED event 100ms after
+        //  setup. So we wait an extra 100ms here so that this test is not affected by that extra
+        //  event.
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+        dispatchedAccessibilityEvents.clear()
+
+        // Act.
+        try {
+            androidComposeView.snapshotObserver.startObserving()
+            rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+            rule.runOnIdle {
+                Snapshot.notifyObjectsInitialized()
+                scrollValue = 2f
+                Snapshot.sendApplyNotifications()
+            }
+        } finally {
+            androidComposeView.snapshotObserver.stopObserving()
+        }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_SUBTREE
+                    },
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_VIEW_SCROLLED
+                        scrollY = 2
+                        maxScrollY = 100
+                    },
+                )
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenPositionInvalid() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.dp)
+                    .semantics(mergeDescendants = true) {
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 0f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(-1)).isFalse()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsTrue_whenHorizontalScrollableNotAtLimit() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 0.5f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            // Should be scrollable in both directions.
+            assertThat(androidComposeView.canScrollHorizontally(1)).isTrue()
+            assertThat(androidComposeView.canScrollHorizontally(0)).isTrue()
+            assertThat(androidComposeView.canScrollHorizontally(-1)).isTrue()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsTrue_whenVerticalScrollableNotAtLimit() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        verticalScrollAxisRange = ScrollAxisRange(
+                            value = { 0.5f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            // Should be scrollable in both directions.
+            assertThat(androidComposeView.canScrollVertically(1)).isTrue()
+            assertThat(androidComposeView.canScrollVertically(0)).isTrue()
+            assertThat(androidComposeView.canScrollVertically(-1)).isTrue()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenHorizontalScrollable_whenScrolledRightAndAtLimit() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 1f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(-1)).isTrue()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenHorizontalScrollable_whenScrolledLeftAndAtLimit() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 0f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollHorizontally(1)).isTrue()
+            assertThat(androidComposeView.canScrollHorizontally(0)).isTrue()
+            assertThat(androidComposeView.canScrollHorizontally(-1)).isFalse()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenVerticalScrollable_whenScrolledDownAndAtLimit() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        verticalScrollAxisRange = ScrollAxisRange(
+                            value = { 1f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollVertically(1)).isFalse()
+            assertThat(androidComposeView.canScrollVertically(0)).isFalse()
+            assertThat(androidComposeView.canScrollVertically(-1)).isTrue()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenVerticalScrollable_whenScrolledUpAndAtLimit() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        verticalScrollAxisRange = ScrollAxisRange(
+                            value = { 0f },
+                            maxValue = { 1f },
+                            reverseScrolling = false
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollVertically(1)).isTrue()
+            assertThat(androidComposeView.canScrollVertically(0)).isTrue()
+            assertThat(androidComposeView.canScrollVertically(-1)).isFalse()
+        }
+    }
+
+    @Test
+    fun canScroll_respectsReverseDirection() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 0f },
+                            maxValue = { 1f },
+                            reverseScrolling = true
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(-1)).isTrue()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_forVertical_whenScrollableIsHorizontal() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(100.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 0.5f },
+                            maxValue = { 1f },
+                            reverseScrolling = true
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(50f, 50f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollVertically(1)).isFalse()
+            assertThat(androidComposeView.canScrollVertically(0)).isFalse()
+            assertThat(androidComposeView.canScrollVertically(-1)).isFalse()
+        }
+    }
+
+    @Test
+    fun canScroll_returnsFalse_whenTouchIsOutsideBounds() {
+        // Arrange.
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(50.toDp())
+                    .semantics(mergeDescendants = true) {
+                        testTag = tag
+                        horizontalScrollAxisRange = ScrollAxisRange(
+                            value = { 0.5f },
+                            maxValue = { 1f },
+                            reverseScrolling = true
+                        )
+                    }
+            )
+        }
+
+        // Act.
+        rule.onNodeWithTag(tag).performTouchInput { down(Offset(100f, 100f)) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(androidComposeView.canScrollHorizontally(1)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(0)).isFalse()
+            assertThat(androidComposeView.canScrollHorizontally(-1)).isFalse()
+        }
+    }
+
+    private fun Int.toDp(): Dp = with(rule.density) { [email protected]() }
+
+    private fun ComposeContentTestRule.setContentWithAccessibilityEnabled(
+        content: @Composable () -> Unit
+    ) {
+        setContent {
+            androidComposeView = LocalView.current as AndroidComposeView
+            with(androidComposeView.composeAccessibilityDelegate) {
+                accessibilityForceEnabledForTesting = true
+                onSendAccessibilityEvent = { dispatchedAccessibilityEvents += it; false }
+            }
+            content()
+        }
+
+        // Advance the clock past the first accessibility event loop, and clear the initial
+        // events as we are want the assertions to check the events that were generated later.
+        runOnIdle { mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs) }
+        runOnIdle { dispatchedAccessibilityEvents.clear() }
+    }
+
+    companion object {
+
+        internal val AccessibilityEventComparator = Correspondence
+            .from<AccessibilityEvent, AccessibilityEvent>(
+                { actual, expected ->
+                    actual != null && expected != null &&
+                        actual.eventType == expected.eventType &&
+                        actual.eventTime == expected.eventTime &&
+                        actual.packageName == expected.packageName &&
+                        actual.movementGranularity == expected.movementGranularity &&
+                        actual.action == expected.action &&
+                        actual.contentChangeTypes == expected.contentChangeTypes &&
+                        (SDK_INT < P || actual.windowChanges == expected.windowChanges) &&
+                        actual.className.contentEquals(expected.className) &&
+                        actual.text.toString() == expected.text.toString() &&
+                        actual.contentDescription.contentEquals(expected.contentDescription) &&
+                        actual.itemCount == expected.itemCount &&
+                        actual.currentItemIndex == expected.currentItemIndex &&
+                        actual.isEnabled == expected.isEnabled &&
+                        actual.isPassword == expected.isPassword &&
+                        actual.isChecked == expected.isChecked &&
+                        actual.isFullScreen == expected.isFullScreen &&
+                        actual.isScrollable == expected.isScrollable &&
+                        actual.beforeText.contentEquals(expected.beforeText) &&
+                        actual.fromIndex == expected.fromIndex &&
+                        actual.toIndex == expected.toIndex &&
+                        actual.scrollX == expected.scrollX &&
+                        actual.scrollY == expected.scrollY &&
+                        actual.maxScrollX == expected.maxScrollX &&
+                        actual.maxScrollY == expected.maxScrollY &&
+                        (SDK_INT < P || actual.scrollDeltaX == expected.scrollDeltaX) &&
+                        (SDK_INT < P || actual.scrollDeltaY == expected.scrollDeltaY) &&
+                        actual.addedCount == expected.addedCount &&
+                        actual.removedCount == expected.removedCount &&
+                        actual.parcelableData == expected.parcelableData &&
+                        actual.recordCount == expected.recordCount
+                },
+                "has same properties as"
+            )
+    }
+
+    private val View.composeAccessibilityDelegate: AndroidComposeViewAccessibilityDelegateCompat
+        get() = ViewCompat.getAccessibilityDelegate(this)
+            as AndroidComposeViewAccessibilityDelegateCompat
+
+    // TODO(b/272068594): Add api to fetch the semantics id from SemanticsNodeInteraction directly.
+    private val SemanticsNodeInteraction.semanticsId: Int get() = fetchSemanticsNode().id
+
+    // TODO(b/304359126): Move this to AccessibilityEventCompat and use it wherever we use obtain().
+    private fun AccessibilityEvent(): AccessibilityEvent = if (SDK_INT >= R) {
+        android.view.accessibility.AccessibilityEvent()
+    } else {
+        @Suppress("DEPRECATION")
+        AccessibilityEvent.obtain()
+    }.apply {
+        packageName = "androidx.compose.ui.test"
+        className = "android.view.View"
+        isEnabled = true
+    }
+}
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/accessibility/WindowContentChangeTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/accessibility/WindowContentChangeTest.kt
new file mode 100644
index 0000000..b8f22d5
--- /dev/null
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/accessibility/WindowContentChangeTest.kt
@@ -0,0 +1,366 @@
+
+/*
+ * 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.
+ */
+
+package androidx.compose.ui.accessibility
+
+import android.os.Build.VERSION.SDK_INT
+import android.os.Build.VERSION_CODES.P
+import android.os.Build.VERSION_CODES.R
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED
+import android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.AndroidComposeView
+import androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.semantics.CustomAccessibilityAction
+import androidx.compose.ui.semantics.customActions
+import androidx.compose.ui.semantics.disabled
+import androidx.compose.ui.semantics.onClick
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.TestActivity
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.unit.dp
+import androidx.core.view.ViewCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Correspondence
+import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class WindowContentChangeTest {
+    @get:Rule
+    val rule = createAndroidComposeRule<TestActivity>()
+
+    private lateinit var androidComposeView: AndroidComposeView
+    private val dispatchedAccessibilityEvents = mutableListOf<AccessibilityEvent>()
+    private val accessibilityEventLoopIntervalMs = 100L
+
+    @Test
+    fun sendWindowContentChangeUndefinedEventByDefault_whenPropertyAdded() {
+        // Arrange.
+        var addProperty by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        if (addProperty) disabled()
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { addProperty = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
+                    }
+                )
+        }
+    }
+
+    @Test
+    fun sendWindowContentChangeUndefinedEventByDefault_whenPropertyRemoved() {
+        // Arrange.
+        var removeProperty by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        if (!removeProperty) disabled()
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { removeProperty = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
+                    }
+                )
+        }
+    }
+
+    @Test
+    @Ignore("b/307823561")
+    fun sendWindowContentChangeUndefinedEventByDefault_onlyOnce_whenMultiplePropertiesChange() {
+        // Arrange.
+        var propertiesChanged by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        if (!propertiesChanged) {
+                            disabled()
+                        } else {
+                            onClick { true }
+                        }
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { propertiesChanged = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
+                    }
+                )
+        }
+    }
+
+    @Test
+    fun sendWindowContentChangeUndefinedEventByDefault_standardActionWithTheSameLabel() {
+        // Arrange.
+        var newAction by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        if (!newAction) {
+                            onClick(label = "action") { true }
+                        } else {
+                            onClick(label = "action") { true }
+                        }
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { newAction = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle { assertThat(dispatchedAccessibilityEvents).isEmpty() }
+    }
+
+    @Test
+    fun sendWindowContentChangeUndefinedEventByDefault_standardActionWithDifferentLabels() {
+        // Arrange.
+        var newAction by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        if (!newAction) {
+                            onClick(label = "action1") { true }
+                        } else {
+                            onClick(label = "action2") { true }
+                        }
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { newAction = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
+                    }
+                )
+        }
+    }
+
+    @Test
+    fun sendWindowContentChangeUndefinedEventByDefault_customActionWithTheSameLabel() {
+        // Arrange.
+        var newAction by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        customActions = if (!newAction) {
+                            listOf(CustomAccessibilityAction("action") { true })
+                        } else {
+                            listOf(CustomAccessibilityAction("action") { false })
+                        }
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { newAction = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle { assertThat(dispatchedAccessibilityEvents).isEmpty() }
+    }
+
+    @Test
+    fun sendWindowContentChangeUndefinedEventByDefault_customActionWithDifferentLabels() {
+        // Arrange.
+        var newAction by mutableStateOf(false)
+        rule.mainClock.autoAdvance = false
+        rule.setContentWithAccessibilityEnabled {
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .semantics(mergeDescendants = false) {
+                        customActions = if (!newAction) {
+                            listOf(CustomAccessibilityAction("action1") { true })
+                        } else {
+                            listOf(CustomAccessibilityAction("action2") { true })
+                        }
+                    }
+            )
+        }
+
+        // Act.
+        rule.runOnIdle { newAction = true }
+        rule.mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs)
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(dispatchedAccessibilityEvents)
+                .comparingElementsUsing(AccessibilityEventComparator)
+                .containsExactly(
+                    AccessibilityEvent().apply {
+                        eventType = TYPE_WINDOW_CONTENT_CHANGED
+                        contentChangeTypes = CONTENT_CHANGE_TYPE_UNDEFINED
+                    }
+                )
+        }
+    }
+
+    private fun ComposeContentTestRule.setContentWithAccessibilityEnabled(
+        content: @Composable () -> Unit
+    ) {
+        setContent {
+            androidComposeView = LocalView.current as AndroidComposeView
+            with(androidComposeView.composeAccessibilityDelegate) {
+                accessibilityForceEnabledForTesting = true
+                onSendAccessibilityEvent = { dispatchedAccessibilityEvents += it; false }
+            }
+            content()
+        }
+
+        // Advance the clock past the first accessibility event loop, and clear the initial
+        // events as we are want the assertions to check the events that were generated later.
+        runOnIdle { mainClock.advanceTimeBy(accessibilityEventLoopIntervalMs) }
+        runOnIdle { dispatchedAccessibilityEvents.clear() }
+    }
+
+    companion object {
+        internal val AccessibilityEventComparator = Correspondence
+            .from<AccessibilityEvent, AccessibilityEvent>(
+                { actual, expected ->
+                    actual != null && expected != null &&
+                        actual.eventType == expected.eventType &&
+                        actual.eventTime == expected.eventTime &&
+                        actual.packageName == expected.packageName &&
+                        actual.movementGranularity == expected.movementGranularity &&
+                        actual.action == expected.action &&
+                        actual.contentChangeTypes == expected.contentChangeTypes &&
+                        (SDK_INT < P || actual.windowChanges == expected.windowChanges) &&
+                        actual.className.contentEquals(expected.className) &&
+                        actual.text.toString() == expected.text.toString() &&
+                        actual.contentDescription.contentEquals(expected.contentDescription) &&
+                        actual.itemCount == expected.itemCount &&
+                        actual.currentItemIndex == expected.currentItemIndex &&
+                        actual.isEnabled == expected.isEnabled &&
+                        actual.isPassword == expected.isPassword &&
+                        actual.isChecked == expected.isChecked &&
+                        actual.isFullScreen == expected.isFullScreen &&
+                        actual.isScrollable == expected.isScrollable &&
+                        actual.beforeText.contentEquals(expected.beforeText) &&
+                        actual.fromIndex == expected.fromIndex &&
+                        actual.toIndex == expected.toIndex &&
+                        actual.scrollX == expected.scrollX &&
+                        actual.scrollY == expected.scrollY &&
+                        actual.maxScrollX == expected.maxScrollX &&
+                        actual.maxScrollY == expected.maxScrollY &&
+                        (SDK_INT < P || actual.scrollDeltaX == expected.scrollDeltaX) &&
+                        (SDK_INT < P || actual.scrollDeltaY == expected.scrollDeltaY) &&
+                        actual.addedCount == expected.addedCount &&
+                        actual.removedCount == expected.removedCount &&
+                        actual.parcelableData == expected.parcelableData &&
+                        actual.recordCount == expected.recordCount
+                },
+                "has same properties as"
+            )
+    }
+
+    private val View.composeAccessibilityDelegate: AndroidComposeViewAccessibilityDelegateCompat
+        get() = ViewCompat.getAccessibilityDelegate(this)
+            as AndroidComposeViewAccessibilityDelegateCompat
+
+    // TODO(b/304359126): Move this to AccessibilityEventCompat and use it wherever we use obtain().
+    private fun AccessibilityEvent(): AccessibilityEvent = if (SDK_INT >= R) {
+        android.view.accessibility.AccessibilityEvent()
+    } else {
+        @Suppress("DEPRECATION")
+        AccessibilityEvent.obtain()
+    }.apply {
+        packageName = "androidx.compose.ui.test"
+        className = "android.view.View"
+        isEnabled = true
+    }
+}
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/ClearFocusExitTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/ClearFocusExitTest.kt
index ae6436a..331bb2a 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/ClearFocusExitTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/ClearFocusExitTest.kt
@@ -37,13 +37,13 @@
     @get:Rule
     val rule = createComposeRule()
 
-    val focusRequester = FocusRequester()
-    var clearTriggered = false
-    lateinit var focusState: FocusState
-    lateinit var focusManager: FocusManager
+    private val focusRequester = FocusRequester()
+    private var clearTriggered = false
+    private lateinit var focusState: FocusState
+    private lateinit var focusManager: FocusManager
 
     @Test
-    fun clearFocus_doesNotTriggersExit() {
+    fun clearFocus_doesNotTriggerExit() {
         // Arrange.
         rule.setFocusableContent {
             focusManager = LocalFocusManager.current
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusEventCountTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusEventCountTest.kt
index ef2b7a4..000ce26 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusEventCountTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusEventCountTest.kt
@@ -36,7 +36,7 @@
 
 @MediumTest
 @RunWith(Parameterized::class)
-class FocusEventCountTest(focusEventType: String) {
+class FocusEventCountTest(val focusEventType: String) {
     private val onFocusEvent = if (focusEventType == UseOnFocusEvent) {
         OnFocusEventCall
     } else {
@@ -310,10 +310,16 @@
 
         // Assert.
         rule.runOnIdle {
-            assertThat(focusStates).isExactly(
-                Inactive, // triggered by clearFocus() of the active node.
-                Inactive, // triggered by onFocusEvent node's attach().
-            )
+            if (focusEventType == UseOnFocusEvent) {
+                assertThat(focusStates).isExactly(
+                    Inactive
+                )
+            } else {
+                assertThat(focusStates).isExactly(
+                    Inactive, // triggered by clearFocus() of the active node.
+                    Inactive, // triggered by onFocusEvent node's attach().
+                )
+            }
         }
     }
 
@@ -335,7 +341,11 @@
         rule.runOnIdle { addFocusTarget = false }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        if (focusEventType == UseOnFocusEvent) {
+            rule.runOnIdle { assertThat(focusStates).isEmpty() }
+        } else {
+            rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        }
     }
 
     @Test
@@ -362,7 +372,11 @@
         rule.runOnIdle { addFocusTarget = false }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Active) }
+        if (focusEventType == UseOnFocusEvent) {
+            rule.runOnIdle { assertThat(focusStates).isEmpty() }
+        } else {
+            rule.runOnIdle { assertThat(focusStates).isExactly(Active) }
+        }
     }
 
     @Test
@@ -391,7 +405,11 @@
         rule.runOnIdle { addFocusTarget = false }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Active) }
+        if (focusEventType == UseOnFocusEvent) {
+            rule.runOnIdle { assertThat(focusStates).isEmpty() }
+        } else {
+            rule.runOnIdle { assertThat(focusStates).isExactly(Active) }
+        }
     }
 
     @Test
@@ -412,7 +430,13 @@
         rule.runOnIdle { addFocusTarget = true }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        rule.runOnIdle {
+            if (focusEventType == UseOnFocusEvent) {
+                assertThat(focusStates).isEmpty()
+            } else {
+                assertThat(focusStates).isExactly(Inactive)
+            }
+        }
     }
 
     @Test
@@ -434,7 +458,13 @@
         rule.runOnIdle { addFocusProperties = true }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        rule.runOnIdle {
+            if (focusEventType == UseOnFocusEvent) {
+                assertThat(focusStates).isEmpty() // The new focus event isn't triggered on empty
+            } else {
+                assertThat(focusStates).isExactly(Inactive)
+            }
+        }
     }
 
     @Test
@@ -462,7 +492,13 @@
         rule.runOnIdle { addFocusProperties = true }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        rule.runOnIdle {
+            if (focusEventType == UseOnFocusEvent) {
+                assertThat(focusStates).isEmpty()
+            } else {
+                assertThat(focusStates).isExactly(Inactive)
+            }
+        }
     }
 
     @Test
@@ -484,7 +520,13 @@
         rule.runOnIdle { add = true }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        rule.runOnIdle {
+            if (focusEventType == UseOnFocusEvent) {
+                assertThat(focusStates).isEmpty()
+            } else {
+                assertThat(focusStates).isExactly(Inactive)
+            }
+        }
     }
 
     @Test
@@ -492,10 +534,11 @@
         // Arrange.
         val focusStates = mutableListOf<FocusState>()
         var remove by mutableStateOf(false)
+        val lambda: (FocusState) -> Unit = { focusStates.add(it) }
         rule.setFocusableContent {
             Box(
                 modifier = Modifier
-                    .onFocusEvent { focusStates.add(it) }
+                    .onFocusEvent(lambda)
                     .then(if (remove) Modifier else Modifier.focusProperties { canFocus = true })
                     .focusTarget()
             )
@@ -506,18 +549,27 @@
         rule.runOnIdle { remove = true }
 
         // Assert.
-        rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+        rule.runOnIdle {
+            if (focusEventType == UseOnFocusEvent) {
+                assertThat(focusStates).isEmpty()
+            } else {
+                assertThat(focusStates).isExactly(Inactive)
+            }
+        }
     }
 
+    // TODO: b/296477841
     @Test
     fun removingCantFocusProperty_onFocusEventIsTriggered() {
         // Arrange.
         val focusStates = mutableListOf<FocusState>()
         var remove by mutableStateOf(false)
+        val focusEventHandler: (FocusState) -> Unit = { focusStates.add(it) }
+
         rule.setFocusableContent {
             Box(
                 modifier = Modifier
-                    .onFocusEvent { focusStates.add(it) }
+                    .onFocusEvent(focusEventHandler)
                     .then(if (remove) Modifier else Modifier.focusProperties { canFocus = false })
                     .focusTarget()
             )
@@ -528,7 +580,13 @@
         rule.runOnIdle { remove = true }
 
         // Assert.
-         rule.runOnIdle { assertThat(focusStates).isExactly(Inactive) }
+         rule.runOnIdle {
+             if (focusEventType == UseOnFocusEvent) {
+                 assertThat(focusStates).isEmpty()
+             } else {
+                 assertThat(focusStates).isExactly(Inactive)
+             }
+         }
     }
 
     @Test
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt
index 48f89f2..2799818 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt
@@ -18,17 +18,22 @@
 
 import android.view.View
 import androidx.compose.foundation.layout.Box
+import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusStateImpl.Active
 import androidx.compose.ui.focus.FocusStateImpl.ActiveParent
 import androidx.compose.ui.focus.FocusStateImpl.Inactive
+import androidx.compose.ui.input.InputMode.Companion.Keyboard
+import androidx.compose.ui.input.InputMode.Companion.Touch
+import androidx.compose.ui.input.InputModeManager
 import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.LocalInputModeManager
 import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -39,24 +44,25 @@
     @get:Rule
     val rule = createComposeRule()
 
+    private lateinit var focusManager: FocusManager
+    private lateinit var inputModeManager: InputModeManager
+    private val focusStates = mutableListOf<FocusState>()
+
     @Test
-    fun clearFocus_singleLayout() {
+    fun clearFocus_singleLayout_focusIsRestoredAfterClear() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent(extraItemForInitialFocus = false) {
             Box(
                 modifier = Modifier
                     .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
         rule.runOnIdle {
             focusRequester.requestFocus()
-            assertThat(focusState.isFocused).isTrue()
+            focusStates.clear()
         }
 
         // Act.
@@ -64,8 +70,16 @@
 
         // Assert.
         rule.runOnIdle {
-            assertThat(focusManager.rootFocusState.isFocused).isTrue()
-            assertThat(focusState.isFocused).isFalse()
+            when (inputModeManager.inputMode) {
+                Keyboard -> {
+                    assertThat(focusStates).containsExactly(Inactive, Active).inOrder()
+                    assertThat(focusManager.rootFocusState.hasFocus).isTrue()
+                }
+                Touch -> {
+                    assertThat(focusStates).containsExactly(Inactive).inOrder()
+                    assertThat(focusManager.rootFocusState.hasFocus).isFalse()
+                }
+            }
         }
     }
 
@@ -77,7 +91,7 @@
         lateinit var parentFocusState: FocusState
         lateinit var grandparentFocusState: FocusState
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
+        rule.setTestContent {
             focusManager = LocalFocusManager.current
             Box(
                 modifier = Modifier
@@ -119,96 +133,38 @@
     @Test
     fun takeFocus_whenRootIsInactive() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         lateinit var view: View
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent(extraItemForInitialFocus = false) {
             view = LocalView.current
             Box(
                 modifier = Modifier
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
 
         // Act.
-        rule.runOnIdle { view.requestFocus() }
-
-        // Assert.
         rule.runOnIdle {
-            assertThat(focusManager.rootFocusState).isEqualTo(Active)
-            assertThat(focusState.isFocused).isFalse()
+            focusStates.clear()
+            view.requestFocus()
         }
-    }
-
-    fun takeFocus_whenRootIsActive() {
-        // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
-        lateinit var view: View
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
-            view = LocalView.current
-            Box(
-                modifier = Modifier
-                    .onFocusChanged { focusState = it }
-                    .focusTarget()
-            )
-        }
-        rule.runOnIdle { focusManager.setRootFocusState(Active) }
-
-        // Act.
-        rule.runOnIdle { view.requestFocus() }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(focusManager.rootFocusState).isEqualTo(Active)
-            assertThat(focusState.isFocused).isFalse()
-        }
-    }
-
-    @Test
-    fun takeFocus_whenRootIsActiveParent() {
-        // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
-        lateinit var view: View
-        val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
-            view = LocalView.current
-            Box(
-                modifier = Modifier
-                    .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
-                    .focusTarget()
-            )
-        }
-        rule.runOnIdle { focusRequester.requestFocus() }
-
-        // Act.
-        rule.runOnIdle { view.requestFocus() }
 
         // Assert.
         rule.runOnIdle {
             assertThat(focusManager.rootFocusState).isEqualTo(ActiveParent)
-            assertThat(focusState.isFocused).isTrue()
+            assertThat(focusStates).containsExactly(Active)
         }
     }
 
     @Test
     fun releaseFocus_whenRootIsInactive() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         lateinit var view: View
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent(extraItemForInitialFocus = false) {
             view = LocalView.current
             Box(
                 modifier = Modifier
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
@@ -219,55 +175,28 @@
         // Assert.
         rule.runOnIdle {
             assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
-            assertThat(focusState.isFocused).isFalse()
+            assertThat(focusStates).containsExactly(Inactive)
         }
     }
 
-    fun releaseFocus_whenRootIsActive() {
-        // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
-        lateinit var view: View
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
-            view = LocalView.current
-            Box(
-                modifier = Modifier
-                    .onFocusChanged { focusState = it }
-                    .focusTarget()
-            )
-        }
-        rule.runOnIdle { focusManager.setRootFocusState(Active) }
-
-        // Act.
-        rule.runOnIdle { view.clearFocus() }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
-            assertThat(focusState.isFocused).isFalse()
-        }
-    }
-
-    @Ignore("b/257499180")
     @Test
-    fun releaseFocus_whenRootIsActiveParent() {
+    fun releaseFocus_whenOwnerFocusIsCleared() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         lateinit var view: View
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent(extraItemForInitialFocus = false) {
             view = LocalView.current
             Box(
                 modifier = Modifier
                     .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
-        rule.runOnIdle { focusRequester.requestFocus() }
+        rule.runOnIdle {
+            focusRequester.requestFocus()
+            focusStates.clear()
+        }
 
         // Act.
         rule.runOnIdle {
@@ -276,111 +205,107 @@
 
         // Assert.
         rule.runOnIdle {
-            assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
-            assertThat(focusState.isFocused).isFalse()
+            when (inputModeManager.inputMode) {
+                Keyboard -> {
+                    // Focus is re-assigned to the initially focused item (default focus).
+                    assertThat(focusManager.rootFocusState).isEqualTo(ActiveParent)
+                    assertThat(focusStates).containsExactly(Inactive, Active).inOrder()
+                }
+                Touch -> {
+                    assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
+                    assertThat(focusStates).containsExactly(Inactive)
+                }
+                else -> error("Invalid input mode")
+            }
         }
     }
 
     @Test
     fun clearFocus_whenRootIsInactive() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent {
             Box(
                 modifier = Modifier
                     .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
+        rule.runOnIdle { focusStates.clear() }
 
         // Act.
         rule.runOnIdle { focusManager.clearFocus() }
 
         // Assert.
         rule.runOnIdle {
-            assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
-            assertThat(focusState.isFocused).isFalse()
-        }
-    }
-
-    @Ignore("b/257499180")
-    @Test
-    fun clearFocus_whenRootIsActive() {
-        // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
-        val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
-            Box(
-                modifier = Modifier
-                    .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
-                    .focusTarget()
-            )
-        }
-        rule.runOnIdle { focusManager.setRootFocusState(Active) }
-
-        // Act.
-        rule.runOnIdle { focusManager.clearFocus() }
-
-        // Assert.
-        rule.runOnIdle {
-            assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
-            assertThat(focusState.isFocused).isFalse()
+            when (inputModeManager.inputMode) {
+                Keyboard -> {
+                    assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
+                    assertThat(focusStates).isEmpty()
+                }
+                Touch -> {
+                    assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
+                    assertThat(focusStates).isEmpty()
+                }
+                else -> error("Invalid input mode")
+            }
         }
     }
 
     @Test
     fun clearFocus_whenRootIsActiveParent() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent(extraItemForInitialFocus = false) {
             Box(
                 modifier = Modifier
                     .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
-        rule.runOnIdle { focusRequester.requestFocus() }
+        rule.runOnIdle {
+            focusRequester.requestFocus()
+            focusStates.clear()
+        }
 
         // Act.
         rule.runOnIdle { focusManager.clearFocus() }
 
         // Assert.
         rule.runOnIdle {
-            // TODO(b/257499180): Compose should not hold focus state when clear focus is requested.
-            assertThat(focusManager.rootFocusState).isEqualTo(Active)
-            assertThat(focusState.isFocused).isFalse()
+            when (inputModeManager.inputMode) {
+                Keyboard -> {
+                    assertThat(focusManager.rootFocusState).isEqualTo(ActiveParent)
+                    assertThat(focusStates).containsExactly(Inactive, Active).inOrder()
+                }
+                Touch -> {
+                    assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
+                    assertThat(focusStates).containsExactly(Inactive)
+                }
+                else -> error("Invalid input mode")
+            }
         }
     }
 
     @Test
     fun clearFocus_whenHierarchyHasCapturedFocus() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
+        rule.setTestContent {
             focusManager = LocalFocusManager.current
             Box(
                 modifier = Modifier
                     .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
         rule.runOnIdle {
             focusRequester.requestFocus()
             focusRequester.captureFocus()
+            focusStates.clear()
         }
 
         // Act.
@@ -389,28 +314,27 @@
         // Assert.
         rule.runOnIdle {
             assertThat(focusManager.rootFocusState).isEqualTo(ActiveParent)
-            assertThat(focusState.isFocused).isTrue()
+            assertThat(focusStates).isEmpty()
         }
     }
 
     @Test
     fun clearFocus_forced_whenHierarchyHasCapturedFocus() {
         // Arrange.
-        lateinit var focusManager: FocusManager
-        lateinit var focusState: FocusState
         val focusRequester = FocusRequester()
-        rule.setFocusableContent {
-            focusManager = LocalFocusManager.current
+        rule.setTestContent(extraItemForInitialFocus = false) {
+
             Box(
                 modifier = Modifier
                     .focusRequester(focusRequester)
-                    .onFocusChanged { focusState = it }
+                    .onFocusChanged { focusStates += it }
                     .focusTarget()
             )
         }
         rule.runOnIdle {
             focusRequester.requestFocus()
             focusRequester.captureFocus()
+            focusStates.clear()
         }
 
         // Act.
@@ -418,16 +342,32 @@
 
         // Assert.
         rule.runOnIdle {
-            // TODO(b/257499180): Compose should clear focus and send focus to the root view.
-            assertThat(focusManager.rootFocusState).isEqualTo(Active)
-            assertThat(focusState.isFocused).isFalse()
+            when (inputModeManager.inputMode) {
+                Keyboard -> {
+                    // Focus is re-assigned to the initially focused item (default focus).
+                    assertThat(focusManager.rootFocusState).isEqualTo(ActiveParent)
+                    assertThat(focusStates).containsExactly(Inactive, Active).inOrder()
+                }
+                Touch -> {
+                    assertThat(focusManager.rootFocusState).isEqualTo(Inactive)
+                    assertThat(focusStates).containsExactly(Inactive).inOrder()
+                }
+                else -> error("Invalid input mode")
+            }
         }
     }
 
     private val FocusManager.rootFocusState: FocusState
         get() = (this as FocusOwnerImpl).rootFocusNode.focusState
 
-    private fun FocusManager.setRootFocusState(focusState: FocusStateImpl) {
-        (this as FocusOwnerImpl).rootFocusNode.focusState = focusState
+    private fun ComposeContentTestRule.setTestContent(
+        extraItemForInitialFocus: Boolean = true,
+        content: @Composable () -> Unit
+    ) {
+        setFocusableContent(extraItemForInitialFocus) {
+            focusManager = LocalFocusManager.current
+            inputModeManager = LocalInputModeManager.current
+            content()
+        }
     }
 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTestUtils.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTestUtils.kt
index 20fdc7a..f8be78e2 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTestUtils.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTestUtils.kt
@@ -17,6 +17,7 @@
 package androidx.compose.ui.focus
 
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.runtime.Composable
@@ -34,10 +35,25 @@
  * This function adds a parent composable which has size.
  * [View.requestFocus()][android.view.View.requestFocus] will not take focus if the view has no
  * size.
+ *
+ * @param extraItemForInitialFocus Includes an extra item that takes focus initially. This is
+ * useful in cases where we need tests that could be affected by initial focus. Eg. When there is
+ * only one focusable item and we clear focus, that item could end up being focused on again by the
+ * initial focus logic.
  */
-internal fun ComposeContentTestRule.setFocusableContent(content: @Composable () -> Unit) {
+internal fun ComposeContentTestRule.setFocusableContent(
+    extraItemForInitialFocus: Boolean = true,
+    content: @Composable () -> Unit
+) {
     setContent {
-        Box(modifier = Modifier.requiredSize(100.dp, 100.dp)) { content() }
+        if (extraItemForInitialFocus) {
+            Row {
+                Box(modifier = Modifier.requiredSize(10.dp, 10.dp).focusTarget())
+                Box(modifier = Modifier.requiredSize(100.dp, 100.dp)) { content() }
+            }
+        } else {
+            Box(modifier = Modifier.requiredSize(100.dp, 100.dp)) { content() }
+        }
     }
 }
 
@@ -66,9 +82,9 @@
             .focusProperties { canFocus = !deactivated }
             .focusTarget(),
         measurePolicy = remember(width, height) {
-            MeasurePolicy { measurables, constraint ->
+            MeasurePolicy { measurableList, constraint ->
                 layout(width, height) {
-                    measurables.forEach {
+                    measurableList.forEach {
                         val placeable = it.measure(constraint)
                         placeable.placeRelative(0, 0)
                     }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt
index b7caf2c..cdb0b7d 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt
@@ -23,9 +23,14 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester.Companion.Cancel
 import androidx.compose.ui.focus.FocusStateImpl.Active
+import androidx.compose.ui.focus.FocusStateImpl.ActiveParent
 import androidx.compose.ui.focus.FocusStateImpl.Inactive
+import androidx.compose.ui.input.InputMode.Companion.Keyboard
+import androidx.compose.ui.input.InputMode.Companion.Touch
+import androidx.compose.ui.input.InputModeManager
 import androidx.compose.ui.platform.AndroidComposeView
 import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.LocalInputModeManager
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.unit.dp
@@ -91,33 +96,57 @@
     fun cancelTakeFocus_fromOnFocusChanged() {
         // Arrange.
         lateinit var focusManager: FocusManager
+        lateinit var inputModeManager: InputModeManager
         lateinit var view: View
+        lateinit var focusState1: FocusState
+        lateinit var focusState2: FocusState
+        lateinit var focusState3: FocusState
         val box = FocusRequester()
 
         rule.setFocusableContent {
             focusManager = LocalFocusManager.current
+            inputModeManager = LocalInputModeManager.current
             view = LocalView.current
             Box(
                 Modifier
                     .size(10.dp)
                     .focusRequester(box)
-                    .onFocusChanged { if (it.isFocused) focusManager.clearFocus() }
+                    .onFocusChanged { focusState1 = it }
+                    .onFocusChanged {
+                        focusState2 = it
+                        if (it.isFocused) focusManager.clearFocus()
+                    }
+                    .onFocusChanged { focusState3 = it }
                     .focusTarget()
             )
         }
 
         // Act.
-        rule.runOnIdle {
+        rule.runOnUiThread {
             box.requestFocus()
         }
 
         // Assert.
         rule.runOnIdle {
+            assertThat(focusState1).isEqualTo(Inactive)
+            // TODO(b/312524818): When a focus transaction is cancelled, we should re-notify
+            //  all the focus event modifiers that were called in the previous transaction.
+            assertThat(focusState2).isEqualTo(Active) // Should be Inactive.
+            assertThat(focusState3).isEqualTo(Active) // Should be Inactive.
+
             val root = view as AndroidComposeView
-            val focusOwner = root.focusOwner as FocusOwnerImpl
-            assertThat(focusOwner.rootFocusNode.focusState).isEqualTo(Inactive)
-            // TODO(b/288096244): Find out why this is flaky.
-            //  assertThat(view.isFocused()).isFalse()
+
+            when (inputModeManager.inputMode) {
+                Keyboard -> {
+                    assertThat(root.focusOwner.rootState).isEqualTo(ActiveParent)
+                    assertThat(view.isFocused).isTrue()
+                }
+                Touch -> {
+                    assertThat(root.focusOwner.rootState).isEqualTo(Inactive)
+                    assertThat(view.isFocused).isFalse()
+                }
+                else -> error("invalid input mode")
+            }
         }
     }
 
@@ -152,14 +181,13 @@
         // Assert.
         rule.runOnIdle {
             val root = view as AndroidComposeView
-            val focusOwner = root.focusOwner as FocusOwnerImpl
-            assertThat(focusOwner.rootFocusNode.focusState).isEqualTo(Inactive)
+            assertThat(root.focusOwner.rootState).isEqualTo(Inactive)
             assertThat(view.isFocused).isFalse()
         }
     }
 
     @Test
-    fun rootFocusNodeIsActiveWhenViewIsFocused() {
+    fun rootFocusNodeHasFocusWhenViewIsFocused() {
         lateinit var view: View
         val focusRequester = FocusRequester()
         rule.setFocusableContent {
@@ -174,9 +202,8 @@
 
         // Assert.
         val root = view as AndroidComposeView
-        val focusOwner = root.focusOwner as FocusOwnerImpl
         rule.runOnIdle {
-            assertThat(focusOwner.rootFocusNode.focusState).isEqualTo(Active)
+            assertThat(root.focusOwner.rootState).isEqualTo(ActiveParent)
             assertThat(view.isFocused).isTrue()
         }
 
@@ -190,7 +217,7 @@
 
         // Assert.
         rule.runOnIdle {
-            assertThat(focusOwner.rootFocusNode.focusState).isEqualTo(Active)
+            assertThat(root.focusOwner.rootState.hasFocus).isEqualTo(true)
             assertThat(view.isFocused).isTrue()
         }
     }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusViewInteropTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusViewInteropTest.kt
index b2c2ef2..125adfd 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusViewInteropTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusViewInteropTest.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Rect as AndroidRect
 import android.view.View
+import androidx.compose.foundation.focusGroup
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.offset
@@ -25,6 +26,7 @@
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalView
@@ -101,6 +103,36 @@
         )
     }
 
+    @Test
+    fun requestFocus_returnsFalseWhenCancelled() {
+        // Arrange.
+        lateinit var view: View
+        rule.setContent {
+            view = LocalView.current
+            Box(
+                Modifier
+                    .size(10.dp)
+                    .focusProperties {
+                        @OptIn(ExperimentalComposeUiApi::class)
+                        enter = { FocusRequester.Cancel }
+                    }
+                    .focusGroup()
+            ) {
+                Box(
+                    Modifier
+                        .size(10.dp)
+                        .focusable()
+                )
+            }
+        }
+
+        // Act.
+        val success = rule.runOnIdle { view.requestFocus() }
+
+        // Assert.
+        rule.runOnIdle { assertThat(success).isFalse() }
+    }
+
     private fun View.getFocusedRect() = AndroidRect().run {
         rule.runOnIdle {
             getFocusedRect(this)
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchNextTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchNextTest.kt
index a622899..78c6445 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchNextTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchNextTest.kt
@@ -44,7 +44,7 @@
     @Test
     fun moveFocus_noFocusableItem() {
         // Arrange.
-        rule.setContentWithInitialRootFocus {}
+        rule.setContentForTest {}
 
         // Act.
         val movedFocusSuccessfully = rule.runOnIdle { focusManager.moveFocus(Next) }
@@ -57,7 +57,7 @@
     fun moveFocus_oneDisabledFocusableItem() {
         // Arrange.
         val isItemFocused = mutableStateOf(false)
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(isItemFocused, 0, 0, 10, 10, deactivated = true)
         }
 
@@ -72,7 +72,7 @@
     fun initialFocus_oneItem() {
         // Arrange.
         val isItemFocused = mutableStateOf(false)
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(isItemFocused, 0, 0, 10, 10)
         }
 
@@ -90,7 +90,7 @@
     fun initialFocus_skipsDeactivatedItem() {
         // Arrange.
         val (firstItem, secondItem) = List(2) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             Column {
                 FocusableBox(firstItem, 0, 0, 10, 10, deactivated = true)
                 FocusableBox(secondItem, 0, 0, 10, 10)
@@ -112,7 +112,7 @@
     fun initialFocus_firstItemInCompositionOrderGetsFocus() {
         // Arrange.
         val (firstItem, secondItem) = List(2) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(firstItem, 10, 10, 10, 10)
             FocusableBox(secondItem, 0, 0, 10, 10)
         }
@@ -131,7 +131,7 @@
     fun initialFocus_firstParentInCompositionOrderGetsFocus() {
         // Arrange.
         val (parent1, parent2, child1, child2) = List(4) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(parent1, 10, 10, 10, 10) {
                 FocusableBox(child1, 10, 10, 10, 10)
             }
@@ -154,7 +154,7 @@
     fun initialFocus_firstItemInCompositionOrderGetsFocus_evenIfAnotherNonParentIsPresent() {
         // Arrange.
         val (parent1, child1, item2) = List(3) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(parent1, 10, 10, 10, 10) {
                 FocusableBox(child1, 10, 10, 10, 10)
             }
@@ -175,7 +175,7 @@
     fun initialFocus_firstItemInCompositionOrderGetsFocus_evenIfThereIsAParentAtTheRoot() {
         // Arrange.
         val (parent1, child1, item1) = List(3) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(parent1, 10, 10, 10, 10) {
                 FocusableBox(child1, 10, 10, 10, 10)
@@ -196,7 +196,7 @@
     fun focusMovesToSecondItem() {
         // Arrange.
         val (item1, item2, item3) = List(3) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10, initialFocus)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 20, 0, 10, 10)
@@ -216,7 +216,7 @@
     fun focusMovesToThirdItem_skipsDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10, initialFocus)
             FocusableBox(item2, 10, 0, 10, 10, deactivated = true)
             FocusableBox(item3, 10, 0, 10, 10)
@@ -237,7 +237,7 @@
     fun focusMovesToThirdItem() {
         // Arrange.
         val (item1, item2, item3) = List(3) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10, initialFocus)
             FocusableBox(item3, 20, 0, 10, 10)
@@ -257,7 +257,7 @@
     fun focusMovesToFourthItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 0, 0, 10, 10, deactivated = true)
             FocusableBox(item3, 10, 0, 10, 10, initialFocus)
@@ -278,7 +278,7 @@
     fun focusWrapsAroundToFirstItem() {
         // Arrange.
         val (item1, item2, item3) = List(3) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 20, 0, 10, 10, initialFocus)
@@ -298,7 +298,7 @@
     fun focusWrapsAroundToFirstItem_skippingLastDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 20, 0, 10, 10, initialFocus)
@@ -319,7 +319,7 @@
     fun focusWrapsAroundToFirstItem_skippingFirstDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 10, 0, 10, 10, deactivated = true)
             FocusableBox(item2, 0, 0, 10, 10)
             FocusableBox(item3, 10, 0, 10, 10)
@@ -340,7 +340,7 @@
     fun focusMovesToChildOfDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, child) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10, initialFocus)
             FocusableBox(item2, 10, 0, 10, 10, deactivated = true) {
                 FocusableBox(child, 10, 0, 10, 10)
@@ -362,7 +362,7 @@
     fun focusMovesToGrandChildOfDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, child, grandchild) = List(5) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10, initialFocus)
             FocusableBox(item2, 10, 0, 10, 10, deactivated = true) {
                 FocusableBox(child, 10, 0, 10, 10, deactivated = true) {
@@ -386,7 +386,7 @@
     fun focusMovesToNextSiblingOfDeactivatedItem_evenThoughThereIsACloserNonSibling() {
         // Arrange.
         val (item1, item2, item3, child1, child2) = List(5) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10, deactivated = true) {
                 FocusableBox(child1, 10, 0, 10, 10, initialFocus)
@@ -409,7 +409,7 @@
     fun focusNextOrderAmongChildrenOfMultipleParents() {
         // Arrange.
         val focusState = List(12) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             Column {
                 Row {
                     FocusableBox(focusState[0], 0, 0, 10, 10, initialFocus)
@@ -446,7 +446,7 @@
     fun focusNextOrderAmongChildrenAtMultipleLevels() {
         // Arrange.
         val focusState = List(14) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             Column {
                 FocusableBox(focusState[0], 0, 0, 10, 10, initialFocus)
                 FocusableBox(focusState[1], 0, 10, 10, 10)
@@ -488,7 +488,7 @@
         val (parent3, child6) = List(2) { mutableStateOf(false) }
         val (parent4, child7, child8, child9, child10) = List(5) { mutableStateOf(false) }
         val (parent5, child11) = List(2) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(parent1, 0, 0, 10, 10) {
                 FocusableBox(child1, 0, 0, 10, 10)
                 FocusableBox(child2, 20, 0, 10, 10)
@@ -553,25 +553,16 @@
         rule.runOnIdle { assertThat(parent1.value).isTrue() }
     }
 
-    private fun ComposeContentTestRule.setContentForTest(composable: @Composable () -> Unit) {
-        setContent {
-            focusManager = LocalFocusManager.current
-            composable()
-        }
-        rule.runOnIdle { initialFocus.requestFocus() }
-    }
-
-    private fun ComposeContentTestRule.setContentWithInitialRootFocus(
+    private fun ComposeContentTestRule.setContentForTest(
+        initializeFocus: Boolean = false,
         composable: @Composable () -> Unit
     ) {
         setContent {
             focusManager = LocalFocusManager.current
             composable()
         }
-        rule.runOnIdle {
-            with(focusManager as FocusOwner) {
-                focusTransactionManager.withNewTransaction { takeFocus() }
-            }
+        if (initializeFocus) {
+            rule.runOnIdle { initialFocus.requestFocus() }
         }
     }
 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchPreviousTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchPreviousTest.kt
index 613421e..9d248a0 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchPreviousTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OneDimensionalFocusSearchPreviousTest.kt
@@ -44,7 +44,7 @@
     @Test
     fun moveFocus_noFocusableItem() {
         // Arrange.
-        rule.setContentWithInitialRootFocus {}
+        rule.setContentForTest {}
 
         // Act.
         val movedFocusSuccessfully = rule.runOnIdle { focusManager.moveFocus(Previous) }
@@ -57,7 +57,7 @@
     fun moveFocus_oneDisabledFocusableItem() {
         // Arrange.
         val isItemFocused = mutableStateOf(false)
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(isItemFocused, 0, 0, 10, 10, deactivated = true)
         }
 
@@ -72,7 +72,7 @@
     fun initialFocus_oneItem() {
         // Arrange.
         val isItemFocused = mutableStateOf(false)
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(isItemFocused, 0, 0, 10, 10)
         }
 
@@ -90,7 +90,7 @@
     fun initialFocus_skipsDeactivatedItem() {
         // Arrange.
         val (firstItem, secondItem) = List(2) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             Column {
                 FocusableBox(firstItem, 0, 0, 10, 10)
                 FocusableBox(secondItem, 0, 0, 10, 10, deactivated = true)
@@ -112,7 +112,7 @@
     fun initialFocus_lastItemInCompositionOrderGetsFocus() {
         // Arrange.
         val (firstItem, secondItem) = List(2) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(firstItem, 10, 10, 10, 10)
             FocusableBox(secondItem, 0, 0, 10, 10)
         }
@@ -131,7 +131,7 @@
     fun initialFocus_lastChildInCompositionOrderGetsFocus() {
         // Arrange.
         val (parent1, parent2, child1, child2) = List(4) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(parent1, 10, 10, 10, 10) {
                 FocusableBox(child1, 10, 10, 10, 10)
             }
@@ -154,7 +154,7 @@
     fun initialFocus_lastItemInCompositionOrderGetsFocus_evenIfAnotherNonParentIsPresent() {
         // Arrange.
         val (parent1, child1, item1) = List(3) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(parent1, 10, 10, 10, 10) {
                 FocusableBox(child1, 10, 10, 10, 10)
@@ -175,7 +175,7 @@
     fun initialFocus_lastItemInCompositionOrderGetsFocus_evenIfThereIsAParentAtTheRoot() {
         // Arrange.
         val (parent1, child1, item2) = List(3) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(parent1, 10, 10, 10, 10) {
                 FocusableBox(child1, 10, 10, 10, 10)
                 FocusableBox(item2, 0, 0, 10, 10)
@@ -196,7 +196,7 @@
     fun focusMovesToSecondItem() {
         // Arrange.
         val (item1, item2, item3) = List(3) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 20, 0, 10, 10, initialFocus)
@@ -216,7 +216,7 @@
     fun focusMovesToSecondItem_skipsDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 10, 0, 10, 10, deactivated = true)
@@ -237,7 +237,7 @@
     fun focusMovesToFirstItem() {
         // Arrange.
         val (item1, item2, item3) = List(3) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10, initialFocus)
             FocusableBox(item3, 20, 0, 10, 10)
@@ -257,7 +257,7 @@
     fun focusMovesToFirstItem_ignoresDeactivated() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10, initialFocus)
             FocusableBox(item3, 20, 0, 10, 10, deactivated = true)
@@ -278,7 +278,7 @@
     fun focusMovesToParent() {
         // Arrange.
         val (parent, child1, child2, child3) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(parent, 0, 0, 10, 10) {
                 FocusableBox(child1, 10, 0, 10, 10, initialFocus)
                 FocusableBox(child2, 20, 0, 10, 10)
@@ -300,7 +300,7 @@
     fun focusMovesToParent_ignoresDeactivated() {
         // Arrange.
         val (item, parent, child1, child2) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item, 0, 0, 10, 10)
             FocusableBox(parent, 0, 0, 10, 10, deactivated = true) {
                 FocusableBox(child1, 10, 0, 10, 10, initialFocus)
@@ -322,7 +322,7 @@
     fun focusMovesToParent_ignoresDeactivated_andWrapsAround() {
         // Arrange.
         val (parent, child1, child2, child3) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(parent, 0, 0, 10, 10, deactivated = true) {
                 FocusableBox(child1, 10, 0, 10, 10, initialFocus)
                 FocusableBox(child2, 20, 0, 10, 10)
@@ -344,7 +344,7 @@
     fun focusWrapsAroundToLastItem() {
         // Arrange.
         val (item1, item2, item3) = List(3) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10, initialFocus)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 20, 0, 10, 10)
@@ -364,7 +364,7 @@
     fun focusWrapsAroundToLastItem_skippingFirstDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 20, 0, 10, 10, deactivated = true)
             FocusableBox(item2, 0, 0, 10, 10, initialFocus)
             FocusableBox(item3, 10, 0, 10, 10)
@@ -385,7 +385,7 @@
     fun focusWrapsAroundToLastItem_skippingLastDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, item4) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10, initialFocus)
             FocusableBox(item2, 10, 0, 10, 10)
             FocusableBox(item3, 20, 0, 10, 10)
@@ -406,7 +406,7 @@
     fun focusMovesToChildOfDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, child) = List(4) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10, deactivated = true) {
                 FocusableBox(child, 10, 0, 10, 10)
@@ -428,7 +428,7 @@
     fun focusMovesToGrandChildOfDeactivatedItem() {
         // Arrange.
         val (item1, item2, item3, child, grandchild) = List(5) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 0, 0, 10, 10)
             FocusableBox(item2, 10, 0, 10, 10, deactivated = true) {
                 FocusableBox(child, 10, 0, 10, 10, deactivated = true) {
@@ -452,7 +452,7 @@
     fun focusMovesToNextSiblingOfDeactivatedItem_evenThoughThereIsACloserNonSibling() {
         // Arrange.
         val (item1, item2, item3, child1, child2) = List(5) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             FocusableBox(item1, 10, 0, 10, 10)
             FocusableBox(item2, 0, 0, 10, 10, deactivated = true) {
                 FocusableBox(child1, 0, 0, 10, 10)
@@ -475,7 +475,7 @@
     fun focusNextOrderAmongChildrenOfMultipleParents() {
         // Arrange.
         val focusState = List(12) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             Column {
                 Row {
                     FocusableBox(focusState[0], 0, 0, 10, 10)
@@ -511,7 +511,7 @@
     fun focusNextOrderAmongChildrenAtMultipleLevels() {
         // Arrange.
         val focusState = List(14) { mutableStateOf(false) }
-        rule.setContentForTest {
+        rule.setContentForTest(initializeFocus = true) {
             Column {
                 FocusableBox(focusState[0], 0, 0, 10, 10)
                 FocusableBox(focusState[1], 0, 10, 10, 10)
@@ -554,7 +554,7 @@
         val (parent4, child7, child8, child11, child12) = List(5) { mutableStateOf(false) }
         val (child9, child10) = List(2) { mutableStateOf(false) }
         val (parent5, child13) = List(2) { mutableStateOf(false) }
-        rule.setContentWithInitialRootFocus {
+        rule.setContentForTest {
             FocusableBox(parent1, 0, 0, 10, 10) {
                 FocusableBox(child1, 0, 0, 10, 10)
                 FocusableBox(child2, 20, 0, 10, 10)
@@ -624,25 +624,16 @@
         rule.runOnIdle { assertThat(child11.value).isTrue() }
     }
 
-    private fun ComposeContentTestRule.setContentForTest(composable: @Composable () -> Unit) {
-        setContent {
-            focusManager = LocalFocusManager.current
-            composable()
-        }
-        rule.runOnIdle { initialFocus.requestFocus() }
-    }
-
-    private fun ComposeContentTestRule.setContentWithInitialRootFocus(
+    private fun ComposeContentTestRule.setContentForTest(
+        initializeFocus: Boolean = false,
         composable: @Composable () -> Unit
     ) {
         setContent {
             focusManager = LocalFocusManager.current
             composable()
         }
-        rule.runOnIdle {
-            with(focusManager as FocusOwner) {
-                focusTransactionManager.withNewTransaction { takeFocus() }
-            }
+        if (initializeFocus) {
+            rule.runOnIdle { initialFocus.requestFocus() }
         }
     }
 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OwnerFocusTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OwnerFocusTest.kt
index bfeff0b..e3843b0 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OwnerFocusTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/OwnerFocusTest.kt
@@ -17,13 +17,18 @@
 package androidx.compose.ui.focus
 
 import android.view.View
+import android.view.View.FOCUS_DOWN
+import android.view.View.FOCUS_UP
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.size
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
+import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
@@ -63,19 +68,16 @@
         }
     }
 
-    @Ignore("Enable this test after the owner propagates focus to the hierarchy (b/152535715)")
     @Test
     fun whenOwnerGainsFocus_focusModifiersAreUpdated() {
         // Arrange.
         lateinit var ownerView: View
         lateinit var focusState: FocusState
-        val focusRequester = FocusRequester()
-        rule.setFocusableContent {
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
             ownerView = LocalView.current
             Box(
                 modifier = Modifier
                     .onFocusChanged { focusState = it }
-                    .focusRequester(focusRequester)
                     .focusTarget()
             )
         }
@@ -91,6 +93,106 @@
         }
     }
 
+    @Test
+    fun callingRequestFocusDownWhenOwnerAlreadyHasFocus() {
+        // Arrange.
+        lateinit var ownerView: View
+        lateinit var focusState1: FocusState
+        lateinit var focusState2: FocusState
+        lateinit var focusState3: FocusState
+        val focusRequester = FocusRequester()
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            ownerView = LocalView.current
+            Column {
+                Box(
+                    modifier = Modifier
+                        .size(10.dp)
+                        .onFocusChanged { focusState1 = it }
+                        .focusTarget()
+                )
+                Box(
+                    modifier = Modifier
+                        .size(10.dp)
+                        .focusRequester(focusRequester)
+                        .onFocusChanged { focusState2 = it }
+                        .focusTarget()
+                )
+                Box(
+                    modifier = Modifier
+                        .size(10.dp)
+                        .onFocusChanged { focusState3 = it }
+                        .focusTarget()
+                )
+            }
+        }
+        rule.runOnIdle {
+            focusRequester.requestFocus()
+        }
+
+        // Act.
+        val focusRequested = rule.runOnIdle {
+            ownerView.requestFocus(FOCUS_DOWN)
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(focusRequested).isTrue()
+            assertThat(focusState1.isFocused).isFalse()
+            assertThat(focusState2.isFocused).isTrue()
+            assertThat(focusState3.isFocused).isFalse()
+        }
+    }
+
+    @Test
+    fun callingRequestFocusUpWhenOwnerAlreadyHasFocus() {
+        // Arrange.
+        lateinit var ownerView: View
+        lateinit var focusState1: FocusState
+        lateinit var focusState2: FocusState
+        lateinit var focusState3: FocusState
+        val focusRequester = FocusRequester()
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            ownerView = LocalView.current
+            Column {
+                Box(
+                    modifier = Modifier
+                        .size(10.dp)
+                        .onFocusChanged { focusState1 = it }
+                        .focusTarget()
+                )
+                Box(
+                    modifier = Modifier
+                        .size(10.dp)
+                        .focusRequester(focusRequester)
+                        .onFocusChanged { focusState2 = it }
+                        .focusTarget()
+                )
+                Box(
+                    modifier = Modifier
+                        .size(10.dp)
+                        .onFocusChanged { focusState3 = it }
+                        .focusTarget()
+                )
+            }
+        }
+        rule.runOnIdle {
+            focusRequester.requestFocus()
+        }
+
+        // Act.
+        val focusRequested = rule.runOnIdle {
+            ownerView.requestFocus(FOCUS_UP)
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(focusRequested).isTrue()
+            assertThat(focusState1.isFocused).isFalse()
+            assertThat(focusState2.isFocused).isTrue()
+            assertThat(focusState3.isFocused).isFalse()
+        }
+    }
+
     @Ignore("Enable this test after the owner propagates focus to the hierarchy (b/152535715)")
     @Test
     fun whenWindowGainsFocus_focusModifiersAreUpdated() {
@@ -129,6 +231,7 @@
             ownerView = LocalView.current
             Box(
                 modifier = Modifier
+                    .size(10.dp)
                     .onFocusChanged { focusState = it }
                     .focusRequester(focusRequester)
                     .focusTarget()
@@ -180,6 +283,25 @@
     }
 
     @Test
+    fun viewDoesNotTakeFocus_whenThereAreNoFocusableItems() {
+        // Arrange.
+        lateinit var ownerView: View
+        rule.setFocusableContent(extraItemForInitialFocus = false) {
+            ownerView = LocalView.current
+            Box {}
+        }
+
+        // Act.
+        val success = rule.runOnIdle { ownerView.requestFocus() }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(success).isFalse()
+            assertThat(ownerView.isFocused).isFalse()
+        }
+    }
+
+    @Test
     fun clickingOnNonClickableSpaceInAppWhenViewIsFocused_doesNotChangeViewFocus() {
         // Arrange.
         val nonClickable = "notClickable"
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalImplicitEnterTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalImplicitEnterTest.kt
index cd43471..30f4e1a 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalImplicitEnterTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalImplicitEnterTest.kt
@@ -152,7 +152,7 @@
      *                   |________|
      */
     @Test
-    fun moveFocusEnter_blockFocusChange() {
+    fun moveFocus_skipsItemWithCustomEnter() {
         // Arrange.
         val (up, down, left, right, parent) = List(5) { mutableStateOf(false) }
         val child = mutableStateOf(false)
@@ -185,15 +185,95 @@
 
         // Assert.
         rule.runOnIdle {
-            assertThat(movedFocusSuccessfully).isFalse()
+            assertThat(movedFocusSuccessfully).isTrue()
             assertThat(directionSentToEnter).isEqualTo(focusDirection)
             assertThat(child.value).isFalse()
             assertThat(parent.value).isFalse()
             when (focusDirection) {
-                Left -> assertThat(right.value).isTrue()
-                Right -> assertThat(left.value).isTrue()
-                Up -> assertThat(down.value).isTrue()
-                Down -> assertThat(up.value).isTrue()
+                Left -> assertThat(left.value).isTrue()
+                Right -> assertThat(right.value).isTrue()
+                Up -> assertThat(left.value).isTrue()
+                Down -> assertThat(left.value).isTrue()
+            }
+        }
+    }
+
+    /**
+     *                  _________                   |                    _________
+     *                 |   Up   |                   |                   |   Up   |
+     *                 |________|                   |                   |________|
+     *               ________________               |                 ________________
+     *              |  parent       |               |                |  parent       |
+     *              |   _________   |   __________  |   __________   |   _________   |
+     *              |  | child0 |   |  | focused |  |  | focused |   |  | child0 |   |
+     *              |  |________|   |  |_________|  |  |_________|   |  |________|   |
+     *              |_______________|               |                |_______________|
+     *                  _________                   |                    _________
+     *                 |  Down  |                   |                   |  Down  |
+     *                 |________|                   |                   |________|
+     *                                              |
+     *               moveFocus(Left)                |                moveFocus(Right)
+     *                                              |
+     * ---------------------------------------------|--------------------------------------------
+     *                                              |                   __________
+     *                                              |                  | focused |
+     *                                              |                  |_________|
+     *               ________________               |                ________________
+     *              |  parent       |               |               |  parent       |
+     *   _________  |   _________   |   _________   |   _________   |   _________   |    _________
+     *  |  Left  |  |  | child0 |   |  |  Right |   |  |  Left  |   |  | child0 |   |   |  Right |
+     *  |________|  |  |________|   |  |________|   |  |________|   |  |________|   |   |________|
+     *              |_______________|               |               |_______________|
+     *                  __________                  |
+     *                 | focused |                  |
+     *                 |_________|                  |
+     *                                              |
+     *                moveFocus(Up)                 |                moveFocus(Down)
+     *                                              |
+     */
+    @Test
+    fun moveFocusEnter_blockFocusChange_appropriateOtherItemIsFocused() {
+        // Arrange.
+        val (up, down, left, right, parent) = List(5) { mutableStateOf(false) }
+        val child = mutableStateOf(false)
+        var (upItem, downItem, leftItem, rightItem, childItem) = FocusRequester.createRefs()
+        var directionSentToEnter: FocusDirection? = null
+        val customFocusEnter = Modifier.focusProperties {
+            enter = {
+                directionSentToEnter = it
+                Cancel
+            }
+        }
+        when (focusDirection) {
+            Left -> rightItem = initialFocus
+            Right -> leftItem = initialFocus
+            Up -> downItem = initialFocus
+            Down -> upItem = initialFocus
+        }
+        rule.setContentForTest {
+            if (focusDirection != Up) FocusableBox(up, 30, 0, 10, 10, upItem)
+            if (focusDirection != Left) FocusableBox(left, 0, 30, 10, 10, leftItem)
+            FocusableBox(parent, 20, 20, 30, 30, deactivated = true, modifier = customFocusEnter) {
+                FocusableBox(child, 10, 10, 10, 10, childItem)
+            }
+            if (focusDirection != Right) FocusableBox(right, 60, 30, 10, 10, rightItem)
+            if (focusDirection != Down) FocusableBox(down, 30, 60, 10, 10, downItem)
+        }
+
+        // Act.
+        val movedFocusSuccessfully = rule.runOnIdle { focusManager.moveFocus(focusDirection) }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(movedFocusSuccessfully).isTrue()
+            assertThat(directionSentToEnter).isEqualTo(focusDirection)
+            assertThat(child.value).isFalse()
+            assertThat(parent.value).isFalse()
+            when (focusDirection) {
+                Left -> assertThat(up.value).isTrue()
+                Right -> assertThat(up.value).isTrue()
+                Up -> assertThat(left.value).isTrue()
+                Down -> assertThat(left.value).isTrue()
             }
         }
     }
@@ -205,7 +285,7 @@
      *                 ________________
      *                |               |
      *   _________    |     empty     |    _________
-     *  |  Left  |    |   lazylist    |   |  Right |
+     *  |  Left  |    |   lazyList    |   |  Right |
      *  |________|    |               |   |________|
      *                |_______________|
      *                    _________
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalInitialFocusTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalInitialFocusTest.kt
index bfccce6..a08a472 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalInitialFocusTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalInitialFocusTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.ui.focus
 
-import android.view.View
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.text.BasicText
@@ -29,7 +28,6 @@
 import androidx.compose.ui.focus.FocusDirection.Companion.Right
 import androidx.compose.ui.focus.FocusDirection.Companion.Up
 import androidx.compose.ui.platform.LocalFocusManager
-import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.test.junit4.ComposeContentTestRule
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.test.filters.MediumTest
@@ -54,7 +52,6 @@
     }
 
     private val focusDirection = param.focusDirection
-    lateinit var view: View
     private lateinit var focusManager: FocusManager
 
     companion object {
@@ -214,11 +211,9 @@
 
     private fun ComposeContentTestRule.setContentForTest(composable: @Composable () -> Unit) {
         setContent {
-            view = LocalView.current
             focusManager = LocalFocusManager.current
             composable()
         }
-        rule.runOnIdle { view.requestFocus() }
     }
 }
 
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/EditorInfoTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/EditorInfoTest.kt
index ddd1083..5c9a77e 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/EditorInfoTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/EditorInfoTest.kt
@@ -19,11 +19,11 @@
 import android.text.InputType
 import android.view.inputmethod.EditorInfo
 import androidx.compose.ui.text.TextRange
-import androidx.compose.ui.text.input.AndroidImeOptions
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.ImeOptions
 import androidx.compose.ui.text.input.KeyboardCapitalization
 import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.PlatformImeOptions
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.update
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -544,7 +544,7 @@
         val privateImeOptions = "testOptions"
         info.update(
             ImeOptions(
-                platformImeOptions = AndroidImeOptions(privateImeOptions)
+                platformImeOptions = PlatformImeOptions(privateImeOptions)
             )
         )
 
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt
index e350b81..07764c7 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt
@@ -84,7 +84,6 @@
     @Test
     fun noFocusable_doesNotDeliverEvent() {
         // Arrange.
-        var error: IllegalStateException? = null
         rule.setContent {
             Box(
                 modifier = Modifier.onFocusAwareEvent {
@@ -95,25 +94,15 @@
         }
 
         // Act.
-        try {
-            rule.onRoot().performFocusAwareInput(sentEvent)
-        } catch (exception: IllegalStateException) {
-            error = exception
-        }
+        rule.onRoot().performFocusAwareInput(sentEvent)
 
         // Assert.
-        assertThat(receivedEvent).isNull()
-        when (nodeType) {
-            KeyInput, InterruptedSoftKeyboardInput ->
-                assertThat(error!!.message).contains("do not have an active focus target")
-            RotaryInput -> assertThat(error).isNull()
-        }
+        rule.runOnIdle { assertThat(receivedEvent).isNull() }
     }
 
     @Test
     fun unfocusedFocusable_doesNotDeliverEvent() {
         // Arrange.
-        var error: IllegalStateException? = null
         rule.setFocusableContent {
             Box(
                 modifier = Modifier
@@ -126,18 +115,10 @@
         }
 
         // Act.
-        try {
-            rule.onRoot().performFocusAwareInput(sentEvent)
-        } catch (exception: IllegalStateException) {
-            error = exception
-        }
+        rule.onRoot().performFocusAwareInput(sentEvent)
 
         // Assert.
-        assertThat(receivedEvent).isNull()
-        when (nodeType) {
-            KeyInput -> assertThat(error!!.message).contains("do not have an active focus target")
-            InterruptedSoftKeyboardInput, RotaryInput -> assertThat(receivedEvent).isNull()
-        }
+        rule.runOnIdle { assertThat(receivedEvent).isNull() }
     }
 
     @Test
@@ -526,7 +507,7 @@
     }
 
     private fun ComposeContentTestRule.setContentWithInitialFocus(content: @Composable () -> Unit) {
-        setFocusableContent(content)
+        setFocusableContent(content = content)
         runOnIdle { initialFocus.requestFocus() }
     }
 
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt
index 70124ae..f87436d 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package androidx.compose.ui.input.key
 
 import android.view.KeyEvent as AndroidKeyEvent
@@ -39,7 +38,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import kotlin.test.assertFailsWith
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -51,44 +49,45 @@
     val rule = createComposeRule()
 
     @Test
-    fun noRootFocusTarget_throwsException() {
+    fun noFocusTarget_doesNotTriggerOnKeyEvent() {
         // Arrange.
-        rule.setContent {
-            Box(modifier = Modifier.onKeyEvent { false })
+        var receivedKeyEvent: KeyEvent? = null
+        rule.setFocusableContent {
+            Box(
+                Modifier.onKeyEvent {
+                    receivedKeyEvent = it
+                    true
+                }
+            )
         }
 
         // Act.
-        assertFailsWith<IllegalStateException> {
-            rule.onRoot().performKeyPress(keyEvent(KeyCodeA, KeyDown))
-        }
+        rule.onRoot().performKeyPress(keyEvent(KeyCodeA, KeyDown))
+
+        // Assert.
+        rule.runOnIdle { assertThat(receivedKeyEvent).isNull() }
     }
 
     @Test
-    fun noFocusTarget_throwsException() {
+    fun focusTargetNotFocused_doesNotTriggerOnKeyEvent() {
         // Arrange.
+        var receivedKeyEvent: KeyEvent? = null
         rule.setFocusableContent {
-            Box(modifier = Modifier.onKeyEvent { true })
+            Box(
+                Modifier
+                    .focusTarget()
+                    .onKeyEvent {
+                        receivedKeyEvent = it
+                        true
+                    }
+            )
         }
 
         // Act.
-        assertFailsWith<IllegalStateException> {
-            rule.onRoot().performKeyPress(keyEvent(KeyCodeA, KeyDown))
-        }
-    }
+        rule.onRoot().performKeyPress(keyEvent(KeyCodeA, KeyDown))
 
-    @Test
-    fun focusTargetNotFocused_throwsException() {
-        // Arrange.
-        rule.setFocusableContent {
-            Box(modifier = Modifier
-                .focusTarget()
-                .onKeyEvent { true })
-        }
-
-        // Act.
-        assertFailsWith<IllegalStateException> {
-            rule.onRoot().performKeyPress(keyEvent(KeyCodeA, KeyDown))
-        }
+        // Assert.
+        rule.runOnIdle { assertThat(receivedKeyEvent).isNull() }
     }
 
     @Test
@@ -681,7 +680,10 @@
      * The [KeyEvent] is usually created by the system. This function creates an instance of
      * [KeyEvent] that can be used in tests.
      */
-    private fun keyEvent(keycode: Int, keyEventType: KeyEventType): KeyEvent {
+    private fun keyEvent(
+        @Suppress("SameParameterValue") keycode: Int,
+        keyEventType: KeyEventType
+    ): KeyEvent {
         val action = when (keyEventType) {
             KeyDown -> ACTION_DOWN
             KeyUp -> ACTION_UP
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
index c5b32c4..ad79089 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
@@ -929,4 +929,130 @@
         rule.onNodeWithTag(tag)
             .assertHeightIsEqualTo(10.dp)
     }
+
+    // Tests pointerInput with bad pointer data
+    @Test
+    fun pointerInput_badSinglePointer_composeIgnores() {
+        val events = mutableListOf<PointerEventType>()
+        val tag = "input rect"
+        rule.setContent {
+            Box(
+                Modifier.fillMaxSize()
+                    .testTag(tag)
+                    .pointerInput(Unit) {
+                        awaitPointerEventScope {
+                            while (true) {
+                                val event = awaitPointerEvent()
+                                events += event.type
+                            }
+                        }
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performTouchInput {
+            down(Offset.Zero) // Compose handles
+            // Adds pointer (extra finger) with bad data. Because the bad x/y are part of the
+            // MotionEvent, Compose won't process the entire event or any following events
+            // until the bad data is removed.
+            down(1, Offset(Float.NaN, Float.NaN)) // Compose ignores (adds bad data)
+            moveBy(0, Offset(10f, 10f)) // Compose ignores
+            up() // Compose ignores
+        }
+        assertThat(events).hasSize(1)
+        assertThat(events).containsExactly(PointerEventType.Press)
+    }
+
+    @Test
+    fun pointerInput_badSinglePointerRemove_composeOnlyHandlesEventsWhenBadDataRemoved() {
+        val events = mutableListOf<PointerEventType>()
+        val tag = "input rect"
+        rule.setContent {
+            Box(
+                Modifier.fillMaxSize()
+                    .testTag(tag)
+                    .pointerInput(Unit) {
+                        awaitPointerEventScope {
+                            while (true) {
+                                val event = awaitPointerEvent()
+                                events += event.type
+                            }
+                        }
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performTouchInput {
+            down(Offset.Zero) // Compose handles
+            // Adds pointer (extra finger) with bad data. Because the bad x/y are part of the
+            // MotionEvent, Compose won't process the entire event or any following events
+            // until the bad data is removed.
+            down(1, Offset(Float.NaN, Float.NaN)) // Compose ignores (adds bad data)
+            moveBy(0, Offset(10f, 10f)) // Compose ignores
+            moveBy(0, Offset(10f, 10f)) // Compose ignores
+
+            // Remove bad pointer, now Compose will handle events again.
+            up(1)
+            // Compose handles everything after this
+            moveBy(0, Offset(10f, 10f))
+            up()
+        }
+        assertThat(events).hasSize(3)
+        assertThat(events).containsExactly(
+            PointerEventType.Press,
+            PointerEventType.Move,
+            PointerEventType.Release
+        )
+    }
+
+    @Test
+    fun pointerInput_badMultiplePointers_composeIgnores() {
+        val events = mutableListOf<PointerEventType>()
+        val tag = "input rect"
+        rule.setContent {
+            Box(
+                Modifier.fillMaxSize()
+                    .testTag(tag)
+                    .pointerInput(Unit) {
+                        awaitPointerEventScope {
+                            while (true) {
+                                val event = awaitPointerEvent()
+                                events += event.type
+                            }
+                        }
+                    }
+            )
+        }
+
+        rule.onNodeWithTag(tag).performTouchInput {
+            down(Offset.Zero)
+            // Adds pointer (extra finger) with bad data. Because the bad x/y are part of the
+            // MotionEvent, Compose won't process the entire event or any following events
+            // until the bad data is removed.
+            down(1, Offset(Float.NaN, Float.NaN)) // Compose ignores (adds bad data)
+            down(2, Offset(Float.NaN, Float.NaN)) // Compose ignores (adds bad data)
+            down(3, Offset(20f, 20f)) // Ignored by Compose
+            moveBy(3, Offset(10f, 10f)) // Ignored by Compose
+            moveBy(3, Offset(10f, 10f)) // Ignored by Compose
+            moveBy(3, Offset(10f, 10f)) // Ignored by Compose
+
+            // Remove bad pointers
+            up(1)
+            up(2)
+
+            // Now that bad pointers are gone, Compose properly handles all of these:
+            moveBy(3, Offset(10f, 10f))
+            moveBy(0, Offset(10f, 10f))
+            up() // defaults to id=0
+            up(3)
+        }
+        assertThat(events).hasSize(5)
+        assertThat(events).containsExactly(
+            PointerEventType.Press,
+            PointerEventType.Move,
+            PointerEventType.Move,
+            PointerEventType.Release,
+            PointerEventType.Release
+        )
+    }
 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEventTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEventTest.kt
index e6eb02c..2364e7f 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEventTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEventTest.kt
@@ -45,6 +45,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
+import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -60,6 +61,11 @@
     private var receivedEvent: RotaryScrollEvent? = null
     private val tolerance: Float = 0.000001f
 
+    @Before
+    fun before() {
+        receivedEvent = null
+    }
+
     @Test
     fun androidWearCrownRotation_triggersRotaryEvent() {
         // Arrange.
@@ -90,6 +96,38 @@
         }
     }
 
+    // tests bad data
+    @Test
+    fun androidWearCrownRotation_triggersRotaryEventWithBadData() {
+        // Arrange.
+        ContentWithInitialFocus {
+            Box(
+                modifier = Modifier
+                    .onRotaryScrollEvent {
+                        receivedEvent = it
+                        true
+                    }
+                    .focusable(initiallyFocused = true)
+            )
+        }
+
+        // Act.
+        rule.runOnIdle {
+            rootView.dispatchGenericMotionEvent(
+                MotionEventBuilder.newBuilder()
+                    .setAction(ACTION_SCROLL)
+                    .setSource(SOURCE_ROTARY_ENCODER)
+                    .setPointer(Float.NaN, Float.NaN)
+                    .build()
+            )
+        }
+
+        // Assert.
+        rule.runOnIdle {
+            assertThat(receivedEvent).isNull()
+        }
+    }
+
     @Test
     fun delegated_androidWearCrownRotation_triggersRotaryEvent() {
         val node = object : DelegatingNode() {
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
index 69c453e..4de0f4c 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
@@ -19,7 +19,6 @@
 package androidx.compose.ui.layout
 
 import androidx.activity.ComponentActivity
-import androidx.compose.animation.AnimatedContent
 import androidx.compose.animation.animateContentSize
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.AnimationVector2D
@@ -53,7 +52,6 @@
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.layout.wrapContentWidth
-import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
@@ -64,7 +62,6 @@
 import androidx.compose.runtime.movableContentOf
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.produceState
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
@@ -103,7 +100,6 @@
 import kotlin.math.roundToInt
 import kotlin.random.Random
 import kotlin.test.assertNotNull
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import org.junit.Ignore
 import org.junit.Rule
@@ -2290,83 +2286,6 @@
         }
     }
 
-    @Test
-    fun forceMeasureLookaheadRootInParentsMeasurePass() {
-        var show by mutableStateOf(false)
-        var lookaheadOffset: Offset? = null
-        var offset: Offset? = null
-        rule.setContent {
-            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                // Mutate this state in measure
-                Box(Modifier.fillMaxSize()) {
-                    val size by produceState(initialValue = 200) {
-                        delay(500)
-                        value = 600 - value
-                    }
-                    LazyColumn(Modifier.layout { measurable, _ ->
-                        // Mutate this state in measure. This state will later be used in descendant's
-                        // composition.
-                        show = size > 300
-                        measurable.measure(Constraints.fixed(size, size)).run {
-                            layout(width, height) { place(0, 0) }
-                        }
-                    }) {
-                        item {
-                            SubcomposeLayout(Modifier.fillMaxSize()) {
-                                val placeable = subcompose(Unit) {
-                                    // read the value to force a recomposition
-                                    Box(
-                                        Modifier.requiredSize(222.dp)
-                                    ) {
-                                        AnimatedContent(show, Modifier.requiredSize(200.dp)) {
-                                            if (it) {
-                                                Row(
-                                                    Modifier
-                                                        .fillMaxSize()
-                                                        .layout { measurable, constraints ->
-                                                            val p = measurable.measure(constraints)
-                                                            layout(p.width, p.height) {
-                                                                coordinates
-                                                                    ?.positionInRoot()
-                                                                    .let {
-                                                                        if (isLookingAhead) {
-                                                                            lookaheadOffset = it
-                                                                        } else {
-                                                                            offset = it
-                                                                        }
-                                                                    }
-                                                                p.place(0, 0)
-                                                            }
-                                                        }) {}
-                                            } else {
-                                                Row(
-                                                    Modifier.size(10.dp)
-                                                ) {}
-                                            }
-                                        }
-                                    }
-                                }[0].measure(Constraints(0, 2000, 0, 2000))
-                                // Measure with the same constraints to ensure the child (i.e. Box)
-                                // gets no constraints change and hence starts forceMeasureSubtree
-                                // from there
-                                layout(700, 800) {
-                                    placeable.place(0, 0)
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        rule.waitUntil(2000) {
-            show
-        }
-        rule.waitForIdle()
-
-        assertEquals(Offset(-150f, 0f), lookaheadOffset)
-        assertEquals(Offset(-150f, 0f), offset)
-    }
-
     @OptIn(ExperimentalComposeUiApi::class)
     @Test
     fun lookaheadSizeTrackedWhenModifierChanges() {
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/MeasureOnlyTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/MeasureOnlyTest.kt
index f95f492..c64186f 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/MeasureOnlyTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/MeasureOnlyTest.kt
@@ -18,14 +18,9 @@
 import android.view.View
 import android.view.View.MeasureSpec
 import androidx.activity.ComponentActivity
-import androidx.compose.animation.AnimatedContent
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
@@ -34,19 +29,15 @@
 import androidx.compose.ui.background
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
-import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.constrainHeight
 import androidx.compose.ui.unit.constrainWidth
-import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
-import kotlin.test.assertEquals
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -287,64 +278,4 @@
             assertThat(view.height).isEqualTo(10)
         }
     }
-
-    /**
-     * When a descendant affects the root size, the root should resize when the
-     * descendant changes size.
-     */
-    @Test
-    fun remeasureRootWithLookahead() {
-        var largeContent by mutableStateOf(false)
-        var lookaheadSize: IntSize? = null
-        rule.setContent {
-            // Forces the box to change size, so that the containing AndroidView will get a
-            // different set of measureSpec in `onMeasure`.
-            Box(Modifier.size(if (largeContent) 200.dp else 100.dp)) {
-                AndroidView(factory = { context ->
-                    ComposeView(context).apply {
-                        setContent {
-                            CompositionLocalProvider(LocalDensity provides Density(1f)) {
-                                Box(Modifier.requiredSize(300.dp)) {
-                                    LazyColumn(Modifier.size(300.dp)) {
-                                        item {
-                                            AnimatedContent(largeContent, Modifier.fillMaxSize()) {
-                                                if (it) {
-                                                    Box(
-                                                        Modifier
-                                                            .layout { measurable, constraints ->
-                                                                val placeable = measurable
-                                                                    .measure(constraints)
-                                                                if (isLookingAhead)
-                                                                    lookaheadSize = IntSize(
-                                                                        placeable.width,
-                                                                        placeable.height
-                                                                    )
-                                                                layout(
-                                                                    placeable.width,
-                                                                    placeable.height
-                                                                ) {
-                                                                    placeable.place(0, 0)
-                                                                }
-                                                            }
-                                                            .size(200.dp))
-                                                } else {
-                                                    Box(Modifier.size(100.dp))
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                })
-            }
-        }
-        rule.runOnIdle {
-            largeContent = true
-        }
-        rule.runOnIdle {
-            assertEquals(lookaheadSize, IntSize(300, 200))
-        }
-    }
 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/modifier/ModifierLocalSameLayoutNodeTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/modifier/ModifierLocalSameLayoutNodeTest.kt
index 7144730..a3c7abd 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/modifier/ModifierLocalSameLayoutNodeTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/modifier/ModifierLocalSameLayoutNodeTest.kt
@@ -243,6 +243,7 @@
         val provider2value = "Provider2"
         var useFirstProvider by mutableStateOf(true)
         val receivedValues = mutableListOf<String>()
+
         rule.setContent {
             Box(
                 Modifier
@@ -263,7 +264,7 @@
         // Assert.
         rule.runOnIdle {
             assertThat(receivedValues)
-                .containsExactly(provider1value, defaultValue, provider2value, provider2value)
+                .containsExactly(provider1value, provider2value)
                 .inOrder()
         }
     }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/node/NodeUtils.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/node/NodeUtils.kt
index bec5a59..592ab66 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/node/NodeUtils.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/node/NodeUtils.kt
@@ -21,10 +21,10 @@
 
 /**
  * Remove the root modifier nodes as they are not relevant from the perspective of the tests.
- * There are 5 nodes:
- * KeyInputNode, FocusTargetNode, RotaryInputNode, SemanticsNode and DragAndDropNode.
+ * There are 5 nodes: FocusTargetNode, FocusPropertiesNode, KeyInputNode, RotaryInputNode,
+ * SemanticsNode and DragAndDropNode.
  */
-internal fun <T> List<T>.trimRootModifierNodes(): List<T> = dropLast(5)
+internal fun <T> List<T>.trimRootModifierNodes(): List<T> = dropLast(6)
 
 internal fun Modifier.elementOf(node: Modifier.Node): Modifier {
     return this.then(ElementOf { node })
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidComposeViewsInRecyclerViewTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidComposeViewsInRecyclerViewTest.kt
index e6c7ce2..179d68b 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidComposeViewsInRecyclerViewTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/AndroidComposeViewsInRecyclerViewTest.kt
@@ -17,13 +17,11 @@
 package androidx.compose.ui.platform
 
 import android.content.Context
-import android.os.Build
 import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.LinearLayout
 import androidx.activity.ComponentActivity
-import androidx.annotation.RequiresApi
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.recyclerview.widget.DefaultItemAnimator
@@ -32,7 +30,6 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.testutils.AnimationDurationScaleRule
 import com.google.common.truth.Truth.assertThat
@@ -54,7 +51,6 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
 /**
  * Note: this test's structure largely parallels PoolingContainerRecyclerViewTest
  * (though there are notable implementation differences)
@@ -503,7 +499,6 @@
     var binds = 0
     var releases = 0
 
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
         val view = DisposalCountingComposeView(context, this)
         view.layoutParams =
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
index 2a2d199..f539ca4 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
@@ -18,9 +18,11 @@
 
 import android.view.KeyEvent
 import android.view.View
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.mutableStateOf
-import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.focusTarget
 import androidx.compose.ui.focus.setFocusableContent
 import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
 import androidx.compose.ui.test.junit4.AndroidComposeTestRule
@@ -53,7 +55,6 @@
         rule.setContent {
             BasicText("Main Window")
             windowInfo = LocalWindowInfo.current
-            @Suppress("DEPRECATION")
             WindowFocusObserver { if (it) windowFocusGain.countDown() }
         }
 
@@ -201,21 +202,16 @@
         assertThat(mainWindowInfo.isWindowFocused).isTrue()
     }
 
-    @OptIn(ExperimentalComposeUiApi::class)
     @Test
     fun windowInfo_providesKeyModifiers() {
-        lateinit var mainWindowInfo: WindowInfo
         lateinit var ownerView: View
-
         var keyModifiers = PointerKeyboardModifiers(0)
 
         rule.setFocusableContent {
             ownerView = LocalView.current
-            mainWindowInfo = LocalWindowInfo.current
-
-            keyModifiers = mainWindowInfo.keyboardModifiers
+            keyModifiers = LocalWindowInfo.current.keyboardModifiers
+            Box(Modifier.focusTarget())
         }
-
         assertThat(keyModifiers.packedValue).isEqualTo(0)
 
         (rule as AndroidComposeTestRule<*, *>).runOnUiThread {
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt
index e67101a..72f913c 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt
@@ -40,9 +40,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@Composable private fun Recompose(body: @Composable (recompose: () -> Unit) -> Unit) {
-    val scope = currentRecomposeScope
-    body { scope.invalidate() }
+@Composable private fun Wrapper(body: @Composable () -> Unit) {
+    body()
 }
 
 @MediumTest
@@ -68,13 +67,14 @@
         activityScenario.onActivity {
             it.setContent {
                 SideEffect { composeWrapperCount++ }
-                Recompose { recompose ->
+                Wrapper {
+                    val scope = currentRecomposeScope
                     SideEffect {
                         innerCount++
                         commitLatch.countDown()
                     }
                     DisposableEffect(Unit) {
-                        recompose()
+                        scope.invalidate()
                         onDispose { }
                     }
                 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
index 61da18a..5312b3d 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
@@ -113,7 +113,33 @@
     }
 
     @Test
-    fun isTraversalGroupProperty() {
+    fun paneTitleProperty_unmergedConfig() {
+        val paneTitleString = "test PaneTitle string"
+
+        rule.setContent {
+            Surface {
+                Box(
+                    Modifier
+                        .testTag(TestTag)
+                        .semantics { paneTitle = paneTitleString }
+                ) {}
+            }
+        }
+
+        rule.onNodeWithTag(TestTag)
+            .assert(
+                SemanticsMatcher("unmerged paneTitle property") {
+                    it.unmergedConfig.getOrNull(SemanticsProperties.PaneTitle) == paneTitleString
+                }
+            )
+
+        rule.onNodeWithTag(TestTag)
+            .assert(SemanticsMatcher.expectValue(
+                SemanticsProperties.PaneTitle, paneTitleString))
+    }
+
+    @Test
+    fun isTraversalGroupProperty_unmergedConfig() {
         rule.setContent {
             Surface(
                 Modifier.testTag(TestTag)
@@ -123,12 +149,19 @@
         }
 
         rule.onNodeWithTag(TestTag)
+            .assert(
+                SemanticsMatcher("unmerged traversalGroup property") {
+                    it.unmergedConfig.getOrNull(SemanticsProperties.IsTraversalGroup) == true
+                }
+            )
+
+        rule.onNodeWithTag(TestTag)
             .assert(SemanticsMatcher.expectValue(
                 SemanticsProperties.IsTraversalGroup, true))
     }
 
     @Test
-    fun traversalIndexProperty() {
+    fun traversalIndexProperty_unmergedConfig() {
         rule.setContent {
             Surface {
                 Box(Modifier
@@ -141,6 +174,13 @@
         }
 
         rule.onNodeWithTag(TestTag)
+            .assert(
+                SemanticsMatcher("unmerged traversalIndex property") {
+                    // Using unmerged config here since `traversalIndex` doesn't depend on `config`
+                    it.unmergedConfig.getOrNull(SemanticsProperties.TraversalIndex) == 0f
+                }
+            )
+        rule.onNodeWithTag(TestTag)
             .assert(SemanticsMatcher.expectValue(
                 SemanticsProperties.TraversalIndex, 0f))
     }
@@ -182,7 +222,7 @@
         rule.onNodeWithTag(TestTag)
             .assert(
                 SemanticsMatcher("container property") {
-                    it.config.getOrNull(SemanticsProperties.IsContainer) == true
+                    it.unmergedConfig.getOrNull(SemanticsProperties.IsContainer) == true
                 }
             )
         rule.onNodeWithTag(TestTag)
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofill.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofill.android.kt
index 1b530eb..6f618e4 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofill.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofill.android.kt
@@ -28,7 +28,7 @@
 import androidx.annotation.RequiresApi
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.util.fastMap
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Autofill implementation for Android.
@@ -55,10 +55,10 @@
             view,
             autofillNode.id,
             android.graphics.Rect(
-                boundingBox.left.roundToInt(),
-                boundingBox.top.roundToInt(),
-                boundingBox.right.roundToInt(),
-                boundingBox.bottom.roundToInt()
+                boundingBox.left.fastRoundToInt(),
+                boundingBox.top.fastRoundToInt(),
+                boundingBox.right.fastRoundToInt(),
+                boundingBox.bottom.fastRoundToInt()
             )
         )
     }
@@ -106,10 +106,10 @@
                         Did you call perform autofillTree before the component was positioned? """
                 )
             } else {
-                val left = boundingBox.left.roundToInt()
-                val top = boundingBox.top.roundToInt()
-                val right = boundingBox.right.roundToInt()
-                val bottom = boundingBox.bottom.roundToInt()
+                val left = boundingBox.left.fastRoundToInt()
+                val top = boundingBox.top.fastRoundToInt()
+                val right = boundingBox.right.fastRoundToInt()
+                val bottom = boundingBox.bottom.fastRoundToInt()
                 val width = right - left
                 val height = bottom - top
                 AutofillApi23Helper.setDimens(child, left, top, 0, 0, width, height)
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/focus/FocusInteropUtils.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/focus/FocusInteropUtils.android.kt
new file mode 100644
index 0000000..922d23c
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/focus/FocusInteropUtils.android.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.compose.ui.focus
+
+import android.view.ViewGroup
+import androidx.compose.ui.unit.LayoutDirection
+
+/**
+ * Converts an android focus direction to a compose [focus direction][FocusDirection].
+ */
+internal fun toFocusDirection(androidDirection: Int): FocusDirection? = when (androidDirection) {
+    ViewGroup.FOCUS_UP -> FocusDirection.Up
+    ViewGroup.FOCUS_DOWN -> FocusDirection.Down
+    ViewGroup.FOCUS_LEFT -> FocusDirection.Left
+    ViewGroup.FOCUS_RIGHT -> FocusDirection.Right
+    ViewGroup.FOCUS_FORWARD -> FocusDirection.Next
+    ViewGroup.FOCUS_BACKWARD -> FocusDirection.Previous
+    else -> null
+}
+
+/**
+ * Converts a compose [focus direction][FocusDirection] to an android focus direction.
+ */
+internal fun FocusDirection.toAndroidFocusDirection(): Int? = when (this) {
+        FocusDirection.Up -> ViewGroup.FOCUS_UP
+        FocusDirection.Down -> ViewGroup.FOCUS_DOWN
+        FocusDirection.Left -> ViewGroup.FOCUS_LEFT
+        FocusDirection.Right -> ViewGroup.FOCUS_RIGHT
+        FocusDirection.Next -> ViewGroup.FOCUS_FORWARD
+        FocusDirection.Previous -> ViewGroup.FOCUS_BACKWARD
+        else -> null
+    }
+
+/**
+ * Convert an Android layout direction to a compose [layout direction][LayoutDirection].
+ */
+internal fun toLayoutDirection(androidLayoutDirection: Int): LayoutDirection? {
+    return when (androidLayoutDirection) {
+        android.util.LayoutDirection.LTR -> LayoutDirection.Ltr
+        android.util.LayoutDirection.RTL -> LayoutDirection.Rtl
+        else -> null
+    }
+}
+
+/**
+ * focus search in the Android framework wraps around for 1D focus search, but not for 2D focus
+ * search. This is a helper function that can be used to determine whether we should wrap around.
+ */
+internal fun supportsWrapAroundFocus(androidDirection: Int): Boolean = when (androidDirection) {
+    ViewGroup.FOCUS_FORWARD, ViewGroup.FOCUS_BACKWARD -> true
+    else -> false
+}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt
index b33cc3f..de00860 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AccessibilityIterators.android.kt
@@ -21,9 +21,9 @@
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.style.ResolvedTextDirection
+import androidx.compose.ui.util.fastRoundToInt
 import java.text.BreakIterator
 import java.util.Locale
-import kotlin.math.roundToInt
 
 /**
  * This class contains the implementation of text segment iterators
@@ -457,7 +457,7 @@
             }
             val pageHeight: Int
             try {
-                pageHeight = node.boundsInRoot.height.roundToInt()
+                pageHeight = node.boundsInRoot.height.fastRoundToInt()
                 // TODO(b/153198816): check whether we still get this exception when R is in.
             } catch (e: IllegalStateException) {
                 return null
@@ -491,7 +491,7 @@
             }
             val pageHeight: Int
             try {
-                pageHeight = node.boundsInRoot.height.roundToInt()
+                pageHeight = node.boundsInRoot.height.fastRoundToInt()
                 // TODO(b/153198816): check whether we still get this exception when R is in.
             } catch (e: IllegalStateException) {
                 return null
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 66034b5..20f9dd0 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -22,7 +22,6 @@
 import android.os.Build
 import android.os.Looper
 import android.os.SystemClock
-import android.util.Log
 import android.util.LongSparseArray
 import android.util.SparseArray
 import android.view.DragEvent
@@ -80,6 +79,7 @@
 import androidx.compose.ui.draganddrop.DragAndDropTransferData
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.FocusDirection.Companion.Down
+import androidx.compose.ui.focus.FocusDirection.Companion.Enter
 import androidx.compose.ui.focus.FocusDirection.Companion.Exit
 import androidx.compose.ui.focus.FocusDirection.Companion.Left
 import androidx.compose.ui.focus.FocusDirection.Companion.Next
@@ -88,6 +88,11 @@
 import androidx.compose.ui.focus.FocusDirection.Companion.Up
 import androidx.compose.ui.focus.FocusOwner
 import androidx.compose.ui.focus.FocusOwnerImpl
+import androidx.compose.ui.focus.requestFocus
+import androidx.compose.ui.focus.supportsWrapAroundFocus
+import androidx.compose.ui.focus.toAndroidFocusDirection
+import androidx.compose.ui.focus.toFocusDirection
+import androidx.compose.ui.focus.toLayoutDirection
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Canvas
@@ -95,19 +100,21 @@
 import androidx.compose.ui.graphics.Matrix
 import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.graphics.setFrom
+import androidx.compose.ui.graphics.toAndroidRect
+import androidx.compose.ui.graphics.toComposeRect
 import androidx.compose.ui.hapticfeedback.HapticFeedback
 import androidx.compose.ui.hapticfeedback.PlatformHapticFeedback
 import androidx.compose.ui.input.InputMode.Companion.Keyboard
 import androidx.compose.ui.input.InputMode.Companion.Touch
 import androidx.compose.ui.input.InputModeManager
 import androidx.compose.ui.input.InputModeManagerImpl
+import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.input.key.Key.Companion.Back
 import androidx.compose.ui.input.key.Key.Companion.DirectionCenter
 import androidx.compose.ui.input.key.Key.Companion.DirectionDown
 import androidx.compose.ui.input.key.Key.Companion.DirectionLeft
 import androidx.compose.ui.input.key.Key.Companion.DirectionRight
 import androidx.compose.ui.input.key.Key.Companion.DirectionUp
-import androidx.compose.ui.input.key.Key.Companion.Enter
 import androidx.compose.ui.input.key.Key.Companion.Escape
 import androidx.compose.ui.input.key.Key.Companion.NumPadEnter
 import androidx.compose.ui.input.key.Key.Companion.PageDown
@@ -160,6 +167,7 @@
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.util.fastLastOrNull
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.compose.ui.util.trace
 import androidx.compose.ui.viewinterop.AndroidViewHolder
 import androidx.core.view.AccessibilityDelegateCompat
@@ -179,7 +187,6 @@
 import java.lang.reflect.Method
 import java.util.function.Consumer
 import kotlin.coroutines.CoroutineContext
-import kotlin.math.roundToInt
 
 /**
  * Allows tests to inject a custom [PlatformTextInputService].
@@ -220,12 +227,15 @@
 
     private val semanticsModifier = EmptySemanticsElement
 
-    override val focusOwner: FocusOwner = FocusOwnerImpl { registerOnEndApplyChangesListener(it) }
-
-    private val dragAndDropModifierOnDragListener = DragAndDropModifierOnDragListener(
-        ::startDrag
+    override val focusOwner: FocusOwner = FocusOwnerImpl(
+        onRequestApplyChangesListener = ::registerOnEndApplyChangesListener,
+        onRequestFocusForOwner = ::onRequestFocusForOwner,
+        onClearFocusForOwner = ::onClearFocusForOwner,
+        layoutDirection = ::layoutDirection
     )
 
+    private val dragAndDropModifierOnDragListener = DragAndDropModifierOnDragListener(::startDrag)
+
     override val dragAndDropManager: DragAndDropManager = dragAndDropModifierOnDragListener
 
     private val _windowInfo: WindowInfoImpl = WindowInfoImpl()
@@ -238,8 +248,10 @@
         val focusDirection = getFocusDirection(it)
         if (focusDirection == null || it.type != KeyDown) return@onKeyEvent false
 
-        // Consume the key event if we moved focus.
-        focusOwner.moveFocus(focusDirection)
+        // Consume the key event if we moved focus or if focus search or requestFocus is cancelled.
+        focusOwner.focusSearch(focusDirection, null) { focusTargetNode ->
+            focusTargetNode.requestFocus(focusDirection) ?: true
+        } ?: true
     }
 
     private val rotaryInputModifier = Modifier.onRotaryScrollEvent {
@@ -256,8 +268,8 @@
         it.modifier = Modifier
             .then(semanticsModifier)
             .then(rotaryInputModifier)
-            .then(focusOwner.modifier)
             .then(keyInputModifier)
+            .then(focusOwner.modifier)
             .then(dragAndDropModifierOnDragListener.modifier)
     }
 
@@ -460,7 +472,11 @@
 
     // Backed by mutableStateOf so that the ambient provider recomposes when it changes
     override var layoutDirection by mutableStateOf(
-        context.resources.configuration.localeLayoutDirection
+        // We don't use the attached View's layout direction here since that layout direction may not
+        // be resolved since composables may be composed without attaching to the RootViewImpl.
+        // In Jetpack Compose, use the locale layout direction (i.e. layoutDirection came from
+        // configuration) as a default layout direction.
+        toLayoutDirection(context.resources.configuration.layoutDirection) ?: LayoutDirection.Ltr
     )
         private set
 
@@ -634,10 +650,10 @@
      */
     override fun getFocusedRect(rect: Rect) {
         focusOwner.getFocusRect()?.run {
-            rect.left = left.roundToInt()
-            rect.top = top.roundToInt()
-            rect.right = right.roundToInt()
-            rect.bottom = bottom.roundToInt()
+            rect.left = left.fastRoundToInt()
+            rect.top = top.fastRoundToInt()
+            rect.right = right.fastRoundToInt()
+            rect.bottom = bottom.fastRoundToInt()
         } ?: super.getFocusedRect(rect)
     }
 
@@ -646,14 +662,65 @@
         showLayoutBounds = getIsShowingLayoutBounds()
     }
 
+    override fun focusSearch(direction: Int): View? = if (focusOwner.rootState.hasFocus) {
+        // When the compose hierarchy is focused, it intercepts the key events that trigger focus
+        // search. So focus search should never find a compose hierarchy that has focus.
+        //
+        // However there is a case where we don't consume the key events. When all the components
+        // have been visited, and/or focus can't be moved within the compose hierarchy, the key
+        // events are returned to the framework so it can perform a search among other views. This
+        // focus search could land back on this view.
+        //
+        // Ideally just returning "this" to focus search should cause it to call requestFocus with
+        // the previously focused rect, and we would find the next item. However the framework does
+        // not call request focus on this view because it already has focus.
+        //
+        // To fix this issue, we manually clear focus and return this. The view with default focus
+        // might be assigned focus for a while, but requestFocus will be called which will then
+        // transfer focus to this view.
+        //
+        // There is an additional special case here. Focus wraps around only for 1D focus search
+        // and not for 2D focus search. So we clear focus only if focus search was triggered by
+        // a 1D focus search.
+        if (supportsWrapAroundFocus(direction)) clearFocus()
+        this
+    } else {
+        // TODO(b/261190892) run a mixed focus search that searches between composables and
+        //  child views and chooses an appropriate result.
+        //  We give the embedded children a chance to take focus before the compose view.
+        super.focusSearch(direction) ?: this
+    }
+
+    override fun requestFocus(direction: Int, previouslyFocusedRect: Rect?): Boolean {
+        if (focusOwner.rootState.hasFocus) return true
+        return focusOwner.takeFocus(
+            focusDirection = toFocusDirection(direction) ?: Enter,
+            previouslyFocusedRect = previouslyFocusedRect?.toComposeRect()
+        )
+    }
+
+    private fun onRequestFocusForOwner(
+        focusDirection: FocusDirection?,
+        previouslyFocusedRect: androidx.compose.ui.geometry.Rect?
+    ): Boolean {
+        return super.requestFocus(
+            focusDirection?.toAndroidFocusDirection() ?: FOCUS_DOWN,
+            @Suppress("DEPRECATION")
+            previouslyFocusedRect?.toAndroidRect()
+        )
+    }
+
+    private fun onClearFocusForOwner() {
+        if (isFocused || hasFocus()) {
+            super.clearFocus()
+        }
+    }
+
     override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
-        Log.d(FocusTag, "Owner FocusChanged($gainFocus)")
-       focusOwner.focusTransactionManager.withExistingTransaction(
-           onCancelled = { if (gainFocus) clearFocus() else requestFocus() }
-       ) {
-           if (gainFocus) focusOwner.takeFocus() else focusOwner.releaseFocus()
-       }
+        if (!gainFocus) {
+            focusOwner.releaseFocus()
+        }
     }
 
     override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
@@ -1227,7 +1294,7 @@
             // focus.
             DirectionUp, PageUp -> Up
             DirectionDown, PageDown -> Down
-            DirectionCenter, Enter, NumPadEnter -> FocusDirection.Enter
+            DirectionCenter, Key.Enter, NumPadEnter -> Enter
             Back, Escape -> Exit
             else -> null
         }
@@ -1443,10 +1510,11 @@
 
     override fun dispatchGenericMotionEvent(event: MotionEvent) = when (event.actionMasked) {
         ACTION_SCROLL -> when {
-            event.isFromSource(SOURCE_ROTARY_ENCODER) -> handleRotaryEvent(event)
             isBadMotionEvent(event) || !isAttachedToWindow ->
                 super.dispatchGenericMotionEvent(event)
 
+            event.isFromSource(SOURCE_ROTARY_ENCODER) -> handleRotaryEvent(event)
+
             else -> handleMotionEvent(event).dispatchedToAPointerInputModifier
         }
 
@@ -1808,10 +1876,7 @@
         // If we get such a call, don't try to write to a property delegate
         // that hasn't been initialized yet.
         if (superclassInitComplete) {
-            layoutDirectionFromInt(layoutDirection).let {
-                this.layoutDirection = it
-                focusOwner.layoutDirection = it
-            }
+            this.layoutDirection = toLayoutDirection(layoutDirection) ?: LayoutDirection.Ltr
         }
     }
 
@@ -1975,7 +2040,6 @@
     override fun shouldDelayChildPressedState(): Boolean = false
 
     companion object {
-        private const val FocusTag = "Compose Focus"
         private const val MaximumLayerCacheSize = 10
         private var systemPropertiesClass: Class<*>? = null
         private var getBooleanMethod: Method? = null
@@ -2034,25 +2098,6 @@
 }
 
 /**
- * Return the layout direction set by the [Locale][java.util.Locale].
- *
- * A convenience getter that translates [Configuration.getLayoutDirection] result into
- * [LayoutDirection] instance.
- */
-internal val Configuration.localeLayoutDirection: LayoutDirection
-    // We don't use the attached View's layout direction here since that layout direction may not
-    // be resolved since the composables may be composed without attaching to the RootViewImpl.
-    // In Jetpack Compose, use the locale layout direction (i.e. layoutDirection came from
-    // configuration) as a default layout direction.
-    get() = layoutDirectionFromInt(layoutDirection)
-
-private fun layoutDirectionFromInt(layoutDirection: Int): LayoutDirection = when (layoutDirection) {
-    android.util.LayoutDirection.LTR -> LayoutDirection.Ltr
-    android.util.LayoutDirection.RTL -> LayoutDirection.Rtl
-    else -> LayoutDirection.Ltr
-}
-
-/**
  * These classes are here to ensure that the classes that use this API will get verified and can be
  * AOT compiled. It is expected that this class will soft-fail verification, but the classes
  * which use this method will pass.
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
index 21619e8..bce1f6ea 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
@@ -49,9 +49,6 @@
 import androidx.collection.ArrayMap
 import androidx.collection.ArraySet
 import androidx.collection.SparseArrayCompat
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.R
 import androidx.compose.ui.geometry.Offset
@@ -93,10 +90,12 @@
 import androidx.compose.ui.text.platform.toAccessibilitySpannableString
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.toSize
+import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachIndexed
 import androidx.compose.ui.util.fastJoinToString
 import androidx.compose.ui.util.fastMap
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.core.util.keyIterator
 import androidx.core.view.AccessibilityDelegateCompat
 import androidx.core.view.ViewCompat
@@ -115,7 +114,6 @@
 import kotlin.math.floor
 import kotlin.math.max
 import kotlin.math.min
-import kotlin.math.roundToInt
 import kotlin.math.sign
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.delay
@@ -139,8 +137,8 @@
 internal class AndroidComposeViewAccessibilityDelegateCompat(val view: AndroidComposeView) :
     AccessibilityDelegateCompat(),
     DefaultLifecycleObserver {
-        @Suppress("ConstPropertyName")
-        companion object {
+    @Suppress("ConstPropertyName")
+    companion object {
         /** Virtual node identifier value for invalid nodes. */
         const val InvalidId = Integer.MIN_VALUE
         const val ClassName = "android.view.View"
@@ -313,7 +311,7 @@
     // traversal with granularity switches to the next node
     private var previousTraversedNode: Int? = null
     private val subtreeChangedLayoutNodes = ArraySet<LayoutNode>()
-    private val boundsUpdateChannel = Channel<Unit>(Channel.CONFLATED)
+    private val boundsUpdateChannel = Channel<Unit>(1)
     private var currentSemanticsNodesInvalidated = true
     @VisibleForTesting
     internal var contentCaptureForceEnabledForTesting = false
@@ -354,8 +352,10 @@
     internal var idToBeforeMap = HashMap<Int, Int>()
     internal var idToAfterMap = HashMap<Int, Int>()
     internal val ExtraDataTestTraversalBeforeVal =
+        @Suppress("SpellCheckingInspection")
         "android.view.accessibility.extra.EXTRA_DATA_TEST_TRAVERSALBEFORE_VAL"
     internal val ExtraDataTestTraversalAfterVal =
+        @Suppress("SpellCheckingInspection")
         "android.view.accessibility.extra.EXTRA_DATA_TEST_TRAVERSALAFTER_VAL"
 
     private val urlSpanCache = URLSpanCache()
@@ -378,8 +378,6 @@
                 }
             }
         }
-
-        fun hasPaneTitle() = unmergedConfig.contains(SemanticsProperties.PaneTitle)
     }
 
     // previousSemanticsNodes holds the previous pruned semantics tree so that we can compare the
@@ -468,7 +466,8 @@
                 return@any false
             }
 
-            val scrollRange = node.semanticsNode.config.getOrNull(scrollRangeProperty)
+            // Using `unmergedConfig` here is okay since we iterate through all nodes anyway
+            val scrollRange = node.semanticsNode.unmergedConfig.getOrNull(scrollRangeProperty)
                 ?: return@any false
 
             // A node simply having scrollable semantics doesn't mean it's necessarily scrollable
@@ -623,7 +622,7 @@
                 val currRect = rowGroupings[currIndex].first
                 val groupIsEmpty = currRect.top >= currRect.bottom
                 val groupOverlapsEntry = !entryIsEmpty && !groupIsEmpty &&
-                        max(entryTopCoord, currRect.top) < min(entryBottomCoord, currRect.bottom)
+                    max(entryTopCoord, currRect.top) < min(entryBottomCoord, currRect.bottom)
 
                 // If it overlaps with this row group, update cover and add node
                 if (groupOverlapsEntry) {
@@ -666,8 +665,10 @@
         }
 
         // Kotlin `sortWith` should just pull out the highest traversal indices, but keep everything
-        // else in place
-        returnList.sortWith { a, b -> a.traversalIndex.compareTo(b.traversalIndex) }
+        // else in place. If the element does not have a `traversalIndex` then `0f` will be used.
+        returnList.sortWith { a, b ->
+            a.unmergedConfig.getOrElse(SemanticsProperties.TraversalIndex) { 0f }.compareTo(
+                b.unmergedConfig.getOrElse(SemanticsProperties.TraversalIndex) { 0f }) }
 
         var i = 0
         // Afterwards, go in and add the containers' children.
@@ -704,10 +705,11 @@
         containerMapToChildren: MutableMap<Int, MutableList<SemanticsNode>>
     ) {
         val currRTL = currNode.isRtl
-
         // We only want to add children that are either traversalGroups or are
         // screen reader focusable. The child must also be in the current pruned semantics tree.
-        val isTraversalGroup = currNode.isTraversalGroup
+        val isTraversalGroup =
+            currNode.unmergedConfig.getOrElse(SemanticsProperties.IsTraversalGroup) { false }
+
         if ((isTraversalGroup || isScreenReaderFocusable(currNode)) &&
             currNode.id in currentSemanticsNodes.keys) {
             geometryList.add(currNode)
@@ -775,7 +777,9 @@
     private fun isScreenReaderFocusable(
         node: SemanticsNode
     ): Boolean {
-        val isSpeakingNode = node.infoContentDescriptionOrNull != null ||
+        val nodeContentDescriptionOrNull =
+            node.unmergedConfig.getOrNull(SemanticsProperties.ContentDescription)?.firstOrNull()
+        val isSpeakingNode = nodeContentDescriptionOrNull != null ||
             getInfoText(node) != null || getInfoStateDescriptionOrNull(node) != null ||
             getInfoIsCheckable(node)
 
@@ -811,10 +815,10 @@
                 }
             }
         }
-        if (semanticsNode.isTextField) {
+        if (semanticsNode.unmergedConfig.contains(SemanticsActions.SetText)) {
             info.className = TextFieldClassName
         }
-        if (semanticsNode.config.contains(SemanticsProperties.Text)) {
+        if (semanticsNode.unmergedConfig.contains(SemanticsProperties.Text)) {
             info.className = TextClassName
         }
 
@@ -879,7 +883,9 @@
             // content description for such nodes
             semanticsNode.replacedChildren.isEmpty()
         ) {
-            info.contentDescription = semanticsNode.infoContentDescriptionOrNull
+            info.contentDescription =
+                semanticsNode.unmergedConfig.getOrNull(SemanticsProperties.ContentDescription)
+                    ?.firstOrNull()
         }
 
         // Map testTag to resourceName if testTagsAsResourceId == true (which can be set by an ancestor)
@@ -908,8 +914,8 @@
         semanticsNode.unmergedConfig.getOrNull(SemanticsProperties.Heading)?.let {
             info.isHeading = true
         }
-        info.isPassword = semanticsNode.isPassword
-        info.isEditable = semanticsNode.isEditable
+        info.isPassword = semanticsNode.unmergedConfig.contains(SemanticsProperties.Password)
+        info.isEditable = semanticsNode.unmergedConfig.contains(SemanticsProperties.Editable)
         info.isEnabled = semanticsNode.enabled()
         info.isFocusable = semanticsNode.unmergedConfig.contains(SemanticsProperties.Focused)
         if (info.isFocusable) {
@@ -1364,13 +1370,13 @@
                         if (valueRange.endInclusive - valueRange.start == 0f) 0f
                         else (rangeInfo.current - valueRange.start) /
                             (valueRange.endInclusive - valueRange.start)
-                        ).coerceIn(0f, 1f)
+                        ).fastCoerceIn(0f, 1f)
 
                     // We only display 0% or 100% when it is exactly 0% or 100%.
                     val percent = when (progress) {
                         0f -> 0
                         1f -> 100
-                        else -> (progress * 100).roundToInt().coerceIn(1, 99)
+                        else -> (progress * 100).fastRoundToInt().coerceIn(1, 99)
                     }
                     stateDescription =
                         view.context.resources.getString(R.string.template_percent, percent)
@@ -1590,7 +1596,8 @@
         if (isEnabledForAccessibility) {
             // populate additional information from the node
             currentSemanticsNodes[virtualViewId]?.let {
-                event.isPassword = it.semanticsNode.isPassword
+                event.isPassword =
+                    it.semanticsNode.unmergedConfig.contains(SemanticsProperties.Password)
             }
         }
 
@@ -1839,7 +1846,11 @@
 
             AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS -> {
                 return if (node.unmergedConfig.getOrNull(SemanticsProperties.Focused) == true) {
-                    view.focusOwner.clearFocus()
+                    view.focusOwner.clearFocus(
+                        force = false,
+                        refreshFocusEvents = true,
+                        clearOwnerFocus = true
+                    )
                     true
                 } else {
                     false
@@ -1892,13 +1903,15 @@
             android.R.id.accessibilityActionShowOnScreen -> {
                 // TODO(b/190865803): Consider scrolling nested containers instead of only the first one.
                 var scrollableAncestor: SemanticsNode? = node.parent
-                var scrollAction = scrollableAncestor?.config?.getOrNull(SemanticsActions.ScrollBy)
+                var scrollAction = scrollableAncestor?.unmergedConfig
+                    ?.getOrNull(SemanticsActions.ScrollBy)
                 while (scrollableAncestor != null) {
                     if (scrollAction != null) {
                         break
                     }
                     scrollableAncestor = scrollableAncestor.parent
-                    scrollAction = scrollableAncestor?.config?.getOrNull(SemanticsActions.ScrollBy)
+                    scrollAction = scrollableAncestor?.unmergedConfig
+                        ?.getOrNull(SemanticsActions.ScrollBy)
                 }
                 if (scrollableAncestor == null) {
                     return false
@@ -2209,7 +2222,6 @@
      * recent layout changes and sends events to the accessibility and content capture framework in
      * batches separated by a 100ms delay.
      */
-    @OptIn(ExperimentalComposeUiApi::class)
     internal suspend fun boundsUpdatesEventLoop() {
         try {
             val subtreeChangedSemanticsNodesIds = ArraySet<Int>()
@@ -2333,9 +2345,9 @@
 
         // When we finally send the event, make sure it is an accessibility-focusable node.
         var semanticsNode = if (layoutNode.nodes.has(Nodes.Semantics))
-                layoutNode
-            else
-                layoutNode.findClosestParentNode { it.nodes.has(Nodes.Semantics) }
+            layoutNode
+        else
+            layoutNode.findClosestParentNode { it.nodes.has(Nodes.Semantics) }
 
         val config = semanticsNode?.collapsedSemantics ?: return
         if (!config.isMergingSemanticsOfDescendants) {
@@ -2379,7 +2391,8 @@
         val toRemove = ArraySet<Int>()
         for (id in paneDisplayed) {
             val currentNode = currentSemanticsNodes[id]?.semanticsNode
-            if (currentNode == null || !currentNode.hasPaneTitle()) {
+            if (currentNode == null ||
+                !currentNode.unmergedConfig.contains(SemanticsProperties.PaneTitle)) {
                 toRemove.add(id)
                 sendPaneChangeEvents(
                     id,
@@ -2393,7 +2406,8 @@
         paneDisplayed.removeAll(toRemove)
         previousSemanticsNodes.clear()
         for (entry in currentSemanticsNodes.entries) {
-            if (entry.value.semanticsNode.hasPaneTitle() && paneDisplayed.add(entry.key)) {
+            if (entry.value.semanticsNode.unmergedConfig.contains(SemanticsProperties.PaneTitle) &&
+                paneDisplayed.add(entry.key)) {
                 sendPaneChangeEvents(
                     entry.key,
                     AccessibilityEventCompat.CONTENT_CHANGE_TYPE_PANE_APPEARED,
@@ -2466,7 +2480,7 @@
                         val paneTitle = entry.value as String
                         // If oldNode doesn't have pane title, it will be handled in
                         // updateSemanticsNodesCopyAndPanes().
-                        if (oldNode.hasPaneTitle()) {
+                        if (oldNode.unmergedConfig.contains(SemanticsProperties.PaneTitle)) {
                             sendPaneChangeEvents(
                                 id,
                                 AccessibilityEventCompat.CONTENT_CHANGE_TYPE_PANE_TITLE,
@@ -2510,15 +2524,20 @@
                     SemanticsProperties.Selected -> {
                         // The assumption is among widgets using SemanticsProperties.Selected, only
                         // Tab is using AccessibilityNodeInfo#isSelected, and all others are using
-                        // AccessibilityNodeInfo#isChekable and setting
+                        // AccessibilityNodeInfo#isCheckable and setting
                         // AccessibilityNodeInfo#stateDescription in this delegate.
-                        if (newNode.config.getOrNull(SemanticsProperties.Role) == Role.Tab) {
-                            if (newNode.config.getOrNull(SemanticsProperties.Selected) == true) {
+                        if (newNode.unmergedConfig.getOrNull(SemanticsProperties.Role)
+                            == Role.Tab) {
+                            if (newNode.unmergedConfig.getOrNull(SemanticsProperties.Selected)
+                                == true) {
                                 val event = createEvent(
                                     semanticsNodeIdToAccessibilityVirtualNodeId(id),
                                     AccessibilityEvent.TYPE_VIEW_SELECTED
                                 )
-                                // Here we use the merged node
+                                // Here we use the merged node. Because we specifically are using
+                                // the merged node, we must also use the merged version of the
+                                // SemanticsConfiguration via `config` instead of `unmergedConfig`
+                                // as the rest of the file uses.
                                 val mergedNode = newNode.copyWithMergingEnabled()
                                 val contentDescription = mergedNode.config.getOrNull(
                                     SemanticsProperties.ContentDescription
@@ -2563,7 +2582,7 @@
                     }
 
                     SemanticsProperties.EditableText -> {
-                        if (newNode.isTextField) {
+                        if (newNode.unmergedConfig.contains(SemanticsActions.SetText)) {
 
                             val oldText = oldNode.unmergedConfig.getTextForTextField() ?: ""
                             val newText = newNode.unmergedConfig.getTextForTextField() ?: ""
@@ -2594,12 +2613,19 @@
                             val removedCount = oldTextLen - endCount - startCount
                             val addedCount = newTextLen - endCount - startCount
 
+                            val oldNodeIsPassword =
+                                oldNode.unmergedConfig.contains(SemanticsProperties.Password)
+                            val newNodeIsPassword =
+                                newNode.unmergedConfig.contains(SemanticsProperties.Password)
+                            val oldNodeIsTextfield =
+                                oldNode.unmergedConfig.contains(SemanticsActions.SetText)
+
                             // (b/247891690) We won't send a text change event when we only toggle
                             // the password visibility of the node
-                            val becamePasswordNode = oldNode.semanticsNode.isTextField &&
-                                !oldNode.semanticsNode.isPassword && newNode.isPassword
-                            val becameNotPasswordNode = oldNode.semanticsNode.isTextField &&
-                                oldNode.semanticsNode.isPassword && !newNode.isPassword
+                            val becamePasswordNode = oldNodeIsTextfield &&
+                                !oldNodeIsPassword && newNodeIsPassword
+                            val becameNotPasswordNode = oldNodeIsTextfield &&
+                                oldNodeIsPassword && !newNodeIsPassword
                             val event = if (becamePasswordNode || becameNotPasswordNode) {
                                 // (b/247891690) password visibility toggle is handled by a
                                 // selection event. Because internally Talkback already has the
@@ -2985,10 +3011,10 @@
         }
         if (bufferedContentCaptureDisappearedNodes.isNotEmpty()) {
             session.notifyViewsDisappeared(
-                    bufferedContentCaptureDisappearedNodes
-                        .toList()
-                        .fastMap { it.toLong() }
-                        .toLongArray())
+                bufferedContentCaptureDisappearedNodes
+                    .toList()
+                    .fastMap { it.toLong() }
+                    .toLongArray())
             bufferedContentCaptureDisappearedNodes.clear()
         }
     }
@@ -3368,7 +3394,7 @@
                 .fastJoinToString(",")
         }
 
-        if (node.isTextField) {
+        if (node.unmergedConfig.contains(SemanticsActions.SetText)) {
             return node.unmergedConfig.getTextForTextField()?.text
         }
 
@@ -3498,7 +3524,9 @@
                     node.id.toLong()
                 )
 
-                val text = AnnotatedString(node.getTextForTranslation() ?: return@forEach)
+                val text = AnnotatedString(
+                    node.unmergedConfig.getOrNull(SemanticsProperties.Text)
+                        ?.fastJoinToString("\n") ?: return@forEach)
 
                 requestBuilder.setValue(ViewTranslationRequest.ID_TEXT,
                     TranslationRequestValue.forText(text))
@@ -3552,7 +3580,7 @@
 
 private fun SemanticsNode.isImportantForAccessibility() =
     unmergedConfig.isMergingSemanticsOfDescendants ||
-    unmergedConfig.containsImportantForAccessibility()
+        unmergedConfig.containsImportantForAccessibility()
 
 @OptIn(ExperimentalComposeUiApi::class)
 private val SemanticsNode.isVisible: Boolean
@@ -3567,26 +3595,12 @@
     return false
 }
 
-private fun SemanticsNode.hasPaneTitle() = config.contains(SemanticsProperties.PaneTitle)
-private inline val SemanticsNode.isPassword: Boolean get() =
-    config.contains(SemanticsProperties.Password)
-private inline val SemanticsNode.isTextField get() =
-    unmergedConfig.contains(SemanticsActions.SetText)
-private inline val SemanticsNode.isEditable get() = config.contains(SemanticsProperties.Editable)
 private val SemanticsNode.isRtl get() = layoutInfo.layoutDirection == LayoutDirection.Rtl
-private inline val SemanticsNode.isTraversalGroup get() =
-    config.getOrElse(SemanticsProperties.IsTraversalGroup) { false }
-private inline val SemanticsNode.traversalIndex get() =
-    config.getOrElse(SemanticsProperties.TraversalIndex) { 0f }
-private val SemanticsNode.infoContentDescriptionOrNull get() = this.unmergedConfig.getOrNull(
-    SemanticsProperties.ContentDescription)?.firstOrNull()
-
-private fun SemanticsNode.getTextForTranslation(): String? = this.unmergedConfig.getOrNull(
-    SemanticsProperties.Text)?.fastJoinToString("\n")
 
 private fun SemanticsNode.excludeLineAndPageGranularities(): Boolean {
     // text field that is not in focus
-    if (isTextField && unmergedConfig.getOrNull(SemanticsProperties.Focused) != true) return true
+    if (unmergedConfig.contains(SemanticsActions.SetText) &&
+        unmergedConfig.getOrNull(SemanticsProperties.Focused) != true) return true
 
     // text nodes that are part of the 'merged' text field, for example hint or label.
     val ancestor = layoutNode.findClosestParentNode {
@@ -3636,7 +3650,12 @@
     }
 
     val unaccountedSpace = with(root.boundsInRoot) {
-        Region(left.roundToInt(), top.roundToInt(), right.roundToInt(), bottom.roundToInt())
+        Region(
+            left.fastRoundToInt(),
+            top.fastRoundToInt(),
+            right.fastRoundToInt(),
+            bottom.fastRoundToInt()
+        )
     }
 
     fun findAllSemanticNodesRecursive(currentNode: SemanticsNode, region: Region) {
@@ -3648,10 +3667,10 @@
             return
         }
         val touchBoundsInRoot = currentNode.touchBoundsInRoot
-        val left = touchBoundsInRoot.left.roundToInt()
-        val top = touchBoundsInRoot.top.roundToInt()
-        val right = touchBoundsInRoot.right.roundToInt()
-        val bottom = touchBoundsInRoot.bottom.roundToInt()
+        val left = touchBoundsInRoot.left.fastRoundToInt()
+        val top = touchBoundsInRoot.top.fastRoundToInt()
+        val right = touchBoundsInRoot.right.fastRoundToInt()
+        val bottom = touchBoundsInRoot.bottom.fastRoundToInt()
 
         region.set(left, top, right, bottom)
 
@@ -3685,10 +3704,10 @@
                 nodes[virtualViewId] = SemanticsNodeWithAdjustedBounds(
                     currentNode,
                     android.graphics.Rect(
-                        boundsForFakeNode.left.roundToInt(),
-                        boundsForFakeNode.top.roundToInt(),
-                        boundsForFakeNode.right.roundToInt(),
-                        boundsForFakeNode.bottom.roundToInt(),
+                        boundsForFakeNode.left.fastRoundToInt(),
+                        boundsForFakeNode.top.fastRoundToInt(),
+                        boundsForFakeNode.right.fastRoundToInt(),
+                        boundsForFakeNode.bottom.fastRoundToInt(),
                     )
                 )
             } else if (virtualViewId == AccessibilityNodeProviderCompat.HOST_VIEW_ID) {
@@ -3776,4 +3795,4 @@
 @get:ExperimentalComposeUiApi
 @set:ExperimentalComposeUiApi
 @ExperimentalComposeUiApi
-var DisableContentCapture: Boolean by mutableStateOf(false)
+var DisableContentCapture: Boolean = false
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt
index 13310cc..7f15fef 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt
@@ -32,7 +32,7 @@
 import androidx.compose.ui.graphics.asAndroidPath
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.LayoutDirection
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * Resolves the [AndroidOutline] from the [Shape] of an [OwnedLayer].
@@ -296,10 +296,10 @@
         rectTopLeft = Offset(rect.left, rect.top)
         rectSize = Size(rect.width, rect.height)
         cachedOutline.setRect(
-            rect.left.roundToInt(),
-            rect.top.roundToInt(),
-            rect.right.roundToInt(),
-            rect.bottom.roundToInt()
+            rect.left.fastRoundToInt(),
+            rect.top.fastRoundToInt(),
+            rect.right.fastRoundToInt(),
+            rect.bottom.fastRoundToInt()
         )
     }
 
@@ -309,10 +309,10 @@
         rectSize = Size(roundRect.width, roundRect.height)
         if (roundRect.isSimple) {
             cachedOutline.setRoundRect(
-                roundRect.left.roundToInt(),
-                roundRect.top.roundToInt(),
-                roundRect.right.roundToInt(),
-                roundRect.bottom.roundToInt(),
+                roundRect.left.fastRoundToInt(),
+                roundRect.top.fastRoundToInt(),
+                roundRect.right.fastRoundToInt(),
+                roundRect.bottom.fastRoundToInt(),
                 radius
             )
             roundedCornerRadius = radius
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
index b3f0880..4ef0d8d 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
@@ -504,7 +504,7 @@
         ImeAction.Done -> EditorInfo.IME_ACTION_DONE
         else -> error("invalid ImeAction")
     }
-    (imeOptions.platformImeOptions as? AndroidImeOptions)?.privateImeOptions?.let {
+    imeOptions.platformImeOptions?.privateImeOptions?.let {
         privateImeOptions = it
     }
     when (imeOptions.keyboardType) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
index 12dd53e..a6edb36 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
@@ -56,6 +56,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Velocity
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.core.view.NestedScrollingParent3
 import androidx.core.view.NestedScrollingParentHelper
 import androidx.core.view.ViewCompat
@@ -63,7 +64,6 @@
 import androidx.lifecycle.setViewTreeLifecycleOwner
 import androidx.savedstate.SavedStateRegistryOwner
 import androidx.savedstate.setViewTreeSavedStateRegistryOwner
-import kotlin.math.roundToInt
 import kotlinx.coroutines.launch
 
 /**
@@ -593,8 +593,8 @@
 
 private fun View.layoutAccordingTo(layoutNode: LayoutNode) {
     val position = layoutNode.coordinates.positionInRoot()
-    val x = position.x.roundToInt()
-    val y = position.y.roundToInt()
+    val x = position.x.fastRoundToInt()
+    val y = position.y.fastRoundToInt()
     layout(x, y, x + measuredWidth, y + measuredHeight)
 }
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidDialog.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidDialog.android.kt
index 1ecf799..352e3ec 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidDialog.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidDialog.android.kt
@@ -57,6 +57,7 @@
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.util.fastMaxBy
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.core.view.WindowCompat
 import androidx.lifecycle.findViewTreeLifecycleOwner
 import androidx.lifecycle.findViewTreeViewModelStoreOwner
@@ -65,7 +66,6 @@
 import androidx.savedstate.findViewTreeSavedStateRegistryOwner
 import androidx.savedstate.setViewTreeSavedStateRegistryOwner
 import java.util.UUID
-import kotlin.math.roundToInt
 
 /**
  * Properties used to customize the behavior of a [Dialog].
@@ -256,13 +256,13 @@
     private val displayWidth: Int
         get() {
             val density = context.resources.displayMetrics.density
-            return (context.resources.configuration.screenWidthDp * density).roundToInt()
+            return (context.resources.configuration.screenWidthDp * density).fastRoundToInt()
         }
 
     private val displayHeight: Int
         get() {
             val density = context.resources.displayMetrics.density
-            return (context.resources.configuration.screenHeightDp * density).roundToInt()
+            return (context.resources.configuration.screenHeightDp * density).fastRoundToInt()
         }
 
     @Composable
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
index 8bc882e..8379852 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
@@ -76,6 +76,7 @@
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastMap
+import androidx.compose.ui.util.fastRoundToInt
 import androidx.lifecycle.findViewTreeLifecycleOwner
 import androidx.lifecycle.findViewTreeViewModelStoreOwner
 import androidx.lifecycle.setViewTreeLifecycleOwner
@@ -83,7 +84,6 @@
 import androidx.savedstate.findViewTreeSavedStateRegistryOwner
 import androidx.savedstate.setViewTreeSavedStateRegistryOwner
 import java.util.UUID
-import kotlin.math.roundToInt
 import kotlinx.coroutines.isActive
 import org.jetbrains.annotations.TestOnly
 
@@ -517,13 +517,13 @@
     private val displayWidth: Int
         get() {
             val density = context.resources.displayMetrics.density
-            return (context.resources.configuration.screenWidthDp * density).roundToInt()
+            return (context.resources.configuration.screenWidthDp * density).fastRoundToInt()
         }
 
     private val displayHeight: Int
         get() {
             val density = context.resources.displayMetrics.density
-            return (context.resources.configuration.screenHeightDp * density).roundToInt()
+            return (context.resources.configuration.screenHeightDp * density).fastRoundToInt()
         }
 
     /**
@@ -654,7 +654,7 @@
         val layoutSize = coordinates.size
 
         val position = coordinates.positionInWindow()
-        val layoutPosition = IntOffset(position.x.roundToInt(), position.y.roundToInt())
+        val layoutPosition = IntOffset(position.x.fastRoundToInt(), position.y.fastRoundToInt())
 
         val newParentBounds = IntRect(layoutPosition, layoutSize)
         if (newParentBounds != parentBounds) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Alignment.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Alignment.kt
index 0a56eb3..94e2368 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Alignment.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Alignment.kt
@@ -21,7 +21,7 @@
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 /**
  * An interface to calculate the position of a sized box inside an available space. [Alignment] is
@@ -171,7 +171,7 @@
 
         val x = centerX * (1 + resolvedHorizontalBias)
         val y = centerY * (1 + verticalBias)
-        return IntOffset(x.roundToInt(), y.roundToInt())
+        return IntOffset(x.fastRoundToInt(), y.fastRoundToInt())
     }
 
     /**
@@ -191,7 +191,7 @@
             // calculating the new positions
             val center = (space - size).toFloat() / 2f
             val resolvedBias = if (layoutDirection == LayoutDirection.Ltr) bias else -1 * bias
-            return (center * (1 + resolvedBias)).roundToInt()
+            return (center * (1 + resolvedBias)).fastRoundToInt()
         }
     }
 
@@ -210,7 +210,7 @@
             // Convert to Px first and only round at the end, to avoid rounding twice while
             // calculating the new positions
             val center = (space - size).toFloat() / 2f
-            return (center * (1 + bias)).roundToInt()
+            return (center * (1 + bias)).fastRoundToInt()
         }
     }
 }
@@ -243,7 +243,7 @@
 
         val x = centerX * (1 + horizontalBias)
         val y = centerY * (1 + verticalBias)
-        return IntOffset(x.roundToInt(), y.roundToInt())
+        return IntOffset(x.fastRoundToInt(), y.fastRoundToInt())
     }
 
     /**
@@ -266,7 +266,7 @@
             // Convert to Px first and only round at the end, to avoid rounding twice while
             // calculating the new positions
             val center = (space - size).toFloat() / 2f
-            return (center * (1 + bias)).roundToInt()
+            return (center * (1 + bias)).fastRoundToInt()
         }
     }
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt
index f251943..e9a8947 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt
@@ -43,8 +43,8 @@
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.constrainHeight
 import androidx.compose.ui.unit.constrainWidth
+import androidx.compose.ui.util.fastRoundToInt
 import kotlin.math.max
-import kotlin.math.roundToInt
 
 /**
  * Paint the content using [painter].
@@ -269,14 +269,14 @@
         val intrinsicSize = painter.intrinsicSize
         val intrinsicWidth =
             if (intrinsicSize.hasSpecifiedAndFiniteWidth()) {
-                intrinsicSize.width.roundToInt()
+                intrinsicSize.width.fastRoundToInt()
             } else {
                 constraints.minWidth
             }
 
         val intrinsicHeight =
             if (intrinsicSize.hasSpecifiedAndFiniteHeight()) {
-                intrinsicSize.height.roundToInt()
+                intrinsicSize.height.fastRoundToInt()
             } else {
                 constraints.minHeight
             }
@@ -295,8 +295,8 @@
         // In this case the larger of the 2 dimensions is used and the aspect ratio is
         // maintained. Even if the size of the composable is smaller, the painter will
         // draw its content clipped
-        val minWidth = constraints.constrainWidth(scaledSize.width.roundToInt())
-        val minHeight = constraints.constrainHeight(scaledSize.height.roundToInt())
+        val minWidth = constraints.constrainWidth(scaledSize.width.fastRoundToInt())
+        val minHeight = constraints.constrainHeight(scaledSize.height.fastRoundToInt())
         return constraints.copy(minWidth = minWidth, minHeight = minHeight)
     }
 
@@ -325,8 +325,8 @@
         }
 
         val alignedPosition = alignment.align(
-            IntSize(scaledSize.width.roundToInt(), scaledSize.height.roundToInt()),
-            IntSize(size.width.roundToInt(), size.height.roundToInt()),
+            IntSize(scaledSize.width.fastRoundToInt(), scaledSize.height.fastRoundToInt()),
+            IntSize(size.width.fastRoundToInt(), size.height.fastRoundToInt()),
             layoutDirection
         )
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt
index 9843404f..c80645c 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt
@@ -26,7 +26,8 @@
  * onApplyChangesListener when nodes are scheduled for invalidation.
  */
 internal class FocusInvalidationManager(
-    private val onRequestApplyChangesListener: (() -> Unit) -> Unit
+    private val onRequestApplyChangesListener: (() -> Unit) -> Unit,
+    private val invalidateOwnerFocusState: () -> Unit
 ) {
     private var focusTargetNodes = mutableSetOf<FocusTargetNode>()
     private var focusEventNodes = mutableSetOf<FocusEventModifierNode>()
@@ -138,6 +139,8 @@
         focusTargetNodes.clear()
         focusTargetsWithInvalidatedFocusEvents.clear()
 
+        invalidateOwnerFocusState()
+
          check(focusPropertiesNodes.isEmpty()) { "Unprocessed FocusProperties nodes" }
          check(focusEventNodes.isEmpty()) { "Unprocessed FocusEvent nodes" }
          check(focusTargetNodes.isEmpty()) { "Unprocessed FocusTarget nodes" }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwner.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwner.kt
index 39a0722..f50a0ef 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwner.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwner.kt
@@ -20,7 +20,6 @@
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.input.key.KeyEvent
 import androidx.compose.ui.input.rotary.RotaryScrollEvent
-import androidx.compose.ui.unit.LayoutDirection
 
 /**
  * The focus owner provides some internal APIs that are not exposed by focus manager.
@@ -34,11 +33,6 @@
     val modifier: Modifier
 
     /**
-     * The owner sets the layoutDirection that is then used during focus search.
-     */
-    var layoutDirection: LayoutDirection
-
-    /**
      * This manager provides a way to ensure that only one focus transaction is running at a time.
      * We use this to prevent re-entrant focus operations. Starting a new transaction automatically
      * cancels the previous transaction and reverts any focus state changes made during that
@@ -47,12 +41,52 @@
     val focusTransactionManager: FocusTransactionManager
 
     /**
+     * This function is called to ask the owner to request focus from the framework.
+     * eg. If a composable calls requestFocus and the root view does not have focus, this function
+     * can be used to request focus for the view.
+     *
+     * @param focusDirection If this focus request was triggered by a call to moveFocus or using the
+     * keyboard, provide the owner with the direction of focus change.
+     *
+     * @param previouslyFocusedRect The bounds of the currently focused item.
+     *
+     * @return true if the owner successfully requested focus from the framework. False otherwise.
+     */
+    fun requestFocusForOwner(focusDirection: FocusDirection?, previouslyFocusedRect: Rect?): Boolean
+
+    /**
+     * This function searches the compose hierarchy for the next focus target based on the supplied
+     * parameters.
+     *
+     * @param focusDirection the direction to search for the focus target.
+     *
+     * @param focusedRect the bounds of the currently focused item.
+     *
+     * @param onFound This lambda is called with the focus search result.
+     *
+     * @return true, if a suitable [FocusTargetNode] was found, false if no [FocusTargetNode] was
+     * found, and null if the focus search was cancelled.
+     */
+    fun focusSearch(
+        focusDirection: FocusDirection,
+        focusedRect: Rect?,
+        onFound: (FocusTargetNode) -> Boolean
+    ): Boolean?
+
+    /**
      * The [Owner][androidx.compose.ui.node.Owner] calls this function when it gains focus. This
      * informs the [focus manager][FocusOwnerImpl] that the
      * [Owner][androidx.compose.ui.node.Owner] gained focus, and that it should propagate this
      * focus to one of the focus modifiers in the component hierarchy.
+     *
+     * @param focusDirection the direction to search for the focus target.
+     *
+     * @param previouslyFocusedRect the bounds of the currently focused item.
+     *
+     * @return true, if a suitable [FocusTargetNode] was found and it took focus, false if no
+     * [FocusTargetNode] was found or if the focus search was cancelled.
      */
-    fun takeFocus()
+    fun takeFocus(focusDirection: FocusDirection, previouslyFocusedRect: Rect?): Boolean
 
     /**
      * The [Owner][androidx.compose.ui.node.Owner] calls this function when it loses focus. This
@@ -71,10 +105,13 @@
      * @param refreshFocusEvents: Whether we should send an event up the hierarchy to update
      * the associated onFocusEvent nodes.
      *
+     * @param clearOwnerFocus whether we should also clear focus from the owner. This is usually
+     * true, unless focus is being temporarily cleared (eg. to implement focus wrapping).
+     *
      * This could be used to clear focus when a user clicks on empty space outside a focusable
      * component.
      */
-    fun clearFocus(force: Boolean, refreshFocusEvents: Boolean)
+    fun clearFocus(force: Boolean, refreshFocusEvents: Boolean, clearOwnerFocus: Boolean)
 
     /**
      * Searches for the currently focused item, and returns its coordinates as a rect.
@@ -110,4 +147,9 @@
      * Schedule a FocusProperties node to be invalidated after onApplyChanges.
      */
     fun scheduleInvalidation(node: FocusPropertiesModifierNode)
+
+    /**
+     * The focus state of the root focus node.
+     */
+    val rootState: FocusState
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt
index 0a7515b..c9e4fcf 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusOwnerImpl.kt
@@ -28,10 +28,6 @@
 import androidx.compose.ui.focus.FocusDirection.Companion.Previous
 import androidx.compose.ui.focus.FocusRequester.Companion.Cancel
 import androidx.compose.ui.focus.FocusRequester.Companion.Default
-import androidx.compose.ui.focus.FocusStateImpl.Active
-import androidx.compose.ui.focus.FocusStateImpl.ActiveParent
-import androidx.compose.ui.focus.FocusStateImpl.Captured
-import androidx.compose.ui.focus.FocusStateImpl.Inactive
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.input.key.KeyEvent
 import androidx.compose.ui.input.key.KeyEventType.Companion.KeyDown
@@ -56,11 +52,20 @@
  * The focus manager is used by different [Owner][androidx.compose.ui.node.Owner] implementations
  * to control focus.
  */
-internal class FocusOwnerImpl(onRequestApplyChangesListener: (() -> Unit) -> Unit) : FocusOwner {
+internal class FocusOwnerImpl(
+    onRequestApplyChangesListener: (() -> Unit) -> Unit,
+    private val onRequestFocusForOwner:
+        (focusDirection: FocusDirection?, previouslyFocusedRect: Rect?) -> Boolean,
+    private val onClearFocusForOwner: () -> Unit,
+    private val layoutDirection: (() -> LayoutDirection)
+) : FocusOwner {
 
     internal var rootFocusNode = FocusTargetNode()
 
-    private val focusInvalidationManager = FocusInvalidationManager(onRequestApplyChangesListener)
+    private val focusInvalidationManager = FocusInvalidationManager(
+        onRequestApplyChangesListener,
+        ::invalidateOwnerFocusState
+    )
 
     override val focusTransactionManager: FocusTransactionManager = FocusTransactionManager()
 
@@ -69,21 +74,38 @@
      * list that contains the modifiers required by the focus system. (Eg, a root focus modifier).
      */
     // TODO(b/168831247): return an empty Modifier when there are no focusable children.
-    override val modifier: Modifier = object : ModifierNodeElement<FocusTargetNode>() {
-        override fun create() = rootFocusNode
+    override val modifier: Modifier = Modifier
+        // The root focus target is not focusable, and acts like a focus group.
+        //  We could save an allocation here by making FocusTargetNode implement
+        //  FocusPropertiesModifierNode but to do that we would have to allocate
+        //  a focus properties object. This way only the root node has this extra allocation.
+        .focusProperties { canFocus = false }
+        .then(
+            object : ModifierNodeElement<FocusTargetNode>() {
+                override fun create() = rootFocusNode
+                override fun update(node: FocusTargetNode) {}
+                override fun InspectorInfo.inspectableProperties() { name = "RootFocusTarget" }
+                override fun hashCode(): Int = rootFocusNode.hashCode()
+                override fun equals(other: Any?) = other === this
+            }
+        )
 
-        override fun update(node: FocusTargetNode) {}
-
-        override fun InspectorInfo.inspectableProperties() {
-            name = "RootFocusTarget"
-        }
-
-        override fun hashCode(): Int = rootFocusNode.hashCode()
-
-        override fun equals(other: Any?) = other === this
-    }
-
-    override lateinit var layoutDirection: LayoutDirection
+    /**
+     * This function is called to ask the owner to request focus from the framework.
+     * eg. If a composable calls requestFocus and the root view does not have focus, this function
+     * can be used to request focus for the view.
+     *
+     * @param focusDirection If this focus request was triggered by a call to moveFocus or using the
+     * keyboard, provide the owner with the direction of focus change.
+     *
+     * @param previouslyFocusedRect The bounds of the currently focused item.
+     *
+     * @return true if the owner successfully requested focus from the framework. False otherwise.
+     */
+    override fun requestFocusForOwner(
+        focusDirection: FocusDirection?,
+        previouslyFocusedRect: Rect?
+    ): Boolean = onRequestFocusForOwner(focusDirection, previouslyFocusedRect)
 
     /**
      * Keeps track of which keys have received DOWN events without UP events – i.e. which keys are
@@ -99,14 +121,19 @@
      * informs the [focus manager][FocusOwnerImpl] that the
      * [Owner][androidx.compose.ui.node.Owner] gained focus, and that it should propagate this
      * focus to one of the focus modifiers in the component hierarchy.
+     *
+     * @param focusDirection the direction to search for the focus target.
+     *
+     * @param previouslyFocusedRect the bounds of the currently focused item.
+     *
+     * @return true, if a suitable [FocusTargetNode] was found and it took focus, false if no
+     * [FocusTargetNode] was found or if the focus search was cancelled.
      */
-    override fun takeFocus() {
-        // If the focus state is not Inactive, it indicates that the focus state is already
-        // set (possibly by dispatchWindowFocusChanged). So we don't update the state.
-        if (rootFocusNode.focusState == Inactive) {
-            rootFocusNode.focusState = Active
-            // TODO(b/152535715): propagate focus to children based on child focusability.
-            //  moveFocus(FocusDirection.Enter)
+    override fun takeFocus(focusDirection: FocusDirection, previouslyFocusedRect: Rect?): Boolean {
+        return focusTransactionManager.withExistingTransaction {
+            focusSearch(focusDirection, previouslyFocusedRect) {
+                it.requestFocus(focusDirection) ?: false
+            } ?: false
         }
     }
 
@@ -117,7 +144,9 @@
      * all the focus modifiers in the component hierarchy.
      */
     override fun releaseFocus() {
-        rootFocusNode.clearFocus(forced = true, refreshFocusEvents = true)
+        focusTransactionManager.withExistingTransaction {
+            rootFocusNode.clearFocus(forced = true, refreshFocusEvents = true)
+        }
     }
 
     /**
@@ -130,30 +159,26 @@
      * component.
      */
     override fun clearFocus(force: Boolean) {
-        clearFocus(force, refreshFocusEvents = true)
+        clearFocus(force, refreshFocusEvents = true, clearOwnerFocus = true)
     }
 
     @OptIn(ExperimentalComposeUiApi::class)
-    override fun clearFocus(force: Boolean, refreshFocusEvents: Boolean) {
-        focusTransactionManager.withNewTransaction {
+    override fun clearFocus(force: Boolean, refreshFocusEvents: Boolean, clearOwnerFocus: Boolean) {
+        val clearedFocusSuccessfully = focusTransactionManager.withNewTransaction(
+            onCancelled = { return@withNewTransaction }
+        ) {
             // Don't clear focus if an item on the focused path has a custom exit specified.
             if (!force) {
                 when (rootFocusNode.performCustomClearFocus(Exit)) {
-                    Redirected, Cancelled, RedirectCancelled -> return
+                    Redirected, Cancelled, RedirectCancelled -> return@withNewTransaction false
                     None -> { /* Do nothing. */ }
                 }
             }
+            return@withNewTransaction rootFocusNode.clearFocus(force, refreshFocusEvents)
+        }
 
-            // If this hierarchy had focus before clearing it, it indicates that the host view has
-            // focus. So after clearing focus within the compose hierarchy, we should restore focus
-            // to the root focus modifier to maintain consistency with the host view.
-            val rootInitialState = rootFocusNode.focusState
-            if (rootFocusNode.clearFocus(force, refreshFocusEvents)) {
-                rootFocusNode.focusState = when (rootInitialState) {
-                    Active, ActiveParent, Captured -> Active
-                    Inactive -> Inactive
-                }
-            }
+        if (clearedFocusSuccessfully && clearOwnerFocus) {
+            onClearFocusForOwner.invoke()
         }
     }
 
@@ -162,38 +187,45 @@
      *
      * @return true if focus was moved successfully. false if the focused item is unchanged.
      */
-    @OptIn(ExperimentalComposeUiApi::class)
     override fun moveFocus(focusDirection: FocusDirection): Boolean {
+        // moveFocus is an API that was added to compose, but isn't available in the classic view
+        // system, so for now we only search among compose items and don't support moveFocus for
+        // interop scenarios.
+        val movedFocus = focusSearch(focusDirection, null) {
+            it.requestFocus(focusDirection) ?: false
+        } ?: return false
 
-        // If there is no active node in this sub-hierarchy, we can't move focus.
-        val source = rootFocusNode.findActiveFocusNode() ?: return false
+        // To wrap focus around, we clear focus and request initial focus.
+        if (!movedFocus && focusDirection.supportsWrapAroundFocus()) {
+            clearFocus(force = false, refreshFocusEvents = true, clearOwnerFocus = false)
+            return takeFocus(focusDirection, previouslyFocusedRect = null)
+        }
 
-        // Check if a custom focus traversal order is specified.
-        source.customFocusSearch(focusDirection, layoutDirection).also {
-            if (it !== Default) {
-                return it !== Cancel && it.focus()
+        return movedFocus
+    }
+
+    override fun focusSearch(
+        focusDirection: FocusDirection,
+        focusedRect: Rect?,
+        onFound: (FocusTargetNode) -> Boolean
+    ): Boolean? {
+        val source = rootFocusNode.findActiveFocusNode()?.also {
+            // Check if a custom focus traversal order is specified.
+            when (val customDestination = it.customFocusSearch(focusDirection, layoutDirection())) {
+                @OptIn(ExperimentalComposeUiApi::class)
+                Cancel -> return null
+                Default -> { /* Do Nothing */ }
+                else -> return customDestination.findFocusTargetNode(onFound)
             }
         }
 
-        var isCancelled = false
-        val foundNextItem =
-            rootFocusNode.focusSearch(focusDirection, layoutDirection) { destination ->
-                if (destination == source) return@focusSearch false
-                checkNotNull(destination.nearestAncestor(Nodes.FocusTarget)) {
-                    "Focus search landed at the root."
-                }
-                // If we found a potential next item, move focus to it.
-                // Returning true ends focus search.
-                focusTransactionManager.withNewTransaction {
-                    when (destination.performCustomRequestFocus(focusDirection)) {
-                        Redirected -> true
-                        Cancelled, RedirectCancelled -> { isCancelled = true; true }
-                        None -> destination.performRequestFocus()
-                    }
-                }
+        return rootFocusNode.focusSearch(focusDirection, layoutDirection(), focusedRect) {
+            when (it) {
+                source -> false
+                rootFocusNode -> error("Focus search landed at the root.")
+                else -> onFound(it)
             }
-        // If we didn't find a potential next item, try to wrap around.
-        return !isCancelled && (foundNextItem || wrapAroundFocus(focusDirection))
+        }
     }
 
     /**
@@ -207,11 +239,9 @@
         if (!validateKeyEvent(keyEvent)) return false
 
         val activeFocusTarget = rootFocusNode.findActiveFocusNode()
-        checkNotNull(activeFocusTarget) {
-            "Event can't be processed because we do not have an active focus target."
-        }
-        val focusedKeyInputNode = activeFocusTarget.lastLocalKeyInputNode()
-            ?: activeFocusTarget.nearestAncestor(Nodes.KeyInput)?.node
+        val focusedKeyInputNode = activeFocusTarget?.lastLocalKeyInputNode()
+            ?: activeFocusTarget?.nearestAncestor(Nodes.KeyInput)?.node
+            ?: rootFocusNode.nearestAncestor(Nodes.KeyInput)?.node
 
         focusedKeyInputNode?.traverseAncestors(
             type = Nodes.KeyInput,
@@ -270,6 +300,18 @@
         focusInvalidationManager.scheduleInvalidation(node)
     }
 
+    /**
+     * At the end of the invalidations, we need to ensure that the focus system is in a valid state.
+     */
+    private fun invalidateOwnerFocusState() {
+        // If an active item is removed, we currently clear focus from the hierarchy. We don't
+        // clear focus from the root because that could cause initial focus logic to be re-run.
+        // Now that all the invalidations are complete, we run owner.clearFocus() if needed.
+        if (rootFocusNode.focusState == FocusStateImpl.Inactive) {
+            onClearFocusForOwner()
+        }
+    }
+
     private inline fun <reified T : DelegatableNode> DelegatableNode.traverseAncestors(
         type: NodeKind<T>,
         onPreVisit: (T) -> Unit,
@@ -289,6 +331,9 @@
         return rootFocusNode.findActiveFocusNode()?.focusRect()
     }
 
+    override val rootState: FocusState
+        get() = rootFocusNode.focusState
+
     private fun DelegatableNode.lastLocalKeyInputNode(): Modifier.Node? {
         var focusedKeyInputNode: Modifier.Node? = null
         visitLocalDescendants(Nodes.FocusTarget or Nodes.KeyInput) { modifierNode ->
@@ -299,26 +344,13 @@
         return focusedKeyInputNode
     }
 
-    // TODO(b/144116848): This is a hack to make Next/Previous wrap around. This must be
-    //  replaced by code that sends the move request back to the view system. The view system
-    //  will then pass focus to other views, and ultimately return back to this compose view.
-    private fun wrapAroundFocus(focusDirection: FocusDirection): Boolean {
-        // Wrap is not supported when this sub-hierarchy doesn't have focus.
-        if (!rootFocusNode.focusState.hasFocus || rootFocusNode.focusState.isFocused) return false
-
-        // Next and Previous wraps around.
-        when (focusDirection) {
-            Next, Previous -> {
-                // Clear Focus to send focus the root node.
-                clearFocus(force = false)
-                if (!rootFocusNode.focusState.isFocused) return false
-
-                // Wrap around by calling moveFocus after the root gains focus.
-                return moveFocus(focusDirection)
-            }
-            // We only wrap-around for 1D Focus search.
-            else -> return false
-        }
+    /**
+     * focus search in the Android framework wraps around for 1D focus search, but not for 2D focus
+     * search. This is a helper function that can be used to determine whether we should wrap around.
+     */
+    private fun FocusDirection.supportsWrapAroundFocus(): Boolean = when (this) {
+        Next, Previous -> true
+        else -> false
     }
 
     // TODO(b/307580000) Factor this out into a class to manage key inputs.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequester.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequester.kt
index 97d7357..8c11a94 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequester.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequester.kt
@@ -24,7 +24,6 @@
 import androidx.compose.ui.node.Nodes
 import androidx.compose.ui.node.visitChildren
 
-@Suppress("ConstPropertyName")
 private const val FocusRequesterNotInitialized = """
    FocusRequester is not initialized. Here are some possible fixes:
 
@@ -34,7 +33,6 @@
    response to some event. Eg Modifier.clickable { focusRequester.requestFocus() }
 """
 
-@Suppress("ConstPropertyName")
 private const val InvalidFocusRequesterInvocation = """
     Please check whether the focusRequester is FocusRequester.Cancel or FocusRequester.Default
     before invoking any functions on the focusRequester.
@@ -66,16 +64,15 @@
     }
 
     // TODO(b/245755256): Consider making this API Public.
-    internal fun focus(): Boolean {
+    internal fun focus(): Boolean = findFocusTargetNode { it.requestFocus() }
+
+    internal fun findFocusTargetNode(onFound: (FocusTargetNode) -> Boolean): Boolean {
         @OptIn(ExperimentalComposeUiApi::class)
         return findFocusTarget { focusTarget ->
-            val focusProperties = focusTarget.fetchFocusProperties()
-            if (focusProperties.canFocus) {
-                focusTarget.requestFocus()
+            if (focusTarget.fetchFocusProperties().canFocus) {
+                onFound(focusTarget)
             } else {
-                focusTarget.findChildCorrespondingToFocusEnter(Enter) {
-                    it.requestFocus()
-                }
+                focusTarget.findChildCorrespondingToFocusEnter(Enter, onFound)
             }
         }
     }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequesterModifierNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequesterModifierNode.kt
index 4d95db3..cb36d0e 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequesterModifierNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequesterModifierNode.kt
@@ -38,8 +38,7 @@
 @OptIn(ExperimentalComposeUiApi::class)
 fun FocusRequesterModifierNode.requestFocus(): Boolean {
     visitSelfAndChildren(Nodes.FocusTarget) { focusTarget ->
-        val focusProperties = focusTarget.fetchFocusProperties()
-        return if (focusProperties.canFocus) {
+        return if (focusTarget.fetchFocusProperties().canFocus) {
             focusTarget.requestFocus()
         } else {
             focusTarget.findChildCorrespondingToFocusEnter(Enter) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt
index ea6ba20..489b51e 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTargetNode.kt
@@ -84,13 +84,22 @@
             // Clear focus from the current FocusTarget.
             // This currently clears focus from the entire hierarchy, but we can change the
             // implementation so that focus is sent to the immediate focus parent.
-            Active, Captured -> requireOwner().focusOwner.clearFocus(force = true)
-
-            // If an ActiveParent is deactivated, the entire subtree containing focus is
-            // deactivated, which means the Active node will also receive an onReset() call.
-            // This triggers a clearFocus call, which will notify all the focus event nodes
-            // associated with this FocusTargetNode.
-            ActiveParent, Inactive -> {}
+            Active, Captured -> {
+                requireOwner().focusOwner.clearFocus(
+                    force = true,
+                    refreshFocusEvents = true,
+                    clearOwnerFocus = false
+                )
+                // We don't clear the owner's focus yet, because this could trigger an initial
+                // focus scenario after the focus is cleared. Instead, we schedule invalidation
+                // after onApplyChanges. The FocusInvalidationManager contains the invalidation
+                // logic and calls clearFocus() on the owner after all the nodes in the hierarchy
+                // are invalidated.
+                invalidateFocusTarget()
+            }
+            // This node might be reused, so reset the state to Inactive.
+            ActiveParent -> requireTransactionManager().withNewTransaction { focusState = Inactive }
+            Inactive -> {}
         }
         // This node might be reused, so we reset its state.
         committedFocusState = null
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTransactions.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTransactions.kt
index 88cc1ee..d585d28 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTransactions.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTransactions.kt
@@ -30,6 +30,7 @@
 import androidx.compose.ui.node.Nodes.FocusTarget
 import androidx.compose.ui.node.nearestAncestor
 import androidx.compose.ui.node.observeReads
+import androidx.compose.ui.node.requireOwner
 
 /**
  * Request focus for this node.
@@ -39,12 +40,14 @@
  * [FocusNode][FocusTargetNode]'s parent [FocusNode][FocusTargetNode].
  */
 @OptIn(ExperimentalComposeUiApi::class)
-internal fun FocusTargetNode.requestFocus(): Boolean {
+internal fun FocusTargetNode.requestFocus(): Boolean = requestFocus(Enter) ?: false
+
+internal fun FocusTargetNode.requestFocus(focusDirection: FocusDirection): Boolean? {
     return requireTransactionManager().withNewTransaction {
-        when (performCustomRequestFocus(Enter)) {
+        when (performCustomRequestFocus(focusDirection)) {
             None -> performRequestFocus()
             Redirected -> true
-            Cancelled, RedirectCancelled -> false
+            Cancelled, RedirectCancelled -> null
         }
     }
 }
@@ -244,7 +247,7 @@
 }
 
 private fun FocusTargetNode.requestFocusForOwner(): Boolean {
-    return coordinator?.layoutNode?.owner?.requestFocus() ?: error("Owner not initialized.")
+    return requireOwner().focusOwner.requestFocusForOwner(null, null)
 }
 
 private fun FocusTargetNode.requireActiveChild(): FocusTargetNode {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTraversal.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTraversal.kt
index e0f38c5..7660e54 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTraversal.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusTraversal.kt
@@ -91,6 +91,7 @@
  *
  * @param focusDirection The requested direction to move focus.
  * @param layoutDirection Whether the layout is RTL or LTR.
+ * @param previouslyFocusedRect The bounds of the previously focused item.
  * @param onFound This lambda is invoked if focus search finds the next focus node.
  * @return if no focus node is found, we return false. If we receive a cancel, we return null
  * otherwise we return the result of [onFound].
@@ -99,16 +100,19 @@
 internal fun FocusTargetNode.focusSearch(
     focusDirection: FocusDirection,
     layoutDirection: LayoutDirection,
+    previouslyFocusedRect: Rect?,
     onFound: (FocusTargetNode) -> Boolean
-): Boolean {
+): Boolean? {
     return when (focusDirection) {
         Next, Previous -> oneDimensionalFocusSearch(focusDirection, onFound)
-        Left, Right, Up, Down -> twoDimensionalFocusSearch(focusDirection, onFound) ?: false
+        Left, Right, Up, Down ->
+            twoDimensionalFocusSearch(focusDirection, previouslyFocusedRect, onFound)
         @OptIn(ExperimentalComposeUiApi::class)
         Enter -> {
             // we search among the children of the active item.
             val direction = when (layoutDirection) { Rtl -> Left; Ltr -> Right }
-            findActiveFocusNode()?.twoDimensionalFocusSearch(direction, onFound) ?: false
+            findActiveFocusNode()
+                ?.twoDimensionalFocusSearch(direction, previouslyFocusedRect, onFound)
         }
         @OptIn(ExperimentalComposeUiApi::class)
         Exit -> findActiveFocusNode()?.findNonDeactivatedParent().let {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
index 987cc9a..d883a49 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
@@ -51,10 +51,17 @@
  */
 internal fun FocusTargetNode.twoDimensionalFocusSearch(
     direction: FocusDirection,
+    previouslyFocusedRect: Rect?,
     onFound: (FocusTargetNode) -> Boolean
 ): Boolean? {
     when (focusState) {
-        Inactive -> return if (fetchFocusProperties().canFocus) onFound.invoke(this) else false
+        Inactive -> return if (fetchFocusProperties().canFocus) {
+            onFound.invoke(this)
+        } else if (previouslyFocusedRect == null) {
+            findChildCorrespondingToFocusEnter(direction, onFound)
+        } else {
+            searchChildren(previouslyFocusedRect, direction, onFound)
+        }
         ActiveParent -> {
             val focusedChild = activeChild ?: error(NoActiveChild)
             // For 2D focus search we only search among siblings. You have to use DPad Center or
@@ -66,15 +73,20 @@
 
                 ActiveParent -> {
                     // If the focusedChild is an intermediate parent, we search among its children.
-                    val found = focusedChild.twoDimensionalFocusSearch(direction, onFound)
+                    val found = focusedChild
+                        .twoDimensionalFocusSearch(direction, previouslyFocusedRect, onFound)
                     if (found != false) return found
 
                     // We search among the siblings of the parent.
-                    return generateAndSearchChildren(focusedChild.activeNode(), direction, onFound)
+                    return generateAndSearchChildren(
+                        focusedChild.activeNode().focusRect(),
+                        direction,
+                        onFound
+                    )
                 }
                 // Search for the next eligible sibling.
                 Active, Captured ->
-                    return generateAndSearchChildren(focusedChild, direction, onFound)
+                    return generateAndSearchChildren(focusedChild.focusRect(), direction, onFound)
                 Inactive -> error(NoActiveChild)
             }
         }
@@ -132,7 +144,7 @@
 // Search among your children for the next child.
 // If the next child is not found, generate more children by requesting a beyondBoundsLayout.
 private fun FocusTargetNode.generateAndSearchChildren(
-    focusedItem: FocusTargetNode,
+    focusedItem: Rect,
     direction: FocusDirection,
     onFound: (FocusTargetNode) -> Boolean
 ): Boolean {
@@ -152,7 +164,7 @@
 }
 
 private fun FocusTargetNode.searchChildren(
-    focusedItem: FocusTargetNode,
+    focusedItem: Rect,
     direction: FocusDirection,
     onFound: (FocusTargetNode) -> Boolean
 ): Boolean {
@@ -162,7 +174,7 @@
         }
     }
     while (children.isNotEmpty()) {
-        val nextItem = children.findBestCandidate(focusedItem.focusRect(), direction)
+        val nextItem = children.findBestCandidate(focusedItem, direction)
             ?: return false
 
         // If the result is not deactivated, this is a valid next item.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
index 1b0994a..e792460 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
@@ -380,30 +380,35 @@
             val change = changes.valueAt(j)
 
             if (pointerIds.contains(keyValue)) {
-                // And translate their position relative to the parent coordinates, to give us a
-                // change local to the PointerInputFilter's coordinates
-                val historical = ArrayList<HistoricalChange>(change.historical.size)
-                change.historical.fastForEach {
-                    historical.add(
-                        HistoricalChange(
-                            it.uptimeMillis,
-                            coordinates!!.localPositionOf(parentCoordinates, it.position),
-                            it.originalEventPosition
-                        )
-                    )
-                }
+                val prevPosition = change.previousPosition
+                val currentPosition = change.position
 
-                relevantChanges.put(keyValue, change.copy(
-                    previousPosition = coordinates!!.localPositionOf(
-                        parentCoordinates,
-                        change.previousPosition
-                    ),
-                    currentPosition = coordinates!!.localPositionOf(
-                        parentCoordinates,
-                        change.position
-                    ),
-                    historical = historical
-                ))
+                if (prevPosition.isValid() && currentPosition.isValid()) {
+                    // And translate their position relative to the parent coordinates, to give us a
+                    // change local to the PointerInputFilter's coordinates
+                    val historical = ArrayList<HistoricalChange>(change.historical.size)
+                    change.historical.fastForEach {
+                        historical.add(
+                            HistoricalChange(
+                                it.uptimeMillis,
+                                coordinates!!.localPositionOf(parentCoordinates, it.position),
+                                it.originalEventPosition
+                            )
+                        )
+                    }
+
+                    relevantChanges.put(keyValue, change.copy(
+                        previousPosition = coordinates!!.localPositionOf(
+                            parentCoordinates,
+                            prevPosition
+                        ),
+                        currentPosition = coordinates!!.localPositionOf(
+                            parentCoordinates,
+                            currentPosition
+                        ),
+                        historical = historical
+                    ))
+                }
             }
         }
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
index 223a4012..9df114d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
@@ -64,7 +64,6 @@
 /**
  * Enable to log changes to the LayoutNode tree.  This logging is quite chatty.
  */
-@Suppress("ConstPropertyName")
 private const val DebugChanges = false
 
 private val DefaultDensity = Density(1f)
@@ -1061,7 +1060,11 @@
     private fun invalidateFocusOnDetach() {
         nodes.tailToHead(FocusTarget) {
             if (it.focusState.isFocused) {
-                requireOwner().focusOwner.clearFocus(force = true, refreshFocusEvents = false)
+                requireOwner().focusOwner.clearFocus(
+                    force = true,
+                    refreshFocusEvents = false,
+                    clearOwnerFocus = true
+                )
                 it.scheduleInvalidationForFocusEvents()
             }
         }
@@ -1373,6 +1376,7 @@
         /**
          * Constant used by [placeOrder].
          */
+        @Suppress("ConstPropertyName")
         internal const val NotPlacedPlaceOrder = Int.MAX_VALUE
 
         /**
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeAlignmentLines.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeAlignmentLines.kt
index 98abd1b..a9ec09d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeAlignmentLines.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeAlignmentLines.kt
@@ -21,7 +21,7 @@
 import androidx.compose.ui.layout.HorizontalAlignmentLine
 import androidx.compose.ui.layout.merge
 import androidx.compose.ui.unit.toOffset
-import kotlin.math.roundToInt
+import androidx.compose.ui.util.fastRoundToInt
 
 internal sealed class AlignmentLines(val alignmentLinesOwner: AlignmentLinesOwner) {
     /**
@@ -131,11 +131,11 @@
             }
         }
 
-        val positionInContainer = if (alignmentLine is HorizontalAlignmentLine) {
-            position.y.roundToInt()
+        val positionInContainer = (if (alignmentLine is HorizontalAlignmentLine) {
+            position.y
         } else {
-            position.x.roundToInt()
-        }
+            position.x
+        }).fastRoundToInt()
         // If the line was already provided by a previous child, merge the values.
         alignmentLineMap[alignmentLine] = if (alignmentLine in alignmentLineMap) {
             alignmentLine.merge(
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
index 34ee53c3..4e6de06 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
@@ -1093,9 +1093,13 @@
 
     fun shouldSharePointerInputWithSiblings(): Boolean {
         val start = headNode(Nodes.PointerInput.includeSelfInTraversal) ?: return false
-        start.visitLocalDescendants(Nodes.PointerInput) {
-            if (it.sharePointerInputWithSiblings()) return true
+
+        if (start.isAttached) {
+            start.visitLocalDescendants(Nodes.PointerInput) {
+                if (it.sharePointerInputWithSiblings()) return true
+            }
         }
+
         return false
     }
 
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.desktop.kt
similarity index 100%
rename from compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.kt
rename to compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.desktop.kt
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopTextInputSession.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopTextInputSession.desktop.kt
similarity index 100%
rename from compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopTextInputSession.kt
rename to compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopTextInputSession.desktop.kt
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformTextInputMethodRequest.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformTextInputMethodRequest.desktop.kt
similarity index 100%
rename from compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformTextInputMethodRequest.kt
rename to compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/PlatformTextInputMethodRequest.desktop.kt
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/ComponentUpdater.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/ComponentUpdater.desktop.kt
similarity index 100%
rename from compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/ComponentUpdater.kt
rename to compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/ComponentUpdater.desktop.kt
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.desktop.kt
similarity index 100%
rename from compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.kt
rename to compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.desktop.kt
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowScope.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowScope.desktop.kt
similarity index 100%
rename from compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowScope.kt
rename to compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowScope.desktop.kt
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
index f0c5115..596a478 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
@@ -76,7 +76,6 @@
 import androidx.compose.ui.node.RootForTest
 import androidx.compose.ui.semantics.EmptySemanticsElement
 import androidx.compose.ui.semantics.SemanticsOwner
-import androidx.compose.ui.text.ExperimentalTextApi
 import androidx.compose.ui.text.font.createFontFamilyResolver
 import androidx.compose.ui.text.input.TextInputService
 import androidx.compose.ui.text.platform.FontLoader
@@ -92,7 +91,6 @@
 
 @OptIn(
     ExperimentalComposeUiApi::class,
-    ExperimentalTextApi::class,
     InternalCoreApi::class,
     InternalComposeUiApi::class
 )
@@ -100,7 +98,7 @@
     private val platformInputService: PlatformInput,
     private val component: PlatformComponent,
     density: Density = Density(1f, 1f),
-    coroutineContext: CoroutineContext,
+    override val coroutineContext: CoroutineContext,
     val isPopup: Boolean = false,
     val isFocusable: Boolean = true,
     val onDismissRequest: (() -> Unit)? = null,
@@ -126,12 +124,12 @@
 
     private val semanticsModifier = EmptySemanticsElement
 
-    override val focusOwner: FocusOwner = FocusOwnerImpl {
-        registerOnEndApplyChangesListener(it)
-    }.apply {
-        // TODO(demin): support RTL [onRtlPropertiesChanged]
-        layoutDirection = LayoutDirection.Ltr
-    }
+    override val focusOwner: FocusOwner = FocusOwnerImpl(
+        onRequestApplyChangesListener = ::registerOnEndApplyChangesListener,
+        onRequestFocusForOwner = { _, _ -> true }, // TODO request focus from framework.
+        onClearFocusForOwner = {}, // TODO clear focus from framework.
+        layoutDirection = { layoutDirection } // TODO(demin): support RTL [onRtlPropertiesChanged].
+    )
 
     // TODO: Set the input mode. For now we don't support touch mode, (always in Key mode).
     private val _inputModeManager = InputModeManagerImpl(
@@ -188,8 +186,6 @@
             .onKeyEvent(onKeyEvent)
     }
 
-    override val coroutineContext: CoroutineContext = coroutineContext
-
     override val rootForTest = this
 
     override val snapshotObserver = OwnerSnapshotObserver { command ->
@@ -204,7 +200,8 @@
         snapshotObserver.startObserving()
         root.attach(this)
         focusOwner.focusTransactionManager.withNewTransaction {
-            focusOwner.takeFocus()
+            // TODO instead of taking focus here, call this when the owner gets focused.
+            focusOwner.takeFocus(Enter, previouslyFocusedRect = null)
         }
     }
 
diff --git a/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt b/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt
index 1687dad..4dd8cc4 100644
--- a/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt
+++ b/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt
@@ -35,7 +35,7 @@
     private val ConstraintSetScopeStub = bytecodeStub(
         filename = "ConstraintSetScope.kt",
         filepath = COMPOSE_CONSTRAINTLAYOUT_FILE_PATH,
-        checksum = 0x912b8878,
+        checksum = 0xb5f243fa,
         source = """
             package androidx.constraintlayout.compose
     
@@ -86,98 +86,100 @@
 
             class ConstrainedLayoutReference(val id: Any)
         """.trimIndent(),
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgMudSTMxLKcrPTKnQS87PKy4pSszM
+        K8lJrMwvLQEK5BbkF6cKCfnml2Tm5wUnp+alBifnF6R6l3AJcrGnViTmFuSk
+        CrGFpBaXeJcoMWgxAACjh5JrZAAAAA==
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGJ2KM3AJcjFnlqRmFuQkyrEFpJaXOJdosSg
-                xQAASc3A6SsAAAA=
-                """,
+        androidx/constraintlayout/compose/ConstrainedLayoutReference.class:
+        H4sIAAAAAAAA/6VRXU8TURA9d/u1rEW2lUoBxQ9QSlEWiG8giWJMNqloqOGF
+        p9vda7ntdpfs3jb41t/iL9BEo/HBND76o4xzy4oCvvkyZ87cmTNzZ378/PoN
+        wCOsMWzz0I8j6Z84XhQmKuYyVAF/G/UVBXrHUSKc3d8Pwm+MX/bFGxGL0BMF
+        MAa7wwfcCXjYdl62OsJTBWQY8tsylGqHoVJrXEzYWjlgWGxEcdvpCNXS0onD
+        wzBSXElq5uxFaq8fBFsMhvRNmAwL3UgFMnQ6g55DE4o45IHjhiqmUuklBVjU
+        yTsSXjetfcVj3hOUyLD8jwn+ijS1SJtmKqKISQtXcJUhU9M8B9tCFiWG8mWJ
+        Ikxcm4CBaYasOpIJw07jf7ZJ3821hXJ9hunayuWGDKVGuoYXQnGfK6431Btk
+        6JhMmwltwMC6FD+Rmq2T52/QnUfDomVUDcuwR0PLMLPV0XDTWGdPJ8t525gj
+        7/u7vGFn9ktnzLRGw7msmbVzWmOTaeXK2fiqKVTTi47FWlcxzO/3QyV7wg0H
+        MpGtQDz5c05az27kC4apBv16r99rifg1pxy91sjjwQGPpeZpcOmi1tktz4la
+        zagfe+K51DWzac3Bpe7YoBNlx2sp64sRLhPLExYIDcIcMQM1Ys8IDUJ7tTzx
+        BVP1zyjXVz+h8mGcuZLW5bGOOvnXT3MJZ/TeyTvVXyW/wNIGJVQxm8o7+jaE
+        ufpHVN6f00SqWTxNSDXPT/pgbO/jIeFjis5R3vwhMi5uuLjpYgG3yMVtF3dw
+        9xAswSKWDpFPMJPgXgIz0X41wewvvckEVQIEAAA=
+        """,
         """
-                androidx/constraintlayout/compose/ConstrainedLayoutReference.class:
-                H4sIAAAAAAAA/6VRXU8TURA9d/u1rEW2lUoBxQ9QSlEXiG8giWJMmhQ01PSl
-                T7e713Lb7S7ZvW3wrb/FX6CJRuODaXz0RxnnlhUFfPNlzpy5M2fmzvz4+fUb
-                gMd4yLDDAy8KpXfiuGEQq4jLQPn8bThQFOgfh7Fw9n4/CK8+eTkUb0QkAlfk
-                wBjsLh9yx+dBx3nZ7gpX5ZBiyO7IQKpdhlKlfjFhe63JsFwPo47TFaqtpWOH
-                B0GouJLUzDkI1cHA97cZDOmZMBmWeqHyZeB0h32HJhRRwH2nFqiISqUb52BR
-                J/dIuL2k9hWPeF9QIsPqPyb4K9LQIh2aKY88pi1cwVWGVEXzDGwLaRQYipcl
-                8jBxbQoGZhnS6kjGDLv1/9kmfTfTEarmMcxW1i43ZCjUkzXsC8U9rrjeUH+Y
-                omMybXIMrEehE6nZBnneJp14PMpbRtmwDHs8sgwzXR6PtowN9my6mLWNBfK+
-                v8saduqwcMZMazxaSJtpO6M1thjpo3Q2uWoI1XDDY/GopxgWDweBkn1RC4Yy
-                lm1fPP1zSdrMXugJhpk6ffhg0G+L6DWnHL3R0OV+k0dS8yS4clHr7IznRK1G
-                OIhc8ULqmvmkpnmpOzbpOmm9HBT1sQjvE8sS5ggNwgwxA6vEnhMahPZ6ceoL
-                ZqqfUayuf0LpwySzktRlsYE18q+f5hLOARPvVL+aXGHSoIAy5hN5BzoKZKof
-                UXp/ThOJZv40IdE8P+n6xN7DA8InFF2gvMUWUjXcqOEmWSxpc6uG27jTAotx
-                F8stZGPMxViJYcbaL8eY/wVNn9c9/QMAAA==
-                """,
+        androidx/constraintlayout/compose/ConstraintSetScope$ConstrainedLayoutReferences.class:
+        H4sIAAAAAAAA/92X3VLbRhTHz8rfwoBwjOM4hjpEIcaYGBvj8BUKIdAYBKE4
+        pUnpl7AVIjAy45UZcsf0Im/QPkB70dt2pplk2pkOw2VfoG+T6ZFRQDJWxnF0
+        1QFrz65W//M7Z4+k1T9v//wbALJQIbAuKqVqRS4dpYoVhapVUVbUsviiUlNx
+        YP+gQqXUwvmJgqQWipUDiT8fkkpCffKG9EyqSkpRoh4gBLhd8VBMlUVlJ/Vo
+        e1cqqh5wEHDPyIqszhIQ4kI7bqe3hEbd6aFNAqG4xYmbQqW6k9qV1G1Nh6ZE
+        Ramooiqjcmqtoq7VyuVpAg65RL3gI9C/V1HLspLaPdxPoVupqojlVF5Rq3it
+        XMTIOgj0Fp9LxT394nWxKu5LOJHA7fhlBMNIQRPZQSg/dEIXC37oxnyoz2XK
+        jxLItZcOP/RAwAcMXMEg4pq2C3pZcEKIwJUmKfGDD8La/GsEnJpvAhtteX7f
+        +mNC2fqViqSoaQJz8aEP8XFJEPWu6+tSrJTLGEd9+earVfEFXcHC+oSAf0dS
+        BZGqeaUkHVnVQ94PN2CAhRjcJJBtJ2wP3CLQKRYxSsor0pGaLxFYbrOWhy5X
+        hx9uQ5yFQRgiMPMxOfPAMFZqk4o8q5ERFpJwh8AKL/MiP4LJe1RdLFNp5MNW
+        mr9YZh4XmuQJMDIuSNhYARkb3WQ0NxfSYzZKj5mlszZKZ83S4zZKj5ulczZK
+        58zSd22UvmuWnrBResIsPWmj9KQm3XFR8vjYFmy7f0YbxNN2iqcbxDN2imca
+        xMfsFB9rEM/aKZ5tEB+3U3y8QTxnp3j93uwR9LfiqqSKJVEV8UXJ7B86cGNH
+        tINPOwA+lvdw/EjWeliyTClNSN/JcYRlwgzLcCfHLP4zXA/LeB1nY95u7+lL
+        Z/jkOMOMkvu93pPjgJ9jIt6AM4ADo47Tn90M51z2ce4IM+p5ePqSQdtrsH0G
+        mzXYHQbbb7A7DXaXwe422JzB7jHYAYN9xWAHDXavwQ69szdCxpienP7gxLic
+        mAmXliS8RTB1sx+9cXnPeuIL+nIB3NlTCSSEZvvQQqVWLUoPpO3azuKRKuGO
+        tKKgC9ehWK5JBP4trM6vs00V2ZW6HJsoxN5ZS+xwLB1rPtvuDSG6ysSeiXt1
+        8WaRLeG5FZVNCGz6ZjqZnZhKo5GZyk6yiUUWk7hRU1R5X8orhzKVt8vS/MUu
+        HvexC5USht8toOu12v62VH0s4hwCAaFSFMubYlXW+vqgryDvKKJaq6LNN+qe
+        7+ZNDjoLqljcWxUPdAl/XlGk6kJZpFRbRPZsXZZk7Vyw2SIRuKZ72rzED2nc
+        jTvx1mQgoG3OsehK2HNj6wXgOG2Dj/0e7Ltw1AES9rZwtnY79yYD7BvgEsOv
+        IJh4DVcTyVcQ+b0u9gyPXTjJDSx0QwcEsd3BsdjZhXAdotrTAS3NAalbmnsG
+        ntev94CMrYecceCkPujHYc37jyjhwTad+AMiguMeNsG16PAb4H8B33A08yt0
+        RXNOR8418gYSMOX+C5JPr7lfQ+o3vMgBu3jkgHkLEQ+MEQ8MLnswARpvCEPU
+        qPswKTFsefzdwt877hjOG8VzLpzhgQxaWuLSeiyGtCFu1gLXaTcup+NyiMsh
+        LmfCHW8RN2eB67IbN6DjBhA3gLgBE+7dFnEnLHDdduMGddwg4gYRN2jCnWwR
+        d8oC12M3bkjHDSFuCHFDJtzpFnFnLHC9duOGddww4oYRN2zCvdci7uw57k86
+        bqaOy7VfDdeb80bQUxq/4SPIGsGv5Mg57w2c92mdt9/Am2nKO2fF2345WPBG
+        dd4o8kaRN2rinW+R974Vb/v1YMHbr/P2I28/8vabeBda5H1gxeuzmzem88aQ
+        N4a8MRPvYou8S1a8rN28AzrvAPIOIO+AifezFnkfWvF22M3L67w88vLIy5t4
+        8y3yLlvx+u3mHdR5B5F3sP5n5F1pkVew4u20mzeu88aRN460cRPvaou8a1a8
+        XXbzJnTeBPImkDdh4n3UIu+6FW+33bxJnTeJvEnkTZp4P2+J1wV7eGSxx6DC
+        d8hfBm2D/D3sY/t//egCBYM7wKA3MAGFLXDk4XEevsjDJnyJJjzJw1P4agsI
+        xY+Rr7fgKoUohW8o+OpHN4UwhT4K31J4QGGJwkMKyxQECmsU1ilkKeQoTFCY
+        ojBDYZbCHMUXnZb4LvQq4m+7rl78D9ISPcyrGgAA
+        """,
         """
-                androidx/constraintlayout/compose/ConstraintSetScope$ConstrainedLayoutReferences.class:
-                H4sIAAAAAAAA/62Y3VLbRhTH/ysbfwgDxjGO4xjqEIcYY2JsDCGE0pAEGoMh
-                FKc0Kf0StkIERs54RYbcMb3IG7QP0F70tp1pJpl2ppPhsi/Qt8n0yCggAco4
-                RAPePbva/Z/fnj2yVv737V//AChgi2FZUquNulLdzVbqKtcakqJqNel5fUej
-                ju2ndS5n7xxeKMtauVJ/KicPu+RqqTl4RX4sN2S1InMvGENwU3omZWuSupG9
-                v74pVzQvXAyeKUVVtGmGUqp0Frc310rHdW8OrjJEUjYXLpfqjY3spqyt6zo8
-                K6lqXZM0hZSzS3VtaadWu8ngUqrcBz9D31ZdqylqdvPZdpbcyg1VqmWLqtag
-                uUqFVtbO0FN5Ile2jMnLUkPalmkgw9XUSQRTT1kX2SCoADrQKSKALoqH9kTh
-                yRGG8bOFI4BuhPwQcI4WkdK129Ajwo0Iw7lTQhKAH1F9/AUGt+6bYeVMnt+3
-                /xRQsTlTlVUtx3ArNfghPk4Ikt5FY18q9VqN1tHcvplGQ3rOFyixPmEIbMha
-                SeJaUa3Ku3b5UAzgEvpFJHCZoXCWZXtxhaFDqtAqeVKVd7VilWH+jLk8eDI7
-                AriKlIgBDDJMfUzMvBiiTD0lIw9yZFhEBtcYFpJKUkoOU/DuN2ZrXB7+sJ1O
-                Hm1zkjaaFRkEhTYkas6AvINu8rqbI+lRB6VHrdIFB6ULVukxB6XHrNLjDkqP
-                W6WvOyh93So94aD0hFX6hoPSN3Tp9qOUp6/tkmP3z8gx8ZyT4rlj4nknxfPH
-                xEedFB89Jl5wUrxwTHzMSfGxY+LjToo3783ukvFUXJQ1qSppEj0ohe1nLjrY
-                Mb3w0jcyne+EXUVvUbYK1RxjvW/2YqIQFUQh+GZPpH8h2C0KPtdBn6/Lt//C
-                HX2zlxdG2O0e35u9UCAoxHwhd4g6Rlz7v3iEoHveH/TEhBHvvf0XAtk+k+03
-                2aLJbjfZAZPdYbI7TXaXyQ6a7G6THTLZ50x22GT3mOzIO3slYl7Tw/0f3bQu
-                N0WiTQ8S3R1gmP7oM8t7tpKezSf3/tqWRrNWdlRN2ZaL6jOFK+s1eeboxEpn
-                tjv1qszQVSLRpZ3tdbnxQKIxDKFSvSLVVqWGoreNTn9Z2VAlbadBdvK47uHJ
-                1eKgo6xJla1F6akhESiqqty4U5M416nFcn2nUZHnFP1a+KBxV17f2Zjd1WQ6
-                ItdVhguGp9UT/MjRydNNuSggpB9EKco/UMtDtQ8IBvXDLLW7qd1GvS5I1Fqj
-                0Xr+9mRC4msE00MvEU6/wvl05iVifzTF1qnspEEeiOhCO8JUV6gvcTARFxEH
-                mpbugDUt3b2AanO+F7Jxu+gcNKgXfdSte/+JJLxU59J/IlZyfUpVeCk+9BrJ
-                X+Efiud/Q2d83O0abxt+jTQmPX8j8+iC5xWyv9MkFx5TGYTwFjEvRpkXA/Ne
-                CoDOG6El6tS9FJQE1Un6XKHPO+4EjRuha200wos8WXrgcsZaTGEj3IINrttp
-                3KCBGyTcIOEGLbhjLeKO2+C2OY0bMnBDhBsi3JAF93qLuBM2uB6nccMGbphw
-                w4QbtuDeaBF30gbX6zRuxMCNEG6EcCMW3Jst4k7Z4Pqcxo0auFHCjRJu1IL7
-                aYu404e4Pxu4+SZu8OzZcPF03hh5ytH7aoxYY/RGGDvkvUTjPmvy9pl486fy
-                3rLjPXs62PDGDd448caJN27hnWmR97Yd79nzwYa3z+DtI94+4u2z8N5pkfeu
-                Ha/fad6EwZsg3gTxJiy8sy3yztnxik7z9hu8/cTbT7z9Ft7PW+S9Z8fb7jRv
-                0uBNEm+SeJMW3mKLvPN2vAGneQcM3gHiHWj+mXkXWuQt2fF2OM2bMnhTxJsi
-                2pSFd7FF3iU73k6nedMGb5p408SbtvDeb5F32Y63y2nejMGbId4M8WYsvF+0
-                xOvGBpUitQRS+I74n0A/IH8Pher/yoszy+Kp7y3iQvNNVEyXE++sOXEokUuc
-                PtrpX5zJVT7xWNpqip/2E/4cXVvQxHRJzF3OZQoTkzky8pOFG2J6VsQmLe4p
-                LXqFQlReg6uIB0V8SSVW9eKrIh7i0RoYx9dYW8N5jjjHNxz+ZunhiHL0cnzL
-                cZdjjuMexzxHiWOJY5mjwDHOMcExyTHFMc1xi+P2/ypvybWDGQAA
-                """,
+        androidx/constraintlayout/compose/ConstraintSetScope.class:
+        H4sIAAAAAAAA/7VVXU8bRxQ9s/5kMY5xAuEjTUlME/MR1qE0bQNNC25JljpA
+        7Qo14qXD7sRZWO+inTWCN9T+gv6F/oJWaiFqpAjlsT+q6p21IcFYeUDtg2fu
+        nHvvOXdn5o7//uev1wDmUGOY454d+I69b1i+J8OAO17o8gO/GRLQ2PWlMMpn
+        jpoIa5a/K1JgDLltvscNl3t1Y21rW1hhCjGG5ILjOeEjhlhxYiODBJI64kgx
+        xMMXjmR4ULmM4DwRe2I/NG2Ga8WJylvpWhg4Xp381zuxpabj2iJIoU9HVlVw
+        41R5plN5xrHTyJEG390VHmncK16UuKjaVpjPII+rSuQaQ7YuPBHwUNhlv+mF
+        DMzMYBDXe6BhiGoomu/nGVE8owzp0G85M/gAGQXeZOizAkHUVfFcLvsBQ724
+        Wek8BarzMjs8fgYJuxIFk4oIhGcJSbtbqPhB3dgW4ZYKkQb3PD/koUNJxqof
+        rjZdl6Jiji3TKDDc3PFD1/GM7b2GQSIi8LhrmJ76IOlYMoWPGAasF8LaaSev
+        84A3BAUy3C1e/KYup0GX6y6KOu5ggmH9v/7kFKZOb3gzdFxjMQj4AaH36JJQ
+        7sHac4aJbrtvTnQBMzBQ0jGD+wyV4uU6oNtJRw32sY5pzDFc7RJBV4Zb9Dly
+        /LR7Vi4p36XnMuhVN1PD5wyJ8VZ791faJ/9UhNzmIacStMZejJ4bpoYeNYC6
+        YofwfUetSmTZtDE/nxze0bUhTddyJ4e6llZGWlcmYWrK9bfRLC2HTg5ntRJ7
+        yDJLiTe/JrWctlLIJUaSpWRVK5Evn0uN6PlkmuUpqpS+TWMU1rOSzukjWqn3
+        iVbN5mJkxX9481NW+YhVlTLLVIHV/6OLRt/jpoa4yDezQy9IvOzbguFKhdJW
+        m40tEXzPt1xC8hXf4u4GDxy1boOjVXp2nIYwvT1HOgQtvm1VhvFO71njnQvL
+        mB69YmWXS6kq02t+M7DEsqMEhtsUGxfocZ8uQzw6X029eWTFyab/ABq/pZWh
+        Tp7mxOQx0r+ToaFCYzICY3hKY6YVgB7oNOfVFWsnrxCZRvPYK2SfHeNKvv8I
+        A5N/YHhhcjT+458YHj3CjSN8+FsHb+Id3rE27y9k3SJFxWtShOIdmMqPv8Tk
+        K0w/m5yaev0Ss8f45DxZEumIbLCV0CZTVgEPyL/ajrtN8xr9Uqy1yA3jU3zW
+        ZRMenudnHZswH/HHsE6jTtg0xZrox3dR1gqqNFcJX6DYLzYRM/HIxJcmvsIi
+        mVgyUcbXm2AS32B5E30SusRjiaTEYGSMSTyRKET2LYneyDD/BWglTVUgCAAA
         """
-                androidx/constraintlayout/compose/ConstraintSetScope.class:
-                H4sIAAAAAAAA/7VUXU8bRxQ9s/5kMY5xAgGcpiTQxDaEdShN20DTglvKUgeo
-                qVAjXjrsTpyF9S7aWSN4Q+0v6F/oL2ilFqJGilAe+6Oq3jELKcbKA2pf7tw5
-                984583Hv/PX3n68BzKDOMMM9O/Ade9+wfE+GAXe80OUHfiskoLnrS2FUzwPr
-                Ily3/F2RAmPIbfM9brjcaxirW9vCClOIMSTnHM8JnzDEiqWNDBJI6ogjxRAP
-                XziS4VHtKoKzROyJ/dC0GW4US7W30uth4HgNit/sxBZajmuLIIU+HVm1g1tn
-                ylOdylOOnUaONPjurvBI40HxssRl1UhhNoM8riuRGwzZhvBEwENhV/2WFzIw
-                M4NB3OyBhiHaQ9F8N8+I4ikwpEP/NJjBe8go8DZDnxUIoq6L53LRDxgaxc1a
-                5yvQPq9yw+PnkLBr7WRSEYHwLCHpdsdqftAwtkW4pVKkwT3PD3no0CJjxQ9X
-                Wq5LWTHHlmmMMdze8UPX8YztvaZBIiLwuGuYnjqQdCyZwgcMA9YLYe1Ei9d4
-                wJuCEhnuFy+fqctrUHHdR1HHPZQY1v7rI6cwcVbhrdBxjfkg4AeEPqAiobUH
-                q88ZSt1u3yx1ATMwUNExhYcMteLVOqDbS7cb7EMdk5hhuN4lg0qGW3QcOX7W
-                PctXlO/Scxn0qsrU8ClDYvy0vftr0cs/FSG3echpC1pzL0bfDVOG2pDtELTv
-                qFmFPJvu5KeTw3u6NqTpWu7kUNfSyknryiVMDbn+CM3SdOjkcFqrsMcss5B4
-                80tSy2nLY7nESLKSrGsViuVzqRE9n0yzPGVV0nfJttN6ltM5fUSr9C5p9Wwu
-                Rl78+zc/ZlWMWNVWphltE/X/o4EK7whTL1zmm9qhzyNe9W3BcK1Gy1ZazS0R
-                fMe3XELyNd/i7gYPHDWPwEKdfhynKUxvz5EOQfNvu5RhvDN63nMX0jKmRx9Y
-                1eVSqp3p634rsMSiowSGI4qNS/R4SHUQV69MI3135MXJp++f7DLNDBrpdpEo
-                HyP9GzkaviGbbIMx1MhmThPQA53GvKquaPEykWk0jr5C9tkxruX7jzBQ/h3D
-                c+VC/Ic/MFw4wq0jvP9rB2/iX7yjEe/P5N0hRcVrUobiHZjIj79E+RUmn5Un
-                Jl6/xPQxPrpIlkS6TTZ4uiAiU94YHlH8aZR3l8aVqNDVJDeMj/FJl0t4fJGf
-                dVzCbJs/hlWyOmGTlLuEfqy1V5n4lsY64XOU+9kmYiaemPicLL5QZt7EAqqb
-                YBJf4qtN9EnoEosSSYnBtjMq8bXEWNu/I9Hbdpb+AeegSxAbCAAA
-                """
     )
 
     private val MotionSceneScopeStub = bytecodeStub(
         filename = "MotionSceneScope.kt",
         filepath = COMPOSE_CONSTRAINTLAYOUT_FILE_PATH,
-        checksum = 0xc89561d0,
+        checksum = 0x499473bb,
         source = """
             package androidx.constraintlayout.compose
 
@@ -239,89 +241,90 @@
                 }
             }
         """.trimIndent(),
+"""
+        META-INF/main.kotlin_module:
+        H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgMudSTMxLKcrPTKnQS87PKy4pSszM
+        K8lJrMwvLQEK5BbkF6cKCfnml2Tm5wUnp+alBifnF6R6l3AJcrGnViTmFuSk
+        CrGFpBaXeJcoMWgxAACjh5JrZAAAAA==
+        """,
         """
-                META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGJ2KM3AZc6lmJiXUpSfmVKhl5yfV1xSlJiZ
-                V5KTWJlfWgIUyC3IL04VEvLNL8nMzwtOTs1LDU7OL0j1LuES5GJPrUjMLchJ
-                FWILSS0u8S5RYtBiAACRUOp0ZAAAAA==
-                """,
+        androidx/constraintlayout/compose/MotionSceneScope$ConstrainedLayoutReferences.class:
+        H4sIAAAAAAAA/92XS1PbVhTHz5XfwoBxgBDAAYoJYOMI+QUGkoYQKAZDKE5p
+        UvoStkIERmJ8ZYbsmC7yDdoP0C66bWeaSaad6TAsu+sXyvTIiCA5VkYhWnXA
+        0rlXV//zOw/ZV/+8+fNvAEiDQmBdkMtVRSofcyVFpmpVkGS1IjxXaipOHBwq
+        VOTWFFVS5GJJlMViSTkUowsXK8Vyob50U3wqVkW5JFIfEAKhPeFI4CqCvMs9
+        3NkTS6oPXAS8c5IsqXcJrIwVPtzp7HahUXV2fItA95jFheGCUt3l9kR1R5On
+        nCDLiipoopRbV9T1WqUyS8AllakfAgRu7itqRZK5vaMDDmnEqixUuLysVvFe
+        qYRxtRDoKj0TS/v6zRtCVTgQcSGB0bF3EQwzRU1kF6GC0AptLAShHbOhPpNo
+        dJJA+irJCEIHhAPAwDUMYUxT9kAXC27oJnCtSUKCEIAebf0NAm7NM4GNK/h9
+        X+UxmWz9PlmUVZ7AvbFxGx6sBVGvT69JSalUMIp66earVeE5XcWWGiAQ3BXV
+        gkDVvFwWj616IR+EIfiEhUEYJpD88KB9MEKgVShhjDQqi8dqvkxg+Uo9PP5u
+        VwRhFMZYuAXjBOY+Jl8+iGOHNunE8+5IsDABtwnko1JUiCYwcQ+rixUqJj6k
+        xtHLAkexxCRPgJGwFD3G2icdc5LUnFwKpxwTTpmF044Jp83CGceEM2bhrGPC
+        WbPwlGPCU2bhaceEp83COceEc5pwy2WL45fzikNPy2SDNO+cNN8gnXROOtkg
+        nXJOOtUgnXZOOt0gnXFOOtMgnXVOuv4cdhT0X7w1URXKgirgjyBzcOTCzRrR
+        DgHtAPjFu4/zx5I2wiZlyjwhkdOTXpbpYVgmdHrC4j8T6mAZv+t8zt/uP3vh
+        7jk9STKT5H6X//QkHAwxvf6wO4wTk66zn71MyL0SCHl7mUnf8tkLBm2/wQ4Y
+        bNZgtxjsoMFuNdhtBrvdYIcMdofBDhvsawa702B3GezuC3uz2xjT47Mf3BiX
+        GzPh0ZKEDwam7u5Hb0reU0/cfDWW//a+SiBWaLa7LCq1akl8IO7UdhePVRH3
+        mYqMDjxHQqUmEvi3uDa/wTbRY1frYmysOHhhLbHxQX6w2VpnN3noJjn4VNiv
+        SzeLaQmvrapsrMDyw/xEJjfDo5GcyU6ysUUWk7dZk1XpQMzLRxKVdiri/OWu
+        HHemC0oZA28voOv12sGOWH0k4BoC4YJSEipbQlXSxvpkoCjtyoJaq6IdbdR9
+        uzs3OWgtqkJpf0041CWCeVkWqwsVgVKteOx5RZYk7Vpns/IQuKF72nqHH3jc
+        X7vxkWQgrG23sdnKOPLi2Q8QCmlbdhx34NiDsy4QcbSNq7XHuGsizL6GUCz+
+        Ejpjr+B6bOIl9P5eF3uKxzZc5IXr0I6ynXjexbnB8xuhD/q1bwW0NAekbmnu
+        GXhWv98HEp595JwDF0XgJk5r3n9ECR+e+dgf0Ftw3cFT53p//DVEf4FAvD/5
+        K7T1Z92urCfxGmIw4/0LJp7c8L4C7je8yQV7eAwB8wZ6fZAiPri14sMEaLzd
+        GCIgWQTmkLMPovgZwc8F9yCum8SEeXCFD5JoaYnj9VgMaUPctAWu22nciI4b
+        QdwI4kZMuBmbuFkLXI/TuAM67gDiDiDugAl3yibutAWu12ncIR13CHGHEHfI
+        hJuziTtjgetzGndYxx1G3GHEHTbhztrEnbPA9TuNO6LjjiDuSP3PiHvHJu7d
+        t7g/6bjJOm7o6t3Q15x3FD3NYQ+MIukovv2OvuUdwnWf1nlvGniTTXnvWfFe
+        vR0seMd13nHkHdfe1k288zZ571vxXr0fLHjjOm8ceePIGzfxLtjkfWDFG3Ca
+        N6HzJpA3gbwJE++iTd4lK17WaV5O5+WQl0NezsT7mU3eZSveFqd5eZ2XR14e
+        eXkTb94m74oVb9Bp3pTOm0LeFPKmTLyrNnkLVrytTvNmdN4M8maQN2PiXbPJ
+        u27F2+Y075TOO4W8U8g7ZeJ9aJN3w4q33WnenM6bQ94c8uZMvJ/b4vXAPh5Z
+        HDGo8B3yV0DbIH8PB3j+/71ugYxhHWK4mxh6cRtceXiUhy/ysAVfogmP8/AE
+        vtoGQvE15OttuE6hn8I3FAL1o5dCD4UIhW8pPKCwRGGZwgqFAoV1ChsU0hSy
+        FKYpzFCYo3CXwj2KP3FaytvQq4Cfnbp66T9woDCJcRoAAA==
+        """,
         """
-                androidx/constraintlayout/compose/MotionSceneScope$ConstrainedLayoutReferences.class:
-                H4sIAAAAAAAA/62YW1PbRhTH/ysbX4QBQ4AQLgGKCRfjGN+4l4YQKAZDKE5p
-                UnoTtkIERma8giFvTB/yDdoP0D70tZ1pJpl2psPw2Ld+oUyPjAiSgzIO0YBX
-                Z9dn/+e3Z4/slf9989c/AJLYY1iT1HypqOSPo7miyrWSpKhaQXpePNRoYP+g
-                yOXoalFTimo2J6tyNlc8kEPzF55yPlN23ZCfyiVZzcncC8YQ3JWOpGhBUnei
-                D7d35ZzmhYvBM6OoijbLsDyY+fCg01uZStXpoU2G1kGbN/oyxdJOdFfWtnV5
-                HpVUtahJuiiPrhW1tcNCYZrBpeS5D36G23tFraCo0d2j/SjRyCVVKkTTqlai
-                uUqO1lXL0JJ7Juf2jMnrUknal8mRYWDwXQTTSFYX2SGoAOpQLyKABsqG9kzh
-                oVGG5HWSEUAjmvwQcIOWMKgr16BFhButDDeuSEgAfrTp/rcY3HpkhvVrxH3f
-                zlMyxfI8VVa1GMO9waEqItgLkl6HsSe5YqFAqyhv3VypJD3nK1RS3QyBHVnL
-                SFxLq3n52K4W0gH04hMRPehjiH/4or3oZ6iTcrRGHlLlYy2dZ1i6Vg0PvVsV
-                AQxgUMQdDDHMfEy+vAhThV5RiefVERExgrsM6ZASkkIRStzD0kKBy5EP2ePQ
-                5QaHaItZmkFQaCvazHsfdyxIXA9yKZxwTDhhFU46Jpy0CqccE05ZhcccEx6z
-                Co87JjxuFZ5wTHjCKjzpmPCkLlx7WeL04bzs0N0yWiEdc046ViEdd046XiGd
-                cE46USGddE46WSGdck46VSE95px0+T5szBjfeKuyJuUlTaIvQWH/yEWHNaY3
-                XvrMpTObcKzoPapPIR9jrOv0pF0U2gRRCJ6eiPQvBBtFwec6H/M1+M5euNtO
-                T+LCKLvf4js9aQoEhXZfk7uJBkZdZ794hKB72R/0tAuj3qWzFwLZPpPtN9mi
-                ya412QGTXWey6012g8kOmuxGk91ksm+Y7GaT3WKyWy/sjVbzmh6f/eimdbkp
-                EzV6kuieAMPsR59H3rOVdO6q3Pm7exrN2ThUNWVfTqtHCle2C/Lc5TmUzmLz
-                xbzM0JAhybXD/W259EgiH4amTDEnFTalkqL3jUF/VtlRJe2wRHaoUvftedQS
-                oC6rSbm9VenAkAikVVUuzRckznVmMVs8LOXkRUV/r/m880DePtxZONZkOvgW
-                VYZbRqTNd/gRoxOlmypRQJN+wKQc/0A9D119QDCoH1Kp30j9Ghp1QaLeFnnr
-                1dsy0iS+RnA4/BLNw69wc3jkJdr/KIttU1tPTh7cRAPJNtM1R2M95xPRgU6g
-                bOkBWNnSwwvIl+d7IRs3i85BTl24TcN69J9IwkvX2PCfaM+4PqVL81pn+DVC
-                v8If7oz/hvrOMbdrrCbyGsOY8vyNkSe3PK8Q/Z0mufCU2iCEN2j3IsG8uLPs
-                pQTovK20RBBZF2aIswMhevXT64K7h/xGKWE15OFFnCw9cTFjLaa0EW7SBtft
-                NG6XgdtFuF2E22XBTVWJO2aDW+M0breB20243YTbbcEdrxJ3wgbX4zRur4Hb
-                S7i9hNtrwZ2sEnfKBtfrNG6fgdtHuH2E22fBna4Sd8YG1+c0br+B20+4/eU/
-                M+6nVeLOvsX92cCNl3GD16+Gjqt5ByjSDNXAAJEO0PPewFveXvL7rMx728Qb
-                v5L3nh3v9cvBhnfI4B0i3iH9+dTCO1cl73073uvXgw1v2OANE2+YeMMW3vkq
-                eR/Y8fqd5o0YvBHijRBvxMK7UCXvoh2v6DRv1OCNEm+UeKMW3s+r5F2y4611
-                mjdm8MaIN0a8MQtvukreZTvegNO8CYM3QbwJ4k1YeFeq5M3Y8dY5zZsyeFPE
-                myLelIV3tUreNTveeqd5xw3eceIdJ95xC+/DKnnX7XgbnOadNHgniXeSeCct
-                vF9UxevGDrUi9QRS+I74n0E/IH8Pha7/ZVfn1sUrnlrElfJTqDic7bmwFsVw
-                T6znKl9nf0WmMPGep9JeWfqqn+QX6b0VTRzOiLG+2EhqcipGRnxqbFQcXhCx
-                S8s6oOVuUHKyW3Cl8SiNL6nFpt58lcZjPNkC4/gaW1u4ydHJ8Q2Hv9x6ONo4
-                uji+5XjAscixxLHMkeFY41jnSHKMcUxwTHHMcMxy3OO4/z+8pxUSTxkAAA==
-                """,
+        androidx/constraintlayout/compose/MotionSceneScope.class:
+        H4sIAAAAAAAA/61VW08bRxT+Zm1ssxjHOOHqNCWBNuYS1qH0FmhacEtY11wK
+        KWrES4fdCVlY76KdNYI31H/Qp773F7RSC1EjRSiP/VFVz6yXJBgrUqLI0pkz
+        35z5vpkz56z//e+f5wBm8JBhmnt24Dv2oWH5ngwD7nihy4/8RkhAfd+Xwlj2
+        Q8f3NizhiQ3L3xdpMIb8Lj/ghsu9HWN1e1dYYRoJhtSc4znhfYZEaWwziw6k
+        dCSRZkiGTxzJMFN7e7lZovXEYWjaDNdKY7VXwhth4Hg7tN7fii00HNcWQRrd
+        OnJKv3iuO9Wq69gZ5EmC7+8LjyTulC4rXBaNBWazKOCq0rhGKdmhIwc8FLZp
+        V/yGFzIwM4s+9HdCwwDD9ZL5ZqYhxVRkyIR+czGLD5BV4A2GbisQRL4uHstF
+        P2AQpa1a6yPQSd8+waOV80hh16JQ0hCB8CwhKbkjNT/YMXZFuK1CpME9zw+5
+        opDGih+uNFyXohKOLTMYYbix54eu4xm7B3WDtEXgcdcwPXUd6VgyjY8Yeq0n
+        wtqLN6/xgNcFBTLcLl2+UZvXoMq6jZKOjzHGsPJ+L5zGxHlxU224xnwQ8CNC
+        71CJ0N6j1ccMY+0yb461AbMwUNYxhbsM1dK7FH+7N4466xMdk5hhuNomgoqF
+        W3QZOXreOEvvJN6m2bLoUhWp4UuGjtFmV+deFn5c9j21uAiWRchtHnI6kVY/
+        SNBHhynTqQyoPfYIP3TUrEyeTVn67ey4pGsDmq7lz451LaOcTHMkUEH5nhjO
+        0XTg7HhaK7N7rHuh48XvKS2vVUfyqaFUOb2ulWmtkM8M6YVUhhUoqtx5i2wU
+        plcz+a4hrZxd0tZz+QR5yZ9e/JJTa8RKUEcLpI43zdSh195/ixXfsEwv3Mo2
+        tUc5TlZ8WzBcqdGmlUZ9WwQP+bZLSKHmW9zd5IGj5jFYXKeHcerC9A4c6RA0
+        /6qLGUZbV1/25IWwrOnRO1dcLqU6l77hNwJLLDpKYDCm2LxEj7tULUl6Yo1+
+        c+iPvL5oTFI66T+CbI1mhqoIGjvGT5H5MwpbJpuKwDRWyGabAeiETmNB1WK8
+        uUpkGo3Dz5B7dIorhZ4T9I7/hcG58WLy578xWDzB9RN8+EcLb+E13uGY91fy
+        biIR8Zqkpnh7JwqjTzH+DJOPxicmnj/F9Ck+vUiWQm9E1tfcEJMpbwSf0fpq
+        HHeLxjV1Jdac5AfxOb5ok4R7F/lZSxJmI/4EfiCrEzZJsVX0YD3a9T02aPyR
+        8K8o9v4WEia+NvGNiXkskIuKiW/x3RaYxCIebCEnoUssSaQk5iKnT2JYwpQY
+        iaY3Jboip/o/WrVkd0EIAAA=
+        """,
         """
-                androidx/constraintlayout/compose/MotionSceneScope.class:
-                H4sIAAAAAAAA/61VW08bRxT+Zm1ssxjHOOHqNCWBNuYS1qH0FmhScEpZ11wK
-                LWrES4fdCVlY76KdNYI31H/Qp773F7RSC1EjRSiP/VFVzqyXpBgrUqLI0pkz
-                35z5vpkz56z//e+f5wBmsMEwzT078B370LB8T4YBd7zQ5Ud+IySgvu9LYSz7
-                oeN7G5bwxIbl74s0GEN+lx9ww+XejrG6vSusMI0EQ2rO8ZzwPkOiNLaZRQdS
-                OpJIMyTDJ45kmKm9vdws0XriMDRthmulsdpr4Y0wcLwdWu9vxRYajmuLII1u
-                HTmlXzzXnWrVdewM8iTB9/eFRxJ3SpcVLovGArNZFHBVaVyjlOzQkQMeCtu0
-                K37DCxmYmUUf+juhYYDhesl8M9OQYioyZEK/uZjFB8gq8AZDtxUIIl8Xj+Wi
-                HzCI0lat9RHopG+f4NHKeaSwa1EoaYhAeJaQlNyRmh/sGLsi3FYh0uCe54dc
-                UUhjxQ9XGq5LUQnHlhmMMNzY80PX8Yzdg7pB2iLwuGuYnrqOdCyZxkcMvdYT
-                Ye3Fm9d4wOuCAhluly7fqM1rUGXdRknHxxhjWHm/F05j4ry4qTZcYz4I+BGh
-                d6hEaO/R6mOGsXaZN8fagFkYKOuYwl2Gauldir/dG0ed9YmOScwwXG0TQcXC
-                LbqMHD1vnKV3Em/TbFl0qYrU8CVDx2izq3OvCj8u+55aXATLIuQ2DzmdSKsf
-                JOijw5ShhmR7BB06alYmz6YE/XZ2XNK1AU3X8mfHupZRTqY5EqigfE8M52g6
-                cHY8rZXZPda90PHi95SW16oj+dRQqpxe18q0VshnhvRCKsMKFFXuvEU2CtOr
-                mXzXkFbOLmnruXyCvORPL37JqTViJaijBVLHm2Z0dKy9/+4qvmGZHreVbWqP
-                0pus+LZguFKjTSuN+rYIfuDbLiGFmm9xd5MHjprHYHGd3sSpC9M7cKRD0Pzr
-                BmYYbV191Y4XwrKmR09ccbmU6lz6ht8ILLHoKIHBmGLzEj3uUqEk6Yk1+s2h
-                P/L6ojFJ6aS/B7Lf0cygkTKMjvFTZP6MwmpkUxGYxjLZbDMAndBpLKgyjDdX
-                iUyjcfgZco9OcaXQc4Le8b8wODdeTP78NwaLJ7h+gg//aOEt/I93OOb9lbyb
-                SES8Jqkp3t6JwuhTjD/D5KPxiYnnTzF9ik8vkqXQG5H1NTfEZMobwWe0vhLH
-                3aJxNW4ANckP4nN80SYJ9y7ys5YkzEb8CayR1QmbpFgTPfg+2lXFOo0/Ev4V
-                xd7fQsLEAxNfk8W8MgsmKni4BSbxDRa3kJPQJb6VSEnMRU6fxLDEksRINL0p
-                0RU55kuxHmQmPAgAAA==
-                """,
+        androidx/constraintlayout/compose/MotionSceneScopeKt.class:
+        H4sIAAAAAAAA/2WQz04iQRDGvxoUEVdEFBXc7GG9M2C8eTIrJhNhdiO7xoSD
+        aYYOaRi6zUwP0RvZR9nH2IMhHvehNlYbjQle6s+vv1R91f/+/30EcILPhBOh
+        h4lRw3s/Mjq1iVDaxuLBZJbB9M6k0u8aq4zuRVLLXmTu5KVdAxHKYzETfiz0
+        yP8+GMuIaY5Q/RWety+CsH1+G55127c/rri7IVQ67/KeTZQenRJqb8sby8sL
+        WCMcdUwy8sfSDtxL6gutjRXOTOqHxoZZHPOQ7c7E2FhpvyutGAormHnTWY4v
+        JBfWXQCBJq7w+PFeuarJ1bBF+LKY54uLedErl76Wyot53WvSzdPvn09/8h5z
+        pzomN2Bn+SMaE0vY/OasC22vRZxJwuFVpq2aykDPVKoGsTx7d00o9kyWRPJC
+        xSytvUqvPwjRgoeVF9t1rCLP3YEzjwJqnPPM191VTOovcR+HnFvMi6zf6CMX
+        4FOAzQAlbAUoYztABTt9UIpdVPvwUqym2HsG4yzy1wsCAAA=
         """
-                androidx/constraintlayout/compose/MotionSceneScopeKt.class:
-                H4sIAAAAAAAA/2WQTU8CMRCG3y7yISqC32DiQe+sGm6ejGKyEVYDSkw4mLI0
-                pLC0ZLdL9Eb8Kf4MD4Z49EcZp0ZjopfpzNN3Zt72/ePlFUANuww1rvqRlv0H
-                N9AqNhGXyoT8USeGwHiiY+E2tZFatQOhRDvQE3FpsmAMxSGfcjfkauBe9YYi
-                IJpi2Lz1z+sXnl8/v/dPm/X76xZVdwxrjV9520RSDU4Yyj/Lq3+X55BlOGjo
-                aOAOhenZm9jlSmnDrZnY9bXxkzCkIaXGSJtQKrcpDO9zw4k542mKXshsoEFs
-                ZBOH+IO02SFl/SOGvfksk5/P8k6xsF8ozmcV55DdvT3dvD1nHOJWdcxoDNb/
-                /kF1ZBhWzqxrrkyHh4lg2G0lysix8NRUxrIXitNfwwz5tk6iQFzIkKTlb2nn
-                nxBHcLBgzaOCNDJUbVvzyGGHzgzxReCLlL/iFulAXbSB9EtdpDwse1ihiIKH
-                VRQ9lLDWBYuxjo0unBjpGJufnYegJwYCAAA=
-                """
     )
 
     @Test
diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionLayout.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionLayout.java
index 9da084d..1c10668 100644
--- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionLayout.java
+++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionLayout.java
@@ -1517,12 +1517,10 @@
                     mBeginState = mScene.getStartId();
                     mEndState = mScene.getEndId();
                 }
-                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT || isAttachedToWindow()) {
+                if (isAttachedToWindow()) {
                     try {
-                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-                            Display display = getDisplay();
-                            mPreviouseRotation = (display == null) ? 0 : display.getRotation();
-                        }
+                        Display display = getDisplay();
+                        mPreviouseRotation = (display == null) ? 0 : display.getRotation();
 
                         if (mScene != null) {
                             ConstraintSet cSet = mScene.getConstraintSet(mCurrentState);
@@ -1576,17 +1574,6 @@
     }
 
     /**
-     * Returns true if the provided view is currently attached to a window.
-     */
-    @Override
-    public boolean isAttachedToWindow() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return super.isAttachedToWindow();
-        }
-        return getWindowToken() != null;
-    }
-
-    /**
      * Set the State of the Constraint layout. Causing it to load a particular ConstraintSet.
      * for states with variants the variant with matching
      * width and height constraintSet will be chosen
diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/Barrier.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/Barrier.java
index 2007e11..15d7e02 100644
--- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/Barrier.java
+++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/Barrier.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.os.Build;
 import android.util.AttributeSet;
 import android.util.SparseArray;
 import android.view.View;
@@ -158,29 +157,19 @@
 
     private void updateType(ConstraintWidget widget, int type, boolean isRtl) {
         mResolvedType = type;
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            // Pre JB MR1, left/right should take precedence, unless they are
-            // not defined and somehow a corresponding start/end constraint exists
+
+        if (isRtl) {
+            if (mIndicatedType == START) {
+                mResolvedType = RIGHT;
+            } else if (mIndicatedType == END) {
+                mResolvedType = LEFT;
+            }
+        } else {
             if (mIndicatedType == START) {
                 mResolvedType = LEFT;
             } else if (mIndicatedType == END) {
                 mResolvedType = RIGHT;
             }
-        } else {
-            // Post JB MR1, if start/end are defined, they take precedence over left/right
-            if (isRtl) {
-                if (mIndicatedType == START) {
-                    mResolvedType = RIGHT;
-                } else if (mIndicatedType == END) {
-                    mResolvedType = LEFT;
-                }
-            } else {
-                if (mIndicatedType == START) {
-                    mResolvedType = LEFT;
-                } else if (mIndicatedType == END) {
-                    mResolvedType = RIGHT;
-                }
-            }
         }
         if (widget instanceof androidx.constraintlayout.core.widgets.Barrier) {
             androidx.constraintlayout.core.widgets.Barrier barrier =
diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java
index 24710a1..bfc5c8b 100644
--- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java
+++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java
@@ -1327,11 +1327,6 @@
             int resolvedGuideBegin = layoutParams.mResolvedGuideBegin;
             int resolvedGuideEnd = layoutParams.mResolvedGuideEnd;
             float resolvedGuidePercent = layoutParams.mResolvedGuidePercent;
-            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-                resolvedGuideBegin = layoutParams.guideBegin;
-                resolvedGuideEnd = layoutParams.guideEnd;
-                resolvedGuidePercent = layoutParams.guidePercent;
-            }
             if (resolvedGuidePercent != UNSET) {
                 guideline.setGuidePercent(resolvedGuidePercent);
             } else if (resolvedGuideBegin != UNSET) {
@@ -1349,33 +1344,6 @@
             int resolveGoneRightMargin = layoutParams.mResolveGoneRightMargin;
             float resolvedHorizontalBias = layoutParams.mResolvedHorizontalBias;
 
-            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-                // Pre JB MR1, left/right should take precedence, unless they are
-                // not defined and somehow a corresponding start/end constraint exists
-                resolvedLeftToLeft = layoutParams.leftToLeft;
-                resolvedLeftToRight = layoutParams.leftToRight;
-                resolvedRightToLeft = layoutParams.rightToLeft;
-                resolvedRightToRight = layoutParams.rightToRight;
-                resolveGoneLeftMargin = layoutParams.goneLeftMargin;
-                resolveGoneRightMargin = layoutParams.goneRightMargin;
-                resolvedHorizontalBias = layoutParams.horizontalBias;
-
-                if (resolvedLeftToLeft == UNSET && resolvedLeftToRight == UNSET) {
-                    if (layoutParams.startToStart != UNSET) {
-                        resolvedLeftToLeft = layoutParams.startToStart;
-                    } else if (layoutParams.startToEnd != UNSET) {
-                        resolvedLeftToRight = layoutParams.startToEnd;
-                    }
-                }
-                if (resolvedRightToLeft == UNSET && resolvedRightToRight == UNSET) {
-                    if (layoutParams.endToStart != UNSET) {
-                        resolvedRightToLeft = layoutParams.endToStart;
-                    } else if (layoutParams.endToEnd != UNSET) {
-                        resolvedRightToRight = layoutParams.endToEnd;
-                    }
-                }
-            }
-
             // Circular constraint
             if (layoutParams.circleConstraint != UNSET) {
                 ConstraintWidget target = idToWidget.get(layoutParams.circleConstraint);
diff --git a/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorLayoutTouchEventTest.java b/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorLayoutTouchEventTest.java
index 9535979..b7c7bd0 100644
--- a/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorLayoutTouchEventTest.java
+++ b/coordinatorlayout/coordinatorlayout/src/androidTest/java/androidx/coordinatorlayout/widget/CoordinatorLayoutTouchEventTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import android.os.Build;
 import android.os.SystemClock;
 import android.view.MotionEvent;
 import android.view.TouchDelegate;
@@ -560,11 +559,7 @@
         @Override
         public String toString() {
             String message = "MotionEvent#getAction() == ";
-            if (Build.VERSION.SDK_INT >= 19) {
-                return message + MotionEvent.actionToString(mAction);
-            } else {
-                return message + mAction;
-            }
+            return message + MotionEvent.actionToString(mAction);
         }
     }
 
diff --git a/core/core-graphics-integration-tests/testapp/src/main/java/androidx/core/graphics/sample/GraphicsSampleActivity.kt b/core/core-graphics-integration-tests/testapp/src/main/java/androidx/core/graphics/sample/GraphicsSampleActivity.kt
index 0c191e8..3021532 100644
--- a/core/core-graphics-integration-tests/testapp/src/main/java/androidx/core/graphics/sample/GraphicsSampleActivity.kt
+++ b/core/core-graphics-integration-tests/testapp/src/main/java/androidx/core/graphics/sample/GraphicsSampleActivity.kt
@@ -4,15 +4,12 @@
 import android.graphics.Bitmap
 import android.graphics.BitmapFactory
 import android.graphics.drawable.BitmapDrawable
-import android.os.Build
 import android.os.Bundle
 import android.view.View
 import android.widget.ImageView
-import androidx.annotation.RequiresApi
 import androidx.core.graphics.BitmapCompat
 
 class GraphicsSampleActivity : Activity() {
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.main_activity)
diff --git a/core/core-ktx/src/main/java/androidx/core/os/Bundle.kt b/core/core-ktx/src/main/java/androidx/core/os/Bundle.kt
index 9bda3bb..601fbf8 100644
--- a/core/core-ktx/src/main/java/androidx/core/os/Bundle.kt
+++ b/core/core-ktx/src/main/java/androidx/core/os/Bundle.kt
@@ -91,8 +91,8 @@
             is Serializable -> putSerializable(key, value)
 
             else -> {
-                if (Build.VERSION.SDK_INT >= 18 && value is IBinder) {
-                    BundleApi18ImplKt.putBinder(this, key, value)
+                if (value is IBinder) {
+                    this.putBinder(key, value)
                 } else if (Build.VERSION.SDK_INT >= 21 && value is Size) {
                     BundleApi21ImplKt.putSize(this, key, value)
                 } else if (Build.VERSION.SDK_INT >= 21 && value is SizeF) {
@@ -111,13 +111,6 @@
  */
 public fun bundleOf(): Bundle = Bundle(0)
 
-@RequiresApi(18)
-private object BundleApi18ImplKt {
-    @DoNotInline
-    @JvmStatic
-    fun putBinder(bundle: Bundle, key: String, value: IBinder?) = bundle.putBinder(key, value)
-}
-
 @RequiresApi(21)
 private object BundleApi21ImplKt {
     @DoNotInline
diff --git a/core/core-remoteviews/src/main/java/androidx/core/widget/AppWidgetManagerCompat.kt b/core/core-remoteviews/src/main/java/androidx/core/widget/AppWidgetManagerCompat.kt
index 797dd21..4573d74f 100644
--- a/core/core-remoteviews/src/main/java/androidx/core/widget/AppWidgetManagerCompat.kt
+++ b/core/core-remoteviews/src/main/java/androidx/core/widget/AppWidgetManagerCompat.kt
@@ -99,14 +99,7 @@
                 factory
             )
         }
-        SDK_INT >= 16 -> {
-            AppWidgetManagerApi16Impl.createExactSizeAppWidget(
-                appWidgetManager,
-                appWidgetId,
-                factory
-            )
-        }
-        else -> createAppWidgetFromProviderInfo(appWidgetManager, appWidgetId, factory)
+        else -> createExactSizeAppWidgetInner(appWidgetManager, appWidgetId, factory)
     }
 }
 
@@ -175,15 +168,7 @@
     require(dpSizes.size <= 16) { "At most 16 sizes may be provided" }
     return when {
         SDK_INT >= 31 -> AppWidgetManagerApi31Impl.createResponsiveSizeAppWidget(dpSizes, factory)
-        SDK_INT >= 16 -> {
-            AppWidgetManagerApi16Impl.createResponsiveSizeAppWidget(
-                appWidgetManager,
-                appWidgetId,
-                dpSizes,
-                factory
-            )
-        }
-        else -> createAppWidgetFromProviderInfo(appWidgetManager, appWidgetId, factory)
+        else -> createResponsiveSizeAppWidgetInner(appWidgetManager, appWidgetId, dpSizes, factory)
     }
 }
 
@@ -208,11 +193,7 @@
                 "App widget SizeF sizes not found in the options bundle, falling back to the " +
                     "min/max sizes"
             )
-            return AppWidgetManagerApi16Impl.createExactSizeAppWidget(
-                appWidgetManager,
-                appWidgetId,
-                factory
-            )
+            return createExactSizeAppWidgetInner(appWidgetManager, appWidgetId, factory)
         }
         return RemoteViews(sizes.associateWith { factory(it.toSizeFCompat()) })
     }
@@ -228,90 +209,85 @@
     private fun SizeF.toSizeFCompat() = SizeFCompat.toSizeFCompat(this)
 }
 
-@RequiresApi(16)
-private object AppWidgetManagerApi16Impl {
-    @DoNotInline
-    fun createExactSizeAppWidget(
-        appWidgetManager: AppWidgetManager,
-        appWidgetId: Int,
-        factory: (SizeFCompat) -> RemoteViews
-    ): RemoteViews {
-        val (landscapeSize, portraitSize) =
-            getSizesFromOptionsBundle(appWidgetManager, appWidgetId)
-                ?: run {
-                    Log.w(
-                        LogTag,
-                        "App widget sizes not found in the options bundle, falling back to the " +
-                            "provider size"
-                    )
-                    return createAppWidgetFromProviderInfo(appWidgetManager, appWidgetId, factory)
-                }
-        return createAppWidget(landscapeSize = landscapeSize, portraitSize = portraitSize, factory)
-    }
+internal fun createExactSizeAppWidgetInner(
+    appWidgetManager: AppWidgetManager,
+    appWidgetId: Int,
+    factory: (SizeFCompat) -> RemoteViews
+): RemoteViews {
+    val (landscapeSize, portraitSize) =
+        getSizesFromOptionsBundle(appWidgetManager, appWidgetId)
+            ?: run {
+                Log.w(
+                    LogTag,
+                    "App widget sizes not found in the options bundle, falling back to the " +
+                        "provider size"
+                )
+                return createAppWidgetFromProviderInfo(appWidgetManager, appWidgetId, factory)
+            }
+    return createAppWidget(landscapeSize = landscapeSize, portraitSize = portraitSize, factory)
+}
 
-    @DoNotInline
-    fun createResponsiveSizeAppWidget(
-        appWidgetManager: AppWidgetManager,
-        appWidgetId: Int,
-        sizes: Collection<SizeFCompat>,
-        factory: (SizeFCompat) -> RemoteViews
-    ): RemoteViews {
-        val minSize = sizes.minByOrNull { it.area } ?: error("Sizes cannot be empty")
-        val (landscapeSize, portraitSize) =
-            getSizesFromOptionsBundle(appWidgetManager, appWidgetId)
-                ?: run {
-                    Log.w(
-                        LogTag,
-                        "App widget sizes not found in the options bundle, falling back to the " +
-                            "smallest supported size ($minSize)"
-                    )
-                    LandscapePortraitSizes(minSize, minSize)
-                }
-        val effectiveLandscapeSize =
-            sizes.filter { landscapeSize approxDominates it }.maxByOrNull { it.area } ?: minSize
-        val effectivePortraitSize =
-            sizes.filter { portraitSize approxDominates it }.maxByOrNull { it.area } ?: minSize
-        return createAppWidget(
-            landscapeSize = effectiveLandscapeSize,
-            portraitSize = effectivePortraitSize,
-            factory
+internal fun createResponsiveSizeAppWidgetInner(
+    appWidgetManager: AppWidgetManager,
+    appWidgetId: Int,
+    sizes: Collection<SizeFCompat>,
+    factory: (SizeFCompat) -> RemoteViews
+): RemoteViews {
+    val minSize = sizes.minByOrNull { it.area } ?: error("Sizes cannot be empty")
+    val (landscapeSize, portraitSize) =
+        getSizesFromOptionsBundle(appWidgetManager, appWidgetId)
+            ?: run {
+                Log.w(
+                    LogTag,
+                    "App widget sizes not found in the options bundle, falling back to the " +
+                        "smallest supported size ($minSize)"
+                )
+                LandscapePortraitSizes(minSize, minSize)
+            }
+    val effectiveLandscapeSize =
+        sizes.filter { landscapeSize approxDominates it }.maxByOrNull { it.area } ?: minSize
+    val effectivePortraitSize =
+        sizes.filter { portraitSize approxDominates it }.maxByOrNull { it.area } ?: minSize
+    return createAppWidget(
+        landscapeSize = effectiveLandscapeSize,
+        portraitSize = effectivePortraitSize,
+        factory
+    )
+}
+
+private fun createAppWidget(
+    landscapeSize: SizeFCompat,
+    portraitSize: SizeFCompat,
+    factory: (SizeFCompat) -> RemoteViews
+): RemoteViews {
+    return if (landscapeSize == portraitSize) {
+        factory(landscapeSize)
+    } else {
+        RemoteViews(
+            /* landscape= */ factory(landscapeSize),
+            /* portrait= */ factory(portraitSize)
         )
     }
+}
 
-    private fun createAppWidget(
-        landscapeSize: SizeFCompat,
-        portraitSize: SizeFCompat,
-        factory: (SizeFCompat) -> RemoteViews
-    ): RemoteViews {
-        return if (landscapeSize == portraitSize) {
-            factory(landscapeSize)
-        } else {
-            RemoteViews(
-                /* landscape= */ factory(landscapeSize),
-                /* portrait= */ factory(portraitSize)
-            )
-        }
-    }
+private fun getSizesFromOptionsBundle(
+    appWidgetManager: AppWidgetManager,
+    appWidgetId: Int
+): LandscapePortraitSizes? {
+    val options = appWidgetManager.getAppWidgetOptions(appWidgetId)
 
-    private fun getSizesFromOptionsBundle(
-        appWidgetManager: AppWidgetManager,
-        appWidgetId: Int
-    ): LandscapePortraitSizes? {
-        val options = appWidgetManager.getAppWidgetOptions(appWidgetId)
+    val portWidthDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, -1)
+    val portHeightDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, -1)
+    if (portWidthDp < 0 || portHeightDp < 0) return null
 
-        val portWidthDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, -1)
-        val portHeightDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, -1)
-        if (portWidthDp < 0 || portHeightDp < 0) return null
+    val landWidthDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, -1)
+    val landHeightDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, -1)
+    if (landWidthDp < 0 || landHeightDp < 0) return null
 
-        val landWidthDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, -1)
-        val landHeightDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, -1)
-        if (landWidthDp < 0 || landHeightDp < 0) return null
-
-        return LandscapePortraitSizes(
-            landscape = SizeFCompat(landWidthDp.toFloat(), landHeightDp.toFloat()),
-            portrait = SizeFCompat(portWidthDp.toFloat(), portHeightDp.toFloat())
-        )
-    }
+    return LandscapePortraitSizes(
+        landscape = SizeFCompat(landWidthDp.toFloat(), landHeightDp.toFloat()),
+        portrait = SizeFCompat(portWidthDp.toFloat(), portHeightDp.toFloat())
+    )
 }
 
 internal fun createAppWidgetFromProviderInfo(
diff --git a/core/core-remoteviews/src/main/java/androidx/core/widget/RemoteViewsCompat.kt b/core/core-remoteviews/src/main/java/androidx/core/widget/RemoteViewsCompat.kt
index b39eeef1..7924af8 100644
--- a/core/core-remoteviews/src/main/java/androidx/core/widget/RemoteViewsCompat.kt
+++ b/core/core-remoteviews/src/main/java/androidx/core/widget/RemoteViewsCompat.kt
@@ -728,8 +728,7 @@
     @JvmStatic
     public fun RemoteViews.setImageViewImageAlpha(@IdRes viewId: Int, alpha: Int) {
         // Note: setImageAlpha was added and is preferred to setAlpha since API 16.
-        val methodName = if (Build.VERSION.SDK_INT >= 16) "setImageAlpha" else "setAlpha"
-        setInt(viewId, methodName, alpha)
+        setInt(viewId, "setImageAlpha", alpha)
     }
 
     /**
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 3cd47b6..1f15519 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -4016,9 +4016,11 @@
     method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
     method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
     method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static boolean isStylusHandwritingEnabled(android.view.inputmethod.EditorInfo);
     method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
     method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
     method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
+    method public static void setStylusHandwritingEnabled(android.view.inputmethod.EditorInfo, boolean);
     field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
     field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
   }
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index 34cf16c..c221686 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -4506,9 +4506,11 @@
     method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
     method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
     method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static boolean isStylusHandwritingEnabled(android.view.inputmethod.EditorInfo);
     method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
     method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
     method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
+    method public static void setStylusHandwritingEnabled(android.view.inputmethod.EditorInfo, boolean);
     field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
     field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
   }
diff --git a/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
index 454cfcd..d0e1c235 100644
--- a/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
@@ -286,21 +286,15 @@
         NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
 
         Notification nDefault = builder.build();
-        if (Build.VERSION.SDK_INT >= 19) {
-            assertThat(NotificationCompat.getShowWhen(nDefault)).isTrue();
-        }
+        assertThat(NotificationCompat.getShowWhen(nDefault)).isTrue();
 
         // test true
         Notification nTrue = builder.setShowWhen(true).build();
-        if (Build.VERSION.SDK_INT >= 19) {
-            assertTrue(NotificationCompat.getShowWhen(nTrue));
-        }
+        assertTrue(NotificationCompat.getShowWhen(nTrue));
 
         // test false
         Notification nFalse = builder.setShowWhen(false).build();
-        if (Build.VERSION.SDK_INT >= 19) {
-            assertFalse(NotificationCompat.getShowWhen(nFalse));
-        }
+        assertFalse(NotificationCompat.getShowWhen(nFalse));
     }
 
     @Test
@@ -309,15 +303,11 @@
 
         // test true
         Notification nTrue = builder.setUsesChronometer(true).build();
-        if (Build.VERSION.SDK_INT >= 19) {
-            assertTrue(NotificationCompat.getUsesChronometer(nTrue));
-        }
+        assertTrue(NotificationCompat.getUsesChronometer(nTrue));
 
         // test false
         Notification nFalse = builder.setUsesChronometer(false).build();
-        if (Build.VERSION.SDK_INT >= 19) {
-            assertFalse(NotificationCompat.getUsesChronometer(nFalse));
-        }
+        assertFalse(NotificationCompat.getUsesChronometer(nFalse));
     }
 
     @SdkSuppress(minSdkVersion = 24)
@@ -686,12 +676,6 @@
         // Add an action so that we start getting the view
         builder.addAction(new NotificationCompat.Action(null, "action", null));
 
-        // Before Jellybean, there was no big view; expect null
-        if (Build.VERSION.SDK_INT < 16) {
-            assertNull(builder.createHeadsUpContentView());
-            return;
-        }
-
         // Expect the standard big notification template
         RemoteViews standardView = builder.createBigContentView();
         assertNotNull(standardView);
@@ -1140,16 +1124,13 @@
                 .setLargeIcon((Bitmap) null)
                 .build();
 
-        // Extras are not populated before API 19.
-        if (Build.VERSION.SDK_INT >= 19) {
-            Bundle extras = NotificationCompat.getExtras(n);
-            assertNotNull(extras);
-            if (Build.VERSION.SDK_INT <= 23) {
-                assertFalse(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON));
-            } else {
-                assertTrue(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON));
-                assertNull(extras.get(NotificationCompat.EXTRA_LARGE_ICON));
-            }
+        Bundle extras = NotificationCompat.getExtras(n);
+        assertNotNull(extras);
+        if (Build.VERSION.SDK_INT <= 23) {
+            assertFalse(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON));
+        } else {
+            assertTrue(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON));
+            assertNull(extras.get(NotificationCompat.EXTRA_LARGE_ICON));
         }
 
         if (Build.VERSION.SDK_INT >= 23) {
@@ -1167,12 +1148,10 @@
                 .build();
 
         // Extras are not populated before API 19.
-        if (Build.VERSION.SDK_INT >= 19) {
-            Bundle extras = NotificationCompat.getExtras(n);
-            assertNotNull(extras);
-            assertTrue(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON));
-            assertNotNull(extras.get(NotificationCompat.EXTRA_LARGE_ICON));
-        }
+        Bundle extras = NotificationCompat.getExtras(n);
+        assertNotNull(extras);
+        assertTrue(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON));
+        assertNotNull(extras.get(NotificationCompat.EXTRA_LARGE_ICON));
         if (Build.VERSION.SDK_INT >= 23) {
             assertNotNull(n.getLargeIcon());
         }
@@ -1570,13 +1549,10 @@
                         .setBigContentTitle("Big Content Title")
                         .setSummaryText("Summary Text"))
                 .build();
-        // Extras are not populated before KITKAT
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            Bundle extras = NotificationCompat.getExtras(n);
-            assertNotNull(extras);
-            assertTrue(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON_BIG));
-            assertNull(extras.get(NotificationCompat.EXTRA_LARGE_ICON_BIG));
-        }
+        Bundle extras = NotificationCompat.getExtras(n);
+        assertNotNull(extras);
+        assertTrue(extras.containsKey(NotificationCompat.EXTRA_LARGE_ICON_BIG));
+        assertNull(extras.get(NotificationCompat.EXTRA_LARGE_ICON_BIG));
     }
 
     @SdkSuppress(minSdkVersion = 23)
@@ -2776,25 +2752,22 @@
 
         // Test extras values. This is equivalent to creating a new NotificationCompat.Builder,
         // and checking the values in it (because those are created via restoreFromCompatExtras).
-        // Extras and NotificationCompatBuilder only available on API 19 and greater.
-        if (Build.VERSION.SDK_INT >= 19) {
-            Bundle extras = notification.extras;
+        Bundle extras = notification.extras;
 
-            // Checks that the notification title is set to the caller name. 11 >=
-            assertEquals("test name", extras.getCharSequence(NotificationCompat.EXTRA_TITLE));
-            // Checks that the notification text is set to the default text (since EXTRA_TEXT isn't
-            // set).
-            assertEquals(
-                    mContext.getResources().getString(R.string.call_notification_incoming_text),
-                    extras.getCharSequence(NotificationCompat.EXTRA_TEXT));
+        // Checks that the notification title is set to the caller name. 11 >=
+        assertEquals("test name", extras.getCharSequence(NotificationCompat.EXTRA_TITLE));
+        // Checks that the notification text is set to the default text (since EXTRA_TEXT isn't
+        // set).
+        assertEquals(
+                mContext.getResources().getString(R.string.call_notification_incoming_text),
+                extras.getCharSequence(NotificationCompat.EXTRA_TEXT));
 
-            // Create a new NotificationCompat Builder object based on the notification.
-            // This allows us to inspect various fields, including actions.
-            NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
-                    notification);
-            // For versions above 11, the "Person" name from the style is applied to the title.
-            assertEquals("test name", builder.mContentTitle);
-        }
+        // Create a new NotificationCompat Builder object based on the notification.
+        // This allows us to inspect various fields, including actions.
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
+                notification);
+        // For versions above 11, the "Person" name from the style is applied to the title.
+        assertEquals("test name", builder.mContentTitle);
 
         if (Build.VERSION.SDK_INT >= 20) {
             assertNotNull(notification.actions);
@@ -2846,13 +2819,11 @@
 
         // Checks in this section check values in the Notification's extras, which were unavailable
         // prior to API 19.
-        if (Build.VERSION.SDK_INT >= 19) {
-            NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
-                    notification);
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
+                notification);
 
-            Bundle extras = builder.getExtras();
-            assertTrue(extras.getBoolean(NotificationCompat.EXTRA_CALL_IS_VIDEO));
-        }
+        Bundle extras = builder.getExtras();
+        assertTrue(extras.getBoolean(NotificationCompat.EXTRA_CALL_IS_VIDEO));
 
         // Actions were introduced in API 20.
         if (Build.VERSION.SDK_INT >= 20) {
@@ -2897,27 +2868,25 @@
 
         // Checks in this section check values in the Notification's extras, which were unavailable
         // prior to API 19.
-        if (Build.VERSION.SDK_INT >= 19) {
-            // Test extras values. This is equivalent to creating a new NotificationCompat.Builder,
-            // and checking the values in it (as those are created via restoreFromCompatExtras).
-            Bundle extras = notification.extras;
+        // Test extras values. This is equivalent to creating a new NotificationCompat.Builder,
+        // and checking the values in it (as those are created via restoreFromCompatExtras).
+        Bundle extras = notification.extras;
 
-            // Checks that the notification title is set to the caller name. 11 >=
-            assertEquals("test name", extras.getCharSequence(NotificationCompat.EXTRA_TITLE));
+        // Checks that the notification title is set to the caller name. 11 >=
+        assertEquals("test name", extras.getCharSequence(NotificationCompat.EXTRA_TITLE));
 
-            // Checks that the notification text is set to the default text (since EXTRA_TEXT isn't
-            // set). 11 >=
-            assertEquals(mContext.getResources().getString(R.string.call_notification_ongoing_text),
-                    extras.getCharSequence(NotificationCompat.EXTRA_TEXT));
+        // Checks that the notification text is set to the default text (since EXTRA_TEXT isn't
+        // set). 11 >=
+        assertEquals(mContext.getResources().getString(R.string.call_notification_ongoing_text),
+                extras.getCharSequence(NotificationCompat.EXTRA_TEXT));
 
-            // Create a new NotificationCompat Builder object based on the notification.
-            // This allows us to inspect various fields, including actions.
-            NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
-                    notification);
+        // Create a new NotificationCompat Builder object based on the notification.
+        // This allows us to inspect various fields, including actions.
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
+                notification);
 
-            // For versions above 11, the "Person" name from the style is applied to the title.
-            assertEquals("test name", builder.mContentTitle);
-        }
+        // For versions above 11, the "Person" name from the style is applied to the title.
+        assertEquals("test name", builder.mContentTitle);
 
         // Actions were introduced in API 20.
         if (Build.VERSION.SDK_INT >= 20) {
@@ -2965,28 +2934,27 @@
 
         // Checks in this section check values in the Notification's extras, which were unavailable
         // prior to API 19.
-        if (Build.VERSION.SDK_INT >= 19) {
-            // Test extras values. This is equivalent to creating a new NotificationCompat.Builder,
-            // and checking the values in it (as those are created via restoreFromCompatExtras).
-            Bundle extras = notification.extras;
+        // Test extras values. This is equivalent to creating a new NotificationCompat.Builder,
+        // and checking the values in it (as those are created via restoreFromCompatExtras).
+        Bundle extras = notification.extras;
 
-            // Checks that the notification title is set to the caller name. 11 >=
-            assertEquals("test name", extras.getCharSequence(NotificationCompat.EXTRA_TITLE));
+        // Checks that the notification title is set to the caller name. 11 >=
+        assertEquals("test name", extras.getCharSequence(NotificationCompat.EXTRA_TITLE));
 
-            // Checks that the notification text is set to the default text (since EXTRA_TEXT isn't
-            // set). 11 >=
-            assertEquals(
-                    mContext.getResources().getString(R.string.call_notification_screening_text),
-                    extras.getCharSequence(NotificationCompat.EXTRA_TEXT));
+        // Checks that the notification text is set to the default text (since EXTRA_TEXT isn't
+        // set). 11 >=
+        assertEquals(
+                mContext.getResources().getString(R.string.call_notification_screening_text),
+                extras.getCharSequence(NotificationCompat.EXTRA_TEXT));
 
-            // Create a new NotificationCompat Builder object based on the notification.
-            // This allows us to inspect various fields, including actions.
-            NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
-                    notification);
+        // Create a new NotificationCompat Builder object based on the notification.
+        // This allows us to inspect various fields, including actions.
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,
+                notification);
 
-            // For versions above 11, the "Person" name from the style is applied to the title.
-            assertEquals("test name", builder.mContentTitle);
-        }
+        // For versions above 11, the "Person" name from the style is applied to the title.
+        assertEquals("test name", builder.mContentTitle);
+
 
         // Actions were introduced in API 20.
         if (Build.VERSION.SDK_INT >= 20) {
@@ -3569,10 +3537,8 @@
 
         // before testing the notification we've built with people, test the clearPeople() method
         final Notification notificationWithoutPeople = builder.clearPeople().build();
-        if (Build.VERSION.SDK_INT >= 19) {
-            assertNull(notificationWithoutPeople.extras.get(NotificationCompat.EXTRA_PEOPLE));
-            assertNull(notificationWithoutPeople.extras.get(NotificationCompat.EXTRA_PEOPLE_LIST));
-        }
+        assertNull(notificationWithoutPeople.extras.get(NotificationCompat.EXTRA_PEOPLE));
+        assertNull(notificationWithoutPeople.extras.get(NotificationCompat.EXTRA_PEOPLE_LIST));
 
         if (Build.VERSION.SDK_INT >= 29) {
             assertNull(notificationWithoutPeople.extras.get(NotificationCompat.EXTRA_PEOPLE));
@@ -3598,7 +3564,7 @@
             expected.add("test name\tnull");
             expected.add("test name 2\tnull");
             assertEquals(expected, people);
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else {
             assertNull(notificationWithoutPeople.extras.get(NotificationCompat.EXTRA_PEOPLE_LIST));
             final String[] peopleArray =
                     notification.extras.getStringArray(Notification.EXTRA_PEOPLE);
@@ -3624,7 +3590,7 @@
             expected.add("test name\tnull");
             expected.add("test name 2\tnull");
             expected.add("null\ttest:selfUri");
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else {
             // On older platforms, the name is converted into a URI
             expected.add("null\tname:test name");
             expected.add("null\tname:test name 2");
diff --git a/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java
index d612ba4..ebe6103 100644
--- a/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java
@@ -48,10 +48,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
-import android.os.Build;
 import android.os.UserManager;
 
-import androidx.annotation.RequiresApi;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
@@ -317,7 +315,6 @@
      * Setup applications with the verifier role can handle unused app restriction features. In
      * this case, they are permission revocation apps.
      */
-    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     @SuppressWarnings("deprecation")
     static void setupPermissionRevocationApps(
             PackageManager packageManager, List<String> packageNames) {
diff --git a/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java
index 16c5ef7..e877a26 100644
--- a/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java
@@ -179,8 +179,7 @@
         // For pre-v15 devices we should get a drawable that corresponds to the density of the
         // current device. For v15+ devices we should get a drawable that corresponds to the
         // density requested in the API call.
-        final int expectedSizeForMediumDensity = (SDK_INT < 15) ?
-                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 12;
+        final int expectedSizeForMediumDensity = 12;
         assertEquals("Unthemed density-aware drawable load: medium width",
                 expectedSizeForMediumDensity, unthemedDrawableForMediumDensity.getIntrinsicWidth());
         assertEquals("Unthemed density-aware drawable load: medium height",
@@ -190,11 +189,8 @@
         final Drawable unthemedDrawableForHighDensity =
                 ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
                         DisplayMetrics.DENSITY_HIGH, null);
-        // For pre-v15 devices we should get a drawable that corresponds to the density of the
-        // current device. For v15+ devices we should get a drawable that corresponds to the
-        // density requested in the API call.
-        final int expectedSizeForHighDensity = (SDK_INT < 15) ?
-                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 21;
+
+        final int expectedSizeForHighDensity = 21;
         assertEquals("Unthemed density-aware drawable load: high width",
                 expectedSizeForHighDensity, unthemedDrawableForHighDensity.getIntrinsicWidth());
         assertEquals("Unthemed density-aware drawable load: high height",
@@ -203,11 +199,8 @@
         final Drawable unthemedDrawableForXHighDensity =
                 ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
                         DisplayMetrics.DENSITY_XHIGH, null);
-        // For pre-v15 devices we should get a drawable that corresponds to the density of the
-        // current device. For v15+ devices we should get a drawable that corresponds to the
-        // density requested in the API call.
-        final int expectedSizeForXHighDensity = (SDK_INT < 15) ?
-                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 32;
+
+        final int expectedSizeForXHighDensity = 32;
         assertEquals("Unthemed density-aware drawable load: xhigh width",
                 expectedSizeForXHighDensity, unthemedDrawableForXHighDensity.getIntrinsicWidth());
         assertEquals("Unthemed density-aware drawable load: xhigh height",
@@ -216,11 +209,8 @@
         final Drawable unthemedDrawableForXXHighDensity =
                 ResourcesCompat.getDrawableForDensity(mResources, R.drawable.density_aware_drawable,
                         DisplayMetrics.DENSITY_XXHIGH, null);
-        // For pre-v15 devices we should get a drawable that corresponds to the density of the
-        // current device. For v15+ devices we should get a drawable that corresponds to the
-        // density requested in the API call.
-        final int expectedSizeForXXHighDensity = (SDK_INT < 15) ?
-                mResources.getDimensionPixelSize(R.dimen.density_aware_size) : 54;
+
+        final int expectedSizeForXXHighDensity = 54;
         assertEquals("Unthemed density-aware drawable load: xxhigh width",
                 expectedSizeForXXHighDensity, unthemedDrawableForXXHighDensity.getIntrinsicWidth());
         assertEquals("Unthemed density-aware drawable load: xxhigh height",
diff --git a/core/core/src/androidTest/java/androidx/core/graphics/BitmapCompatTest.java b/core/core/src/androidTest/java/androidx/core/graphics/BitmapCompatTest.java
index 0c5e39a..ae50a71 100644
--- a/core/core/src/androidTest/java/androidx/core/graphics/BitmapCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/graphics/BitmapCompatTest.java
@@ -30,7 +30,6 @@
 import android.hardware.HardwareBuffer;
 import android.os.Build;
 
-import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
@@ -39,7 +38,6 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-@RequiresApi(api = Build.VERSION_CODES.KITKAT)
 @SmallTest
 public class BitmapCompatTest {
 
@@ -381,7 +379,6 @@
     // For a resize smaller than 1/2 of the original dimensions, the result should basically be
     // uniform grey, so the higher quality the resize, the lower the variance in grey values is
     // expected to be.
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     private void scaledBitmapAndAssertQuality(int scaledWidth, int scaledHeight,
             boolean scaleInLinearSpace,
             float expectedMeanValue, float expectedVariance, Bitmap.Config inputConfig) {
@@ -435,7 +432,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     public void testQualityDownscaleNonLinear() {
         scaledBitmapAndAssertQuality(19, 19, false, 127.0f, DOWNSCALE_VARIANCE,
                 Bitmap.Config.ARGB_8888);
@@ -449,7 +445,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     public void testQualityUpscaleNonLinear() {
         scaledBitmapAndAssertQuality(1213, 1213, false, 127.0f, UPSCALE_VARIANCE,
                 Bitmap.Config.ARGB_8888);
diff --git a/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatUtilTest.java b/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatUtilTest.java
index 245f6c5..e282798 100644
--- a/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatUtilTest.java
+++ b/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatUtilTest.java
@@ -20,7 +20,6 @@
 import android.content.ContentUris;
 import android.content.Context;
 import android.net.Uri;
-import android.os.Build;
 
 import androidx.annotation.RequiresApi;
 import androidx.core.provider.MockFontProvider;
@@ -43,10 +42,6 @@
     @Test
     @RequiresApi(19)
     public void testMmapNullPfd() {
-        if (Build.VERSION.SDK_INT < 19) {
-            // The API tested here requires SDK level 19.
-            return;
-        }
         final Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                 .authority(MockFontProvider.AUTHORITY).build();
         final Uri fileUri = ContentUris.withAppendedId(uri, MockFontProvider.INVALID_FONT_FILE_ID);
diff --git a/core/core/src/androidTest/java/androidx/core/location/LocationCompatTest.java b/core/core/src/androidTest/java/androidx/core/location/LocationCompatTest.java
index 2c9770b..6cf5ee3 100644
--- a/core/core/src/androidTest/java/androidx/core/location/LocationCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/location/LocationCompatTest.java
@@ -25,7 +25,6 @@
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
 import android.location.Location;
-import android.os.Build;
 import android.os.SystemClock;
 
 import androidx.test.filters.SmallTest;
@@ -40,16 +39,10 @@
     @Test
     public void testGetElapsedRealtimeNanos() {
         long locationElapsedRealtimeNs;
-        if (Build.VERSION.SDK_INT >= 17) {
-            locationElapsedRealtimeNs = SystemClock.elapsedRealtimeNanos();
-        } else {
-            locationElapsedRealtimeNs = MILLISECONDS.toNanos(SystemClock.elapsedRealtime());
-        }
+        locationElapsedRealtimeNs = SystemClock.elapsedRealtimeNanos();
 
         Location location = new Location("");
-        if (Build.VERSION.SDK_INT >= 17) {
-            location.setElapsedRealtimeNanos(locationElapsedRealtimeNs);
-        }
+        location.setElapsedRealtimeNanos(locationElapsedRealtimeNs);
         location.setTime(System.currentTimeMillis());
 
         assertTrue(NANOSECONDS.toMillis(Math.abs(
@@ -62,9 +55,7 @@
         long locationElapsedRealtimeMs = SystemClock.elapsedRealtime();
 
         Location location = new Location("");
-        if (Build.VERSION.SDK_INT >= 17) {
-            location.setElapsedRealtimeNanos(MILLISECONDS.toNanos(locationElapsedRealtimeMs));
-        }
+        location.setElapsedRealtimeNanos(MILLISECONDS.toNanos(locationElapsedRealtimeMs));
         location.setTime(System.currentTimeMillis());
 
         assertTrue(Math.abs(
diff --git a/core/core/src/androidTest/java/androidx/core/location/LocationManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/location/LocationManagerCompatTest.java
index b95610f..ba8bf19 100644
--- a/core/core/src/androidTest/java/androidx/core/location/LocationManagerCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/location/LocationManagerCompatTest.java
@@ -33,7 +33,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings;
-import android.text.TextUtils;
 
 import androidx.core.os.ExecutorCompat;
 import androidx.test.core.app.ApplicationProvider;
@@ -63,13 +62,9 @@
         boolean isLocationEnabled;
         if (VERSION.SDK_INT >= 28) {
             isLocationEnabled = mLocationManager.isLocationEnabled();
-        } else if (VERSION.SDK_INT >= 19) {
+        } else {
             isLocationEnabled = Settings.Secure.getInt(mContext.getContentResolver(), LOCATION_MODE,
                     LOCATION_MODE_OFF) != LOCATION_MODE_OFF;
-        } else {
-            isLocationEnabled = !TextUtils.isEmpty(
-                    Settings.Secure.getString(mContext.getContentResolver(),
-                            Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
         }
 
         assertEquals(isLocationEnabled, LocationManagerCompat.isLocationEnabled(mLocationManager));
diff --git a/core/core/src/androidTest/java/androidx/core/provider/DocumentsContractCompatTest.kt b/core/core/src/androidTest/java/androidx/core/provider/DocumentsContractCompatTest.kt
index e5ab057..6fd9d1f 100644
--- a/core/core/src/androidTest/java/androidx/core/provider/DocumentsContractCompatTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/provider/DocumentsContractCompatTest.kt
@@ -48,25 +48,16 @@
 
     @Test
     fun testBuildChildDocumentsUri() {
-        if (isAtLeastKitKat()) {
-            assertEquals(
-                DocumentsContractCompat.buildChildDocumentsUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                ),
-                DocumentsContract.buildChildDocumentsUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                )
+        assertEquals(
+            DocumentsContractCompat.buildChildDocumentsUri(
+                EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
+                DOWNLOAD_DOCID
+            ),
+            DocumentsContract.buildChildDocumentsUri(
+                EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
+                DOWNLOAD_DOCID
             )
-        } else {
-            assertNull(
-                DocumentsContractCompat.buildChildDocumentsUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                )
-            )
-        }
+        )
     }
 
     @Test
@@ -95,25 +86,16 @@
 
     @Test
     fun testBuildDocumentUri() {
-        if (isAtLeastKitKat()) {
-            assertEquals(
-                DocumentsContractCompat.buildDocumentUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                ),
-                DocumentsContract.buildDocumentUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                )
+        assertEquals(
+            DocumentsContractCompat.buildDocumentUri(
+                EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
+                DOWNLOAD_DOCID
+            ),
+            DocumentsContract.buildDocumentUri(
+                EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
+                DOWNLOAD_DOCID
             )
-        } else {
-            assertNull(
-                DocumentsContractCompat.buildDocumentUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                )
-            )
-        }
+        )
     }
 
     @Test
@@ -159,20 +141,15 @@
 
     @Test
     fun testGetDocumentId() {
-        if (isAtLeastKitKat()) {
-            val documentUri =
-                DocumentsContract.buildDocumentUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                )
-            assertEquals(
-                DocumentsContractCompat.getDocumentId(documentUri),
-                DocumentsContract.getDocumentId(documentUri)
+        val documentUri =
+            DocumentsContract.buildDocumentUri(
+                EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
+                DOWNLOAD_DOCID
             )
-        } else {
-            val documentUri = buildDocUri(EXTERNAL_STORAGE_PROVIDER_AUTHORITY, DOWNLOAD_DOCID)
-            assertNull(DocumentsContractCompat.getDocumentId(documentUri))
-        }
+        assertEquals(
+            DocumentsContractCompat.getDocumentId(documentUri),
+            DocumentsContract.getDocumentId(documentUri)
+        )
     }
 
     @Test
@@ -247,19 +224,12 @@
         val mediaStoreUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
         assertFalse(DocumentsContractCompat.isDocumentUri(context, mediaStoreUri))
 
-        if (isAtLeastKitKat()) {
-            val documentUri =
-                DocumentsContract.buildDocumentUri(
-                    EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
-                    DOWNLOAD_DOCID
-                )
-            assertTrue(DocumentsContractCompat.isDocumentUri(context, documentUri))
-        } else {
-            val documentUri = buildDocUri(EXTERNAL_STORAGE_PROVIDER_AUTHORITY, DOWNLOAD_DOCID)
-
-            // DocumentsProvider doesn't exist before KitKat.
-            assertFalse(DocumentsContractCompat.isDocumentUri(context, documentUri))
-        }
+        val documentUri =
+            DocumentsContract.buildDocumentUri(
+                EXTERNAL_STORAGE_PROVIDER_AUTHORITY,
+                DOWNLOAD_DOCID
+            )
+        assertTrue(DocumentsContractCompat.isDocumentUri(context, documentUri))
 
         if (isAtLeastLollipop()) {
             val downloadTree =
@@ -283,7 +253,6 @@
         }
     }
 
-    private fun isAtLeastKitKat() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
     private fun isAtLeastLollipop() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
 
     /** Helper method that works similar to [DocumentsContract.buildDocumentUri]. */
diff --git a/core/core/src/androidTest/java/androidx/core/view/MarginLayoutParamsCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/MarginLayoutParamsCompatTest.java
index 77676e7..7289810 100644
--- a/core/core/src/androidTest/java/androidx/core/view/MarginLayoutParamsCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/MarginLayoutParamsCompatTest.java
@@ -37,14 +37,8 @@
                 MarginLayoutParamsCompat.getLayoutDirection(mlp));
 
         MarginLayoutParamsCompat.setLayoutDirection(mlp, ViewCompat.LAYOUT_DIRECTION_RTL);
-        if (Build.VERSION.SDK_INT >= 17) {
-            assertEquals("RTL layout direction", ViewCompat.LAYOUT_DIRECTION_RTL,
-                    MarginLayoutParamsCompat.getLayoutDirection(mlp));
-        } else {
-            assertEquals("Still LTR layout direction on older devices",
-                    ViewCompat.LAYOUT_DIRECTION_LTR,
-                    MarginLayoutParamsCompat.getLayoutDirection(mlp));
-        }
+        assertEquals("RTL layout direction", ViewCompat.LAYOUT_DIRECTION_RTL,
+                MarginLayoutParamsCompat.getLayoutDirection(mlp));
 
         MarginLayoutParamsCompat.setLayoutDirection(mlp, ViewCompat.LAYOUT_DIRECTION_LTR);
         assertEquals("Back to LTR layout direction", ViewCompat.LAYOUT_DIRECTION_LTR,
diff --git a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
index 281bc49..2305523 100644
--- a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
@@ -140,7 +140,7 @@
 
     @Test
     public void testGetSetHintText() {
-        final CharSequence hintText = (Build.VERSION.SDK_INT >= 19) ? "hint text" : null;
+        final CharSequence hintText = "hint text";
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
         nodeCompat.setHintText(hintText);
         assertThat(nodeCompat.getHintText()).isEqualTo(hintText);
@@ -148,7 +148,7 @@
 
     @Test
     public void testGetSetPaneTitle() {
-        final CharSequence paneTitle = (Build.VERSION.SDK_INT >= 19) ? "pane title" : null;
+        final CharSequence paneTitle = "pane title";
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
         nodeCompat.setPaneTitle(paneTitle);
         assertThat(nodeCompat.getPaneTitle()).isEqualTo(paneTitle);
@@ -156,7 +156,7 @@
 
     @Test
     public void testGetSetTooltipText() {
-        final CharSequence tooltipText = (Build.VERSION.SDK_INT >= 19) ? "tooltip" : null;
+        final CharSequence tooltipText = "tooltip";
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
         nodeCompat.setTooltipText(tooltipText);
         assertThat(nodeCompat.getTooltipText()).isEqualTo(tooltipText);
@@ -197,7 +197,7 @@
 
     @Test
     public void testGetSetContainerTitle() {
-        final CharSequence containerTitle = (Build.VERSION.SDK_INT >= 19) ? "title" : null;
+        final CharSequence containerTitle = "title";
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
         nodeCompat.setContainerTitle(containerTitle);
         assertThat(nodeCompat.getContainerTitle()).isEqualTo(containerTitle);
@@ -265,7 +265,7 @@
 
     @Test
     public void testGetSetUniqueId() {
-        final String uniqueId = (Build.VERSION.SDK_INT >= 19) ? "localUId" : null;
+        final String uniqueId = "localUId";
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
         nodeCompat.setUniqueId(uniqueId);
         assertThat(nodeCompat.getUniqueId()).isEqualTo(uniqueId);
diff --git a/core/core/src/androidTest/java/androidx/core/view/inputmethod/EditorInfoCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/inputmethod/EditorInfoCompatTest.java
index 1e14e1f..d213e1f 100644
--- a/core/core/src/androidTest/java/androidx/core/view/inputmethod/EditorInfoCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/inputmethod/EditorInfoCompatTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -88,6 +89,16 @@
     }
 
     @Test
+    public void testSetStylusHandwritingEnabled() {
+        EditorInfo editorInfo = new EditorInfo();
+        EditorInfoCompat.setStylusHandwritingEnabled(editorInfo, true /* enabled */);
+        assertTrue(EditorInfoCompat.isStylusHandwritingEnabled(editorInfo));
+
+        EditorInfoCompat.setStylusHandwritingEnabled(editorInfo, false /* enabled */);
+        assertFalse(EditorInfoCompat.isStylusHandwritingEnabled(editorInfo));
+    }
+
+    @Test
     public void setInitialText_nullInputText_throwsException() {
         final CharSequence testText = null;
         final EditorInfo editorInfo = new EditorInfo();
diff --git a/core/core/src/androidTest/res/values-hdpi/dimens.xml b/core/core/src/androidTest/res/values-hdpi/dimens.xml
deleted file mode 100755
index 3126a6e..0000000
--- a/core/core/src/androidTest/res/values-hdpi/dimens.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <dimen name="density_aware_size">14dip</dimen>
-</resources>
\ No newline at end of file
diff --git a/core/core/src/androidTest/res/values-mdpi/dimens.xml b/core/core/src/androidTest/res/values-mdpi/dimens.xml
deleted file mode 100755
index ada2cae..0000000
--- a/core/core/src/androidTest/res/values-mdpi/dimens.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <dimen name="density_aware_size">12dip</dimen>
-</resources>
\ No newline at end of file
diff --git a/core/core/src/androidTest/res/values-xhdpi/dimens.xml b/core/core/src/androidTest/res/values-xhdpi/dimens.xml
deleted file mode 100755
index 21125b8..0000000
--- a/core/core/src/androidTest/res/values-xhdpi/dimens.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <dimen name="density_aware_size">16dip</dimen>
-</resources>
\ No newline at end of file
diff --git a/core/core/src/androidTest/res/values-xxhdpi/dimens.xml b/core/core/src/androidTest/res/values-xxhdpi/dimens.xml
deleted file mode 100755
index aaee862..0000000
--- a/core/core/src/androidTest/res/values-xxhdpi/dimens.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <dimen name="density_aware_size">18dip</dimen>
-</resources>
\ No newline at end of file
diff --git a/core/core/src/main/java/androidx/core/accessibilityservice/AccessibilityServiceInfoCompat.java b/core/core/src/main/java/androidx/core/accessibilityservice/AccessibilityServiceInfoCompat.java
index 31d258c..d1dc409 100644
--- a/core/core/src/main/java/androidx/core/accessibilityservice/AccessibilityServiceInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/accessibilityservice/AccessibilityServiceInfoCompat.java
@@ -195,11 +195,7 @@
     @Nullable
     public static String loadDescription(
             @NonNull AccessibilityServiceInfo info, @NonNull PackageManager packageManager) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return info.loadDescription(packageManager);
-        } else {
-            return info.getDescription();
-        }
+        return info.loadDescription(packageManager);
     }
 
     /**
@@ -284,14 +280,7 @@
      */
     @SuppressWarnings("deprecation")
     public static int getCapabilities(@NonNull AccessibilityServiceInfo info) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return info.getCapabilities();
-        } else {
-            if (info.getCanRetrieveWindowContent()) {
-                return CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT;
-            }
-            return 0;
-        }
+        return info.getCapabilities();
     }
 
     /**
diff --git a/core/core/src/main/java/androidx/core/app/ActivityCompat.java b/core/core/src/main/java/androidx/core/app/ActivityCompat.java
index 8f27f72..6ac4335 100644
--- a/core/core/src/main/java/androidx/core/app/ActivityCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ActivityCompat.java
@@ -241,11 +241,7 @@
      */
     public static void startActivityForResult(@NonNull Activity activity, @NonNull Intent intent,
             int requestCode, @Nullable Bundle options) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.startActivityForResult(activity, intent, requestCode, options);
-        } else {
-            activity.startActivityForResult(intent, requestCode);
-        }
+        activity.startActivityForResult(intent, requestCode, options);
     }
 
     /**
@@ -278,13 +274,8 @@
             @NonNull IntentSender intent, int requestCode, @Nullable Intent fillInIntent,
             int flagsMask, int flagsValues, int extraFlags, @Nullable Bundle options)
             throws IntentSender.SendIntentException {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.startIntentSenderForResult(activity, intent, requestCode, fillInIntent,
-                    flagsMask, flagsValues, extraFlags, options);
-        } else {
-            activity.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
-                    flagsValues, extraFlags);
-        }
+        activity.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
+                flagsValues, extraFlags, options);
     }
 
     /**
@@ -295,11 +286,7 @@
      * method. For other platforms {@link Activity#finish()} will be called instead.</p>
      */
     public static void finishAffinity(@NonNull Activity activity) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.finishAffinity(activity);
-        } else {
-            activity.finish();
-        }
+        activity.finishAffinity();
     }
 
     /**
@@ -847,32 +834,6 @@
         }
     }
 
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void startActivityForResult(Activity activity, Intent intent, int requestCode,
-                Bundle options) {
-            activity.startActivityForResult(intent, requestCode, options);
-        }
-
-        @DoNotInline
-        static void startIntentSenderForResult(Activity activity, IntentSender intent,
-                int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
-                int extraFlags, Bundle options) throws IntentSender.SendIntentException {
-            activity.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
-                    flagsValues, extraFlags, options);
-        }
-
-        @DoNotInline
-        static void finishAffinity(Activity activity) {
-            activity.finishAffinity();
-        }
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() {
diff --git a/core/core/src/main/java/androidx/core/app/ActivityManagerCompat.java b/core/core/src/main/java/androidx/core/app/ActivityManagerCompat.java
index 2e5abb5..696e01f 100644
--- a/core/core/src/main/java/androidx/core/app/ActivityManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ActivityManagerCompat.java
@@ -17,7 +17,6 @@
 package androidx.core.app;
 
 import android.app.ActivityManager;
-import android.os.Build;
 
 import androidx.annotation.NonNull;
 
@@ -37,9 +36,6 @@
      * off certain features that require more RAM.
      */
     public static boolean isLowRamDevice(@NonNull ActivityManager activityManager) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return activityManager.isLowRamDevice();
-        }
-        return false;
+        return activityManager.isLowRamDevice();
     }
 }
diff --git a/core/core/src/main/java/androidx/core/app/ActivityOptionsCompat.java b/core/core/src/main/java/androidx/core/app/ActivityOptionsCompat.java
index dd3ecdb..1895964 100644
--- a/core/core/src/main/java/androidx/core/app/ActivityOptionsCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ActivityOptionsCompat.java
@@ -66,11 +66,8 @@
     @NonNull
     public static ActivityOptionsCompat makeCustomAnimation(@NonNull Context context,
             int enterResId, int exitResId) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return new ActivityOptionsCompatImpl(
-                    Api16Impl.makeCustomAnimation(context, enterResId, exitResId));
-        }
-        return new ActivityOptionsCompat();
+        return new ActivityOptionsCompatImpl(
+                ActivityOptions.makeCustomAnimation(context, enterResId, exitResId));
     }
 
     /**
@@ -96,11 +93,9 @@
     @NonNull
     public static ActivityOptionsCompat makeScaleUpAnimation(@NonNull View source,
             int startX, int startY, int startWidth, int startHeight) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return new ActivityOptionsCompatImpl(Api16Impl.makeScaleUpAnimation(source, startX,
-                    startY, startWidth, startHeight));
-        }
-        return new ActivityOptionsCompat();
+        return new ActivityOptionsCompatImpl(
+                ActivityOptions.makeScaleUpAnimation(source, startX, startY, startWidth,
+                        startHeight));
     }
 
     /**
@@ -149,11 +144,8 @@
     @NonNull
     public static ActivityOptionsCompat makeThumbnailScaleUpAnimation(@NonNull View source,
             @NonNull Bitmap thumbnail, int startX, int startY) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return new ActivityOptionsCompatImpl(
-                    Api16Impl.makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY));
-        }
-        return new ActivityOptionsCompat();
+        return new ActivityOptionsCompatImpl(
+                ActivityOptions.makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY));
     }
 
     /**
@@ -411,30 +403,6 @@
         return this;
     }
 
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static ActivityOptions makeCustomAnimation(Context context, int enterResId, int exitResId) {
-            return ActivityOptions.makeCustomAnimation(context, enterResId, exitResId);
-        }
-
-        @DoNotInline
-        static ActivityOptions makeScaleUpAnimation(View source, int startX, int startY, int width,
-                int height) {
-            return ActivityOptions.makeScaleUpAnimation(source, startX, startY, width, height);
-        }
-
-        @DoNotInline
-        static ActivityOptions makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail,
-                int startX, int startY) {
-            return ActivityOptions.makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY);
-        }
-    }
-
     @RequiresApi(23)
     static class Api23Impl {
         private Api23Impl() {
diff --git a/core/core/src/main/java/androidx/core/app/AlarmManagerCompat.java b/core/core/src/main/java/androidx/core/app/AlarmManagerCompat.java
index 659f4c8..1603dc5 100644
--- a/core/core/src/main/java/androidx/core/app/AlarmManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/AlarmManagerCompat.java
@@ -164,11 +164,7 @@
      */
     public static void setExact(@NonNull AlarmManager alarmManager, int type, long triggerAtMillis,
             @NonNull PendingIntent operation) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.setExact(alarmManager, type, triggerAtMillis, operation);
-        } else {
-            alarmManager.set(type, triggerAtMillis, operation);
-        }
+        alarmManager.setExact(type, triggerAtMillis, operation);
     }
 
     /**
@@ -271,17 +267,4 @@
             alarmManager.setExactAndAllowWhileIdle(type, triggerAtMillis, operation);
         }
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setExact(AlarmManager alarmManager, int type, long triggerAtMillis,
-                PendingIntent operation) {
-            alarmManager.setExact(type, triggerAtMillis, operation);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/app/AppOpsManagerCompat.java b/core/core/src/main/java/androidx/core/app/AppOpsManagerCompat.java
index 1a8727f..52e248a 100644
--- a/core/core/src/main/java/androidx/core/app/AppOpsManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/AppOpsManagerCompat.java
@@ -104,13 +104,9 @@
      */
     public static int noteOp(@NonNull Context context, @NonNull String op, int uid,
             @NonNull String packageName) {
-        if (SDK_INT >= 19) {
-            AppOpsManager appOpsManager =
-                    (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-            return Api19Impl.noteOp(appOpsManager, op, uid, packageName);
-        } else {
-            return MODE_IGNORED;
-        }
+        AppOpsManager appOpsManager =
+                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        return appOpsManager.noteOp(op, uid, packageName);
     }
 
     /**
@@ -124,13 +120,9 @@
      */
     public static int noteOpNoThrow(@NonNull Context context, @NonNull String op, int uid,
             @NonNull String packageName) {
-        if (SDK_INT >= 19) {
-            AppOpsManager appOpsManager =
-                    (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-            return Api19Impl.noteOpNoThrow(appOpsManager, op, uid, packageName);
-        } else {
-            return MODE_IGNORED;
-        }
+        AppOpsManager appOpsManager =
+                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        return appOpsManager.noteOpNoThrow(op, uid, packageName);
     }
 
     /**
@@ -282,22 +274,4 @@
             return appOpsManager.noteProxyOpNoThrow(op, proxiedPackageName);
         }
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int noteOpNoThrow(AppOpsManager appOpsManager, String op, int uid,
-                String packageName) {
-            return appOpsManager.noteOpNoThrow(op, uid, packageName);
-        }
-
-        @DoNotInline
-        static int noteOp(AppOpsManager appOpsManager, String op, int uid, String packageName) {
-            return appOpsManager.noteOp(op, uid, packageName);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/app/NavUtils.java b/core/core/src/main/java/androidx/core/app/NavUtils.java
index 74e6549..b7a2fac 100644
--- a/core/core/src/main/java/androidx/core/app/NavUtils.java
+++ b/core/core/src/main/java/androidx/core/app/NavUtils.java
@@ -26,10 +26,8 @@
 import android.os.Build;
 import android.util.Log;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 /**
  * NavUtils provides helper functionality for applications implementing
@@ -59,12 +57,7 @@
      */
     public static boolean shouldUpRecreateTask(@NonNull Activity sourceActivity,
             @NonNull Intent targetIntent) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.shouldUpRecreateTask(sourceActivity, targetIntent);
-        } else {
-            String action = sourceActivity.getIntent().getAction();
-            return action != null && !action.equals(Intent.ACTION_MAIN);
-        }
+        return sourceActivity.shouldUpRecreateTask(targetIntent);
     }
 
     /**
@@ -107,13 +100,7 @@
      * @param upIntent An intent representing the target destination for up navigation
      */
     public static void navigateUpTo(@NonNull Activity sourceActivity, @NonNull Intent upIntent) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.navigateUpTo(sourceActivity, upIntent);
-        } else {
-            upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            sourceActivity.startActivity(upIntent);
-            sourceActivity.finish();
-        }
+        sourceActivity.navigateUpTo(upIntent);
     }
 
     /**
@@ -131,7 +118,7 @@
         if (Build.VERSION.SDK_INT >= 16) {
             // Prefer the "real" JB definition if available,
             // else fall back to the meta-data element.
-            Intent result = Api16Impl.getParentActivityIntent(sourceActivity);
+            Intent result = sourceActivity.getParentActivityIntent();
             if (result != null) {
                 return result;
             }
@@ -261,11 +248,9 @@
         }
 
         ActivityInfo info = pm.getActivityInfo(componentName, flags);
-        if (Build.VERSION.SDK_INT >= 16) {
-            String result = info.parentActivityName;
-            if (result != null) {
-                return result;
-            }
+        String result = info.parentActivityName;
+        if (result != null) {
+            return result;
         }
         if (info.metaData == null) {
             return null;
@@ -283,26 +268,4 @@
     /** No instances! */
     private NavUtils() {
     }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean shouldUpRecreateTask(Activity activity, Intent targetIntent) {
-            return activity.shouldUpRecreateTask(targetIntent);
-        }
-
-        @DoNotInline
-        static boolean navigateUpTo(Activity activity, Intent upIntent) {
-            return activity.navigateUpTo(upIntent);
-        }
-
-        @DoNotInline
-        static Intent getParentActivityIntent(Activity activity) {
-            return activity.getParentActivityIntent();
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/app/NotificationCompat.java b/core/core/src/main/java/androidx/core/app/NotificationCompat.java
index 7effc27..33b1459 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationCompat.java
@@ -2219,10 +2219,6 @@
          */
         @SuppressLint("BuilderSetStyle")  // This API is copied from Notification.Builder
         public @Nullable RemoteViews createBigContentView() {
-            // Before Jellybean, there was no "big" notification view
-            if (Build.VERSION.SDK_INT < 16) {
-                return null;
-            }
             // If the user setCustomBigContentView(), return it if appropriate for the style.
             if (mBigContentView != null && useExistingRemoteView()) {
                 return mBigContentView;
@@ -6960,12 +6956,12 @@
             if (wearableBundle != null) {
                 final ArrayList<Parcelable> parcelables =
                         wearableBundle.getParcelableArrayList(KEY_ACTIONS);
-                if (Build.VERSION.SDK_INT >= 16 && parcelables != null) {
+                if (parcelables != null) {
                     Action[] actions = new Action[parcelables.size()];
                     for (int i = 0; i < actions.length; i++) {
                         if (Build.VERSION.SDK_INT >= 20) {
                             actions[i] = Api20Impl.getActionCompatFromAction(parcelables, i);
-                        } else if (Build.VERSION.SDK_INT >= 16) {
+                        } else {
                             actions[i] = NotificationCompatJellybean.getActionFromBundle(
                                     (Bundle) parcelables.get(i));
                         }
@@ -7010,20 +7006,16 @@
             Bundle wearableBundle = new Bundle();
 
             if (!mActions.isEmpty()) {
-                if (Build.VERSION.SDK_INT >= 16) {
-                    ArrayList<Parcelable> parcelables = new ArrayList<>(mActions.size());
-                    for (Action action : mActions) {
-                        if (Build.VERSION.SDK_INT >= 20) {
-                            parcelables.add(
-                                    WearableExtender.getActionFromActionCompat(action));
-                        } else if (Build.VERSION.SDK_INT >= 16) {
-                            parcelables.add(NotificationCompatJellybean.getBundleForAction(action));
-                        }
+                ArrayList<Parcelable> parcelables = new ArrayList<>(mActions.size());
+                for (Action action : mActions) {
+                    if (Build.VERSION.SDK_INT >= 20) {
+                        parcelables.add(
+                                WearableExtender.getActionFromActionCompat(action));
+                    } else {
+                        parcelables.add(NotificationCompatJellybean.getBundleForAction(action));
                     }
-                    wearableBundle.putParcelableArrayList(KEY_ACTIONS, parcelables);
-                } else {
-                    wearableBundle.putParcelableArrayList(KEY_ACTIONS, null);
                 }
+                wearableBundle.putParcelableArrayList(KEY_ACTIONS, parcelables);
             }
             if (mFlags != DEFAULT_FLAGS) {
                 wearableBundle.putInt(KEY_FLAGS, mFlags);
@@ -9196,13 +9188,7 @@
      */
     @Nullable
     public static Bundle getExtras(@NonNull Notification notification) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return notification.extras;
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getExtras(notification);
-        } else {
-            return null;
-        }
+        return notification.extras;
     }
 
     /**
@@ -9210,13 +9196,7 @@
      * manner. Actions were supported from JellyBean (Api level 16) forwards.
      */
     public static int getActionCount(@NonNull Notification notification) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return notification.actions != null ? notification.actions.length : 0;
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getActionCount(notification);
-        } else {
-            return 0;
-        }
+        return notification.actions != null ? notification.actions.length : 0;
     }
 
     /**
@@ -9229,7 +9209,7 @@
     public static @Nullable Action getAction(@NonNull Notification notification, int actionIndex) {
         if (Build.VERSION.SDK_INT >= 20) {
             return getActionCompatFromAction(notification.actions[actionIndex]);
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else {
             Notification.Action action = notification.actions[actionIndex];
             Bundle actionExtras = null;
             SparseArray<Bundle> actionExtrasMap = notification.extras.getSparseParcelableArray(
@@ -9239,10 +9219,6 @@
             }
             return NotificationCompatJellybean.readAction(action.icon, action.title,
                     action.actionIntent, actionExtras);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getAction(notification, actionIndex);
-        } else {
-            return null;
         }
     }
 
@@ -9337,19 +9313,17 @@
     @RequiresApi(21)
     public static @NonNull List<Action> getInvisibleActions(@NonNull Notification notification) {
         ArrayList<Action> result = new ArrayList<>();
-        if (Build.VERSION.SDK_INT >= 19) {
-            Bundle carExtenderBundle =
-                    notification.extras.getBundle(CarExtender.EXTRA_CAR_EXTENDER);
-            if (carExtenderBundle == null) {
-                return result;
-            }
+        Bundle carExtenderBundle =
+                notification.extras.getBundle(CarExtender.EXTRA_CAR_EXTENDER);
+        if (carExtenderBundle == null) {
+            return result;
+        }
 
-            Bundle listBundle = carExtenderBundle.getBundle(CarExtender.EXTRA_INVISIBLE_ACTIONS);
-            if (listBundle != null) {
-                for (int i = 0; i < listBundle.size(); i++) {
-                    result.add(NotificationCompatJellybean.getActionFromBundle(
-                            listBundle.getBundle(Integer.toString(i))));
-                }
+        Bundle listBundle = carExtenderBundle.getBundle(CarExtender.EXTRA_INVISIBLE_ACTIONS);
+        if (listBundle != null) {
+            for (int i = 0; i < listBundle.size(); i++) {
+                result.add(NotificationCompatJellybean.getActionFromBundle(
+                        listBundle.getBundle(Integer.toString(i))));
             }
         }
         return result;
@@ -9371,7 +9345,7 @@
                     result.add(Person.fromAndroidPerson(person));
                 }
             }
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else {
             final String[] peopleArray = notification.extras.getStringArray(EXTRA_PEOPLE);
             if (peopleArray != null && peopleArray.length != 0) {
                 for (String personUri : peopleArray) {
@@ -9428,13 +9402,8 @@
     public static boolean getLocalOnly(@NonNull Notification notification) {
         if (Build.VERSION.SDK_INT >= 20) {
             return (notification.flags & Notification.FLAG_LOCAL_ONLY) != 0;
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return notification.extras.getBoolean(NotificationCompatExtras.EXTRA_LOCAL_ONLY);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getExtras(notification).getBoolean(
-                    NotificationCompatExtras.EXTRA_LOCAL_ONLY);
         } else {
-            return false;
+            return notification.extras.getBoolean(NotificationCompatExtras.EXTRA_LOCAL_ONLY);
         }
     }
 
@@ -9445,13 +9414,8 @@
     public static @Nullable String getGroup(@NonNull Notification notification) {
         if (Build.VERSION.SDK_INT >= 20) {
             return Api20Impl.getGroup(notification);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return notification.extras.getString(NotificationCompatExtras.EXTRA_GROUP_KEY);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getExtras(notification).getString(
-                    NotificationCompatExtras.EXTRA_GROUP_KEY);
         } else {
-            return null;
+            return notification.extras.getString(NotificationCompatExtras.EXTRA_GROUP_KEY);
         }
     }
 
@@ -9527,13 +9491,8 @@
     public static boolean isGroupSummary(@NonNull Notification notification) {
         if (Build.VERSION.SDK_INT >= 20) {
             return (notification.flags & Notification.FLAG_GROUP_SUMMARY) != 0;
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return notification.extras.getBoolean(NotificationCompatExtras.EXTRA_GROUP_SUMMARY);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getExtras(notification).getBoolean(
-                    NotificationCompatExtras.EXTRA_GROUP_SUMMARY);
         } else {
-            return false;
+            return notification.extras.getBoolean(NotificationCompatExtras.EXTRA_GROUP_SUMMARY);
         }
     }
 
@@ -9552,13 +9511,8 @@
     public static @Nullable String getSortKey(@NonNull Notification notification) {
         if (Build.VERSION.SDK_INT >= 20) {
             return Api20Impl.getSortKey(notification);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return notification.extras.getString(NotificationCompatExtras.EXTRA_SORT_KEY);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return NotificationCompatJellybean.getExtras(notification).getString(
-                    NotificationCompatExtras.EXTRA_SORT_KEY);
         } else {
-            return null;
+            return notification.extras.getString(NotificationCompatExtras.EXTRA_SORT_KEY);
         }
     }
 
diff --git a/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java b/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java
index f3c71f2..edb7913 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java
@@ -157,16 +157,12 @@
             mContentView = b.mContentView;
             mBigContentView = b.mBigContentView;
         }
-        if (Build.VERSION.SDK_INT >= 17) {
-            Api17Impl.setShowWhen(mBuilder, b.mShowWhen);
-        }
-        if (Build.VERSION.SDK_INT >= 19) {
-            if (Build.VERSION.SDK_INT < 21) {
-                final List<String> people = combineLists(getPeople(b.mPersonList), b.mPeople);
-                if (people != null && !people.isEmpty()) {
-                    mExtras.putStringArray(Notification.EXTRA_PEOPLE,
-                            people.toArray(new String[people.size()]));
-                }
+        mBuilder.setShowWhen(b.mShowWhen);
+        if (Build.VERSION.SDK_INT < 21) {
+            final List<String> people = combineLists(getPeople(b.mPersonList), b.mPeople);
+            if (people != null && !people.isEmpty()) {
+                mExtras.putStringArray(Notification.EXTRA_PEOPLE,
+                        people.toArray(new String[people.size()]));
             }
         }
         if (Build.VERSION.SDK_INT >= 20) {
@@ -229,7 +225,7 @@
             }
         }
         if (Build.VERSION.SDK_INT >= 24) {
-            Api19Impl.setExtras(mBuilder, b.mExtras);
+            mBuilder.setExtras(b.mExtras);
             Api24Impl.setRemoteInputHistory(mBuilder, b.mRemoteInputHistory);
             if (b.mContentView != null) {
                 Api24Impl.setCustomContentView(mBuilder, b.mContentView);
@@ -427,7 +423,7 @@
                     action.getShowsUserInterface());
             Api20Impl.addExtras(actionBuilder, actionExtras);
             Api20Impl.addAction(mBuilder, Api20Impl.build(actionBuilder));
-        } else if (Build.VERSION.SDK_INT >= 16) {
+        } else {
             mActionExtrasList.add(
                     NotificationCompatJellybean.writeActionAndGetExtras(mBuilder, action));
         }
@@ -457,7 +453,7 @@
 
             return notification;
         } else if (Build.VERSION.SDK_INT >= 21) {
-            Api19Impl.setExtras(mBuilder, mExtras);
+            mBuilder.setExtras(mExtras);
             Notification notification = Api16Impl.build(mBuilder);
             if (mContentView != null) {
                 notification.contentView = mContentView;
@@ -485,7 +481,7 @@
             }
             return notification;
         } else if (Build.VERSION.SDK_INT >= 20) {
-            Api19Impl.setExtras(mBuilder, mExtras);
+            mBuilder.setExtras(mExtras);
             Notification notification = Api16Impl.build(mBuilder);
             if (mContentView != null) {
                 notification.contentView = mContentView;
@@ -510,7 +506,7 @@
             }
 
             return notification;
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else {
             SparseArray<Bundle> actionExtrasMap =
                     NotificationCompatJellybean.buildActionExtrasMap(mActionExtrasList);
             if (actionExtrasMap != null) {
@@ -518,7 +514,7 @@
                 mExtras.putSparseParcelableArray(
                         NotificationCompatExtras.EXTRA_ACTION_EXTRAS, actionExtrasMap);
             }
-            Api19Impl.setExtras(mBuilder, mExtras);
+            mBuilder.setExtras(mExtras);
             Notification notification = Api16Impl.build(mBuilder);
             if (mContentView != null) {
                 notification.contentView = mContentView;
@@ -527,34 +523,6 @@
                 notification.bigContentView = mBigContentView;
             }
             return notification;
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            Notification notification = Api16Impl.build(mBuilder);
-            // Merge in developer provided extras, but let the values already set
-            // for keys take precedence.
-            Bundle extras = NotificationCompat.getExtras(notification);
-            Bundle mergeBundle = new Bundle(mExtras);
-            for (String key : mExtras.keySet()) {
-                if (extras.containsKey(key)) {
-                    mergeBundle.remove(key);
-                }
-            }
-            extras.putAll(mergeBundle);
-            SparseArray<Bundle> actionExtrasMap =
-                    NotificationCompatJellybean.buildActionExtrasMap(mActionExtrasList);
-            if (actionExtrasMap != null) {
-                // Add the action extras sparse array if any action was added with extras.
-                NotificationCompat.getExtras(notification).putSparseParcelableArray(
-                        NotificationCompatExtras.EXTRA_ACTION_EXTRAS, actionExtrasMap);
-            }
-            if (mContentView != null) {
-                notification.contentView = mContentView;
-            }
-            if (mBigContentView != null) {
-                notification.bigContentView = mBigContentView;
-            }
-            return notification;
-        } else {
-            return mBuilder.getNotification();
         }
     }
 
@@ -597,38 +565,6 @@
 
     /**
      * A class for wrapping calls to {@link NotificationCompatBuilder} methods which
-     * were added in API 17; these calls must be wrapped to avoid performance issues.
-     * See the UnsafeNewApiCall lint rule for more details.
-     */
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-        }
-
-        @DoNotInline
-        static Notification.Builder setShowWhen(Notification.Builder builder, boolean show) {
-            return builder.setShowWhen(show);
-        }
-
-    }
-
-    /**
-     * A class for wrapping calls to {@link NotificationCompatBuilder} methods which
-     * were added in API 19; these calls must be wrapped to avoid performance issues.
-     * See the UnsafeNewApiCall lint rule for more details.
-     */
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() { }
-
-        @DoNotInline
-        static Notification.Builder setExtras(Notification.Builder builder, Bundle extras) {
-            return builder.setExtras(extras);
-        }
-    }
-
-    /**
-     * A class for wrapping calls to {@link NotificationCompatBuilder} methods which
      * were added in API 20; these calls must be wrapped to avoid performance issues.
      * See the UnsafeNewApiCall lint rule for more details.
      */
diff --git a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
index 48bf924..1fcf6fc 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
@@ -367,7 +367,7 @@
     public boolean areNotificationsEnabled() {
         if (Build.VERSION.SDK_INT >= 24) {
             return Api24Impl.areNotificationsEnabled(mNotificationManager);
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else {
             AppOpsManager appOps =
                     (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
             ApplicationInfo appInfo = mContext.getApplicationInfo();
@@ -385,8 +385,6 @@
                     | InvocationTargetException | IllegalAccessException | RuntimeException e) {
                 return true;
             }
-        } else {
-            return true;
         }
     }
 
diff --git a/core/core/src/main/java/androidx/core/app/PendingIntentCompat.java b/core/core/src/main/java/androidx/core/app/PendingIntentCompat.java
index 92edc72..66a61a9 100644
--- a/core/core/src/main/java/androidx/core/app/PendingIntentCompat.java
+++ b/core/core/src/main/java/androidx/core/app/PendingIntentCompat.java
@@ -76,12 +76,8 @@
             @Flags int flags,

             @Nullable Bundle options,

             boolean isMutable) {

-        if (VERSION.SDK_INT >= 16) {

-            return Api16Impl.getActivities(

-                    context, requestCode, intents, addMutabilityFlags(isMutable, flags), options);

-        } else {

-            return PendingIntent.getActivities(context, requestCode, intents, flags);

-        }

+        return PendingIntent.getActivities(context, requestCode, intents,

+                addMutabilityFlags(isMutable, flags), options);

     }

 

     /**

@@ -135,12 +131,8 @@
             @Flags int flags,

             @Nullable Bundle options,

             boolean isMutable) {

-        if (VERSION.SDK_INT >= 16) {

-            return Api16Impl.getActivity(

-                    context, requestCode, intent, addMutabilityFlags(isMutable, flags), options);

-        } else {

-            return PendingIntent.getActivity(context, requestCode, intent, flags);

-        }

+        return PendingIntent.getActivity(context, requestCode, intent,

+                addMutabilityFlags(isMutable, flags), options);

     }

 

     /**

@@ -299,31 +291,6 @@
 

     private PendingIntentCompat() {}

 

-    @RequiresApi(16)

-    private static class Api16Impl {

-        private Api16Impl() {}

-

-        @DoNotInline

-        public static @NonNull PendingIntent getActivities(

-                @NonNull Context context,

-                int requestCode,

-                @NonNull @SuppressLint("ArrayReturn") Intent[] intents,

-                @Flags int flags,

-                @Nullable Bundle options) {

-            return PendingIntent.getActivities(context, requestCode, intents, flags, options);

-        }

-

-        @DoNotInline

-        public static @NonNull PendingIntent getActivity(

-                @NonNull Context context,

-                int requestCode,

-                @NonNull Intent intent,

-                @Flags int flags,

-                @Nullable Bundle options) {

-            return PendingIntent.getActivity(context, requestCode, intent, flags, options);

-        }

-    }

-

     @RequiresApi(23)

     private static class Api23Impl {

         private Api23Impl() {}

diff --git a/core/core/src/main/java/androidx/core/app/ShareCompat.java b/core/core/src/main/java/androidx/core/app/ShareCompat.java
index 5cfe607..818210a 100644
--- a/core/core/src/main/java/androidx/core/app/ShareCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ShareCompat.java
@@ -16,8 +16,6 @@
 
 package androidx.core.app;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import static androidx.core.util.Preconditions.checkNotNull;
 
 import android.app.Activity;
@@ -38,11 +36,9 @@
 import android.view.MenuItem;
 import android.widget.ShareActionProvider;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.StringRes;
 import androidx.core.content.IntentCompat;
 
@@ -248,12 +244,6 @@
                 + shareIntent.getContext().getClass().getName());
         provider.setShareIntent(shareIntent.getIntent());
         item.setActionProvider(provider);
-
-        if (SDK_INT < 16) {
-            if (!item.hasSubMenu()) {
-                item.setIntent(shareIntent.createChooserIntent());
-            }
-        }
     }
 
     /**
@@ -370,21 +360,16 @@
                 mIntent.setAction(Intent.ACTION_SEND);
                 if (mStreams != null && !mStreams.isEmpty()) {
                     mIntent.putExtra(Intent.EXTRA_STREAM, mStreams.get(0));
-                    if (SDK_INT >= 16) {
-                        Api16Impl.migrateExtraStreamToClipData(mIntent, mStreams);
-                    }
+                    migrateExtraStreamToClipData(mIntent, mStreams);
                 } else {
                     mIntent.removeExtra(Intent.EXTRA_STREAM);
-                    if (SDK_INT >= 16) {
-                        Api16Impl.removeClipData(mIntent);
-                    }
+                    mIntent.setClipData(null);
+                    mIntent.setFlags(mIntent.getFlags() & ~Intent.FLAG_GRANT_READ_URI_PERMISSION);
                 }
             } else {
                 mIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
                 mIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, mStreams);
-                if (SDK_INT >= 16) {
-                    Api16Impl.migrateExtraStreamToClipData(mIntent, mStreams);
-                }
+                migrateExtraStreamToClipData(mIntent, mStreams);
             }
 
             return mIntent;
@@ -833,44 +818,12 @@
                 if (text instanceof Spanned) {
                     result = Html.toHtml((Spanned) text);
                 } else if (text != null) {
-                    if (SDK_INT >= 16) {
-                        result = Api16Impl.escapeHtml(text);
-                    } else {
-                        StringBuilder out = new StringBuilder();
-                        withinStyle(out, text, 0, text.length());
-                        result = out.toString();
-                    }
+                    result = Html.escapeHtml(text);
                 }
             }
             return result;
         }
 
-        @SuppressWarnings("SameParameterValue")
-        private static void withinStyle(StringBuilder out, CharSequence text, int start, int end) {
-            for (int i = start; i < end; i++) {
-                char c = text.charAt(i);
-
-                if (c == '<') {
-                    out.append("&lt;");
-                } else if (c == '>') {
-                    out.append("&gt;");
-                } else if (c == '&') {
-                    out.append("&amp;");
-                } else if (c > 0x7E || c < ' ') {
-                    out.append("&#").append((int) c).append(";");
-                } else if (c == ' ') {
-                    while (i + 1 < end && text.charAt(i + 1) == ' ') {
-                        out.append("&nbsp;");
-                        i++;
-                    }
-
-                    out.append(' ');
-                } else {
-                    out.append(c);
-                }
-            }
-        }
-
         /**
          * Get a URI referring to a data stream shared with the target activity.
          *
@@ -1084,40 +1037,21 @@
         }
     }
 
-    @RequiresApi(16)
-    private static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
+    static void migrateExtraStreamToClipData(@NonNull Intent intent,
+            @NonNull ArrayList<Uri> streams) {
+        CharSequence text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
+        String htmlText = intent.getStringExtra(IntentCompat.EXTRA_HTML_TEXT);
+
+        ClipData clipData = new ClipData(
+                null, new String[] { intent.getType() },
+                new ClipData.Item(text, htmlText, null, streams.get(0)));
+
+        for (int i = 1, end = streams.size(); i < end; i++) {
+            Uri uri = streams.get(i);
+            clipData.addItem(new ClipData.Item(uri));
         }
 
-        @DoNotInline
-        static void migrateExtraStreamToClipData(@NonNull Intent intent,
-                @NonNull ArrayList<Uri> streams) {
-            CharSequence text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
-            String htmlText = intent.getStringExtra(IntentCompat.EXTRA_HTML_TEXT);
-
-            ClipData clipData = new ClipData(
-                    null, new String[] { intent.getType() },
-                    new ClipData.Item(text, htmlText, null, streams.get(0)));
-
-            for (int i = 1, end = streams.size(); i < end; i++) {
-                Uri uri = streams.get(i);
-                clipData.addItem(new ClipData.Item(uri));
-            }
-
-            intent.setClipData(clipData);
-            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        }
-
-        @DoNotInline
-        static void removeClipData(@NonNull Intent intent) {
-            intent.setClipData(null);
-            intent.setFlags(intent.getFlags() & ~Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        }
-
-        @DoNotInline
-        static String escapeHtml(CharSequence text) {
-            return Html.escapeHtml(text);
-        }
+        intent.setClipData(clipData);
+        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
     }
 }
diff --git a/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java b/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java
index db30332..e171fd5 100644
--- a/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java
+++ b/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java
@@ -22,14 +22,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.core.content.ContextCompat;
 
 import java.util.ArrayList;
@@ -341,11 +338,7 @@
         intents[0] = new Intent(intents[0]).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
 
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getActivities(mSourceContext, requestCode, intents, flags, options);
-        } else {
-            return PendingIntent.getActivities(mSourceContext, requestCode, intents, flags);
-        }
+        return PendingIntent.getActivities(mSourceContext, requestCode, intents, flags, options);
     }
 
     /**
@@ -367,17 +360,4 @@
         }
         return intents;
     }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static PendingIntent getActivities(Context context, int requestCode, Intent[] intents,
-                int flags, Bundle options) {
-            return PendingIntent.getActivities(context, requestCode, intents, flags, options);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/content/ContentResolverCompat.java b/core/core/src/main/java/androidx/core/content/ContentResolverCompat.java
index f19d651..c2fc5b2 100644
--- a/core/core/src/main/java/androidx/core/content/ContentResolverCompat.java
+++ b/core/core/src/main/java/androidx/core/content/ContentResolverCompat.java
@@ -16,17 +16,13 @@
 
 package androidx.core.content;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import android.content.ContentResolver;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.CancellationSignal;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.core.os.OperationCanceledException;
 
 /**
@@ -127,42 +123,18 @@
             @NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
             @Nullable String[] selectionArgs, @Nullable String sortOrder,
             @Nullable CancellationSignal cancellationSignal) {
-        if (SDK_INT >= 16) {
-            try {
-                return Api16Impl.query(resolver, uri, projection, selection, selectionArgs,
-                        sortOrder, cancellationSignal);
-            } catch (Exception e) {
-                if (e instanceof android.os.OperationCanceledException) {
-                    // query() can throw a framework OperationCanceledException if it has been
-                    // canceled. We catch that and throw the support version instead.
-                    throw new OperationCanceledException();
-                } else {
-                    // If it's not a framework OperationCanceledException, re-throw the exception
-                    throw e;
-                }
-            }
-        } else {
-            // Note that the cancellation signal cannot cancel the query in progress
-            // prior to Jellybean so we cancel it preemptively here if needed.
-            if (cancellationSignal != null) {
-                cancellationSignal.throwIfCanceled();
-            }
-            return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
-        }
-    }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static Cursor query(ContentResolver contentResolver, Uri uri, String[] projection,
-                String selection, String[] selectionArgs, String sortOrder,
-                CancellationSignal cancellationSignal) {
-            return contentResolver.query(uri, projection, selection, selectionArgs, sortOrder,
+        try {
+            return resolver.query(uri, projection, selection, selectionArgs, sortOrder,
                     cancellationSignal);
+        } catch (Exception e) {
+            if (e instanceof android.os.OperationCanceledException) {
+                // query() can throw a framework OperationCanceledException if it has been
+                // canceled. We catch that and throw the support version instead.
+                throw new OperationCanceledException();
+            } else {
+                // If it's not a framework OperationCanceledException, re-throw the exception
+                throw e;
+            }
         }
     }
 }
diff --git a/core/core/src/main/java/androidx/core/content/ContextCompat.java b/core/core/src/main/java/androidx/core/content/ContextCompat.java
index 92873df..eeb5c6c 100644
--- a/core/core/src/main/java/androidx/core/content/ContextCompat.java
+++ b/core/core/src/main/java/androidx/core/content/ContextCompat.java
@@ -132,7 +132,6 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.TypedValue;
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.WindowManager;
@@ -174,13 +173,9 @@
 public class ContextCompat {
     private static final String TAG = "ContextCompat";
 
-    private static final Object sLock = new Object();
-
     // Lock that provides similar functionality to ContextImpl.mSync.
     private static final Object sSync = new Object();
 
-    private static TypedValue sTempValue;
-
     /**
      * This class should not be instantiated, but the constructor must be
      * visible for the class to be extended (ex. in ActivityCompat).
@@ -274,11 +269,7 @@
      */
     public static boolean startActivities(@NonNull Context context, @NonNull Intent[] intents,
             @Nullable Bundle options) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.startActivities(context, intents, options);
-        } else {
-            context.startActivities(intents);
-        }
+        context.startActivities(intents, options);
         return true;
     }
 
@@ -301,11 +292,7 @@
      */
     public static void startActivity(@NonNull Context context, @NonNull Intent intent,
             @Nullable Bundle options) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.startActivity(context, intent, options);
-        } else {
-            context.startActivity(intent);
-        }
+        context.startActivity(intent, options);
     }
 
     /**
@@ -378,11 +365,7 @@
      */
     @NonNull
     public static File[] getObbDirs(@NonNull Context context) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getObbDirs(context);
-        } else {
-            return new File[]{context.getObbDir()};
-        }
+        return context.getObbDirs();
     }
 
     /**
@@ -431,11 +414,7 @@
      */
     @NonNull
     public static File[] getExternalFilesDirs(@NonNull Context context, @Nullable String type) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExternalFilesDirs(context, type);
-        } else {
-            return new File[]{context.getExternalFilesDir(type)};
-        }
+        return context.getExternalFilesDirs(type);
     }
 
     /**
@@ -484,11 +463,7 @@
      */
     @NonNull
     public static File[] getExternalCacheDirs(@NonNull Context context) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExternalCacheDirs(context);
-        } else {
-            return new File[]{context.getExternalCacheDir()};
-        }
+        return context.getExternalCacheDirs();
     }
 
     /**
@@ -508,22 +483,8 @@
     public static Drawable getDrawable(@NonNull Context context, @DrawableRes int id) {
         if (Build.VERSION.SDK_INT >= 21) {
             return Api21Impl.getDrawable(context, id);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            return context.getResources().getDrawable(id);
         } else {
-            // Prior to JELLY_BEAN, Resources.getDrawable() would not correctly
-            // retrieve the final configuration density when the resource ID
-            // is a reference another Drawable resource. As a workaround, try
-            // to resolve the drawable reference manually.
-            final int resolvedId;
-            synchronized (sLock) {
-                if (sTempValue == null) {
-                    sTempValue = new TypedValue();
-                }
-                context.getResources().getValue(id, sTempValue, true);
-                resolvedId = sTempValue.resourceId;
-            }
-            return context.getResources().getDrawable(resolvedId);
+            return context.getResources().getDrawable(id);
         }
     }
 
@@ -934,12 +895,12 @@
 
         // The Android framework supports per-app locales on API 33, so we assume the
         // configuration has been updated after API 32.
-        if (Build.VERSION.SDK_INT <= 32 && Build.VERSION.SDK_INT >= 17) {
+        if (Build.VERSION.SDK_INT <= 32) {
             if (!locales.isEmpty()) {
                 Configuration newConfig = new Configuration(
                         context.getResources().getConfiguration());
                 ConfigurationCompat.setLocales(newConfig, locales);
-                return Api17Impl.createConfigurationContext(context, newConfig);
+                return context.createConfigurationContext(newConfig);
             }
         }
         return context;
@@ -1033,24 +994,18 @@
                 SERVICES.put(TelecomManager.class, TELECOM_SERVICE);
                 SERVICES.put(TvInputManager.class, TV_INPUT_SERVICE);
             }
-            if (Build.VERSION.SDK_INT >= 19) {
-                SERVICES.put(AppOpsManager.class, APP_OPS_SERVICE);
-                SERVICES.put(CaptioningManager.class, CAPTIONING_SERVICE);
-                SERVICES.put(ConsumerIrManager.class, CONSUMER_IR_SERVICE);
-                SERVICES.put(PrintManager.class, PRINT_SERVICE);
-            }
-            if (Build.VERSION.SDK_INT >= 18) {
-                SERVICES.put(BluetoothManager.class, BLUETOOTH_SERVICE);
-            }
-            if (Build.VERSION.SDK_INT >= 17) {
-                SERVICES.put(DisplayManager.class, DISPLAY_SERVICE);
-                SERVICES.put(UserManager.class, USER_SERVICE);
-            }
-            if (Build.VERSION.SDK_INT >= 16) {
-                SERVICES.put(InputManager.class, INPUT_SERVICE);
-                SERVICES.put(MediaRouter.class, MEDIA_ROUTER_SERVICE);
-                SERVICES.put(NsdManager.class, NSD_SERVICE);
-            }
+
+            SERVICES.put(AppOpsManager.class, APP_OPS_SERVICE);
+            SERVICES.put(CaptioningManager.class, CAPTIONING_SERVICE);
+            SERVICES.put(ConsumerIrManager.class, CONSUMER_IR_SERVICE);
+            SERVICES.put(PrintManager.class, PRINT_SERVICE);
+            SERVICES.put(BluetoothManager.class, BLUETOOTH_SERVICE);
+            SERVICES.put(DisplayManager.class, DISPLAY_SERVICE);
+            SERVICES.put(UserManager.class, USER_SERVICE);
+
+            SERVICES.put(InputManager.class, INPUT_SERVICE);
+            SERVICES.put(MediaRouter.class, MEDIA_ROUTER_SERVICE);
+            SERVICES.put(NsdManager.class, NSD_SERVICE);
             SERVICES.put(AccessibilityManager.class, ACCESSIBILITY_SERVICE);
             SERVICES.put(AccountManager.class, ACCOUNT_SERVICE);
             SERVICES.put(ActivityManager.class, ACTIVITY_SERVICE);
@@ -1083,57 +1038,6 @@
         }
     }
 
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void startActivities(Context obj, Intent[] intents, Bundle options) {
-            obj.startActivities(intents, options);
-        }
-
-        @DoNotInline
-        static void startActivity(Context obj, Intent intent, Bundle options) {
-            obj.startActivity(intent, options);
-        }
-    }
-
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static Context createConfigurationContext(Context obj, Configuration config) {
-            return obj.createConfigurationContext(config);
-        }
-    }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static File[] getExternalCacheDirs(Context obj) {
-            return obj.getExternalCacheDirs();
-        }
-
-        @DoNotInline
-        static File[] getExternalFilesDirs(Context obj, String type) {
-            return obj.getExternalFilesDirs(type);
-        }
-
-        @DoNotInline
-        static File[] getObbDirs(Context obj) {
-            return obj.getObbDirs();
-        }
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() {
diff --git a/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java b/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java
index f8d72df..03e4741 100644
--- a/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java
@@ -831,8 +831,7 @@
             final boolean isHorizontal) {
         final ActivityManager am = (ActivityManager)
                 context.getSystemService(Context.ACTIVITY_SERVICE);
-        final boolean isLowRamDevice =
-                Build.VERSION.SDK_INT < 19 || am == null || am.isLowRamDevice();
+        final boolean isLowRamDevice = am == null || am.isLowRamDevice();
         final int iconDimensionDp = Math.max(1, isLowRamDevice
                 ? DEFAULT_MAX_ICON_DIMENSION_LOWRAM_DP : DEFAULT_MAX_ICON_DIMENSION_DP);
         final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
diff --git a/core/core/src/main/java/androidx/core/content/res/ConfigurationHelper.java b/core/core/src/main/java/androidx/core/content/res/ConfigurationHelper.java
index ca5094d..dcfb64c 100644
--- a/core/core/src/main/java/androidx/core/content/res/ConfigurationHelper.java
+++ b/core/core/src/main/java/androidx/core/content/res/ConfigurationHelper.java
@@ -16,8 +16,6 @@
 
 package androidx.core.content.res;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import android.content.res.Configuration;
 import android.content.res.Resources;
 
@@ -38,10 +36,6 @@
      * is computed and returned.</p>
      */
     public static int getDensityDpi(@NonNull Resources resources) {
-        if (SDK_INT >= 17) {
-            return resources.getConfiguration().densityDpi;
-        } else {
-            return resources.getDisplayMetrics().densityDpi;
-        }
+        return resources.getConfiguration().densityDpi;
     }
 }
diff --git a/core/core/src/main/java/androidx/core/graphics/BitmapCompat.java b/core/core/src/main/java/androidx/core/graphics/BitmapCompat.java
index b10563e..25d0b7b 100644
--- a/core/core/src/main/java/androidx/core/graphics/BitmapCompat.java
+++ b/core/core/src/main/java/androidx/core/graphics/BitmapCompat.java
@@ -54,10 +54,7 @@
      * @see Bitmap#hasMipMap()
      */
     public static boolean hasMipMap(@NonNull Bitmap bitmap) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return Api17Impl.hasMipMap(bitmap);
-        }
-        return false;
+        return bitmap.hasMipMap();
     }
 
     /**
@@ -81,9 +78,7 @@
      * @see Bitmap#setHasMipMap(boolean)
      */
     public static void setHasMipMap(@NonNull Bitmap bitmap, boolean hasMipMap) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            Api17Impl.setHasMipMap(bitmap, hasMipMap);
-        }
+        bitmap.setHasMipMap(hasMipMap);
     }
 
     /**
@@ -94,10 +89,7 @@
      * @see Bitmap#getAllocationByteCount()
      */
     public static int getAllocationByteCount(@NonNull Bitmap bitmap) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getAllocationByteCount(bitmap);
-        }
-        return bitmap.getByteCount();
+        return bitmap.getAllocationByteCount();
     }
 
     /**
@@ -334,35 +326,6 @@
         // This class is not instantiable.
     }
 
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean hasMipMap(Bitmap bitmap) {
-            return bitmap.hasMipMap();
-        }
-
-        @DoNotInline
-        static void setHasMipMap(Bitmap bitmap, boolean hasMipMap) {
-            bitmap.setHasMipMap(hasMipMap);
-        }
-    }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getAllocationByteCount(Bitmap bitmap) {
-            return bitmap.getAllocationByteCount();
-        }
-    }
-
     @RequiresApi(27)
     static class Api27Impl {
         private Api27Impl() {
diff --git a/core/core/src/main/java/androidx/core/graphics/drawable/DrawableCompat.java b/core/core/src/main/java/androidx/core/graphics/drawable/DrawableCompat.java
index 3d01b86..a4d6ea9 100644
--- a/core/core/src/main/java/androidx/core/graphics/drawable/DrawableCompat.java
+++ b/core/core/src/main/java/androidx/core/graphics/drawable/DrawableCompat.java
@@ -77,9 +77,7 @@
      *            not.
      */
     public static void setAutoMirrored(@NonNull Drawable drawable, boolean mirrored) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.setAutoMirrored(drawable, mirrored);
-        }
+        drawable.setAutoMirrored(mirrored);
     }
 
     /**
@@ -94,11 +92,7 @@
      *         mirrored.
      */
     public static boolean isAutoMirrored(@NonNull Drawable drawable) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.isAutoMirrored(drawable);
-        } else {
-            return false;
-        }
+        return drawable.isAutoMirrored();
     }
 
     /**
@@ -181,11 +175,7 @@
      */
     @SuppressWarnings("unused")
     public static int getAlpha(@NonNull Drawable drawable) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getAlpha(drawable);
-        } else {
-            return 0;
-        }
+        return drawable.getAlpha();
     }
 
     /**
@@ -241,7 +231,7 @@
             // to find any DrawableContainers, and then unwrap those to clear the filter on its
             // children manually
             if (drawable instanceof InsetDrawable) {
-                clearColorFilter(Api19Impl.getDrawable((InsetDrawable) drawable));
+                clearColorFilter(((InsetDrawable) drawable).getDrawable());
             } else if (drawable instanceof WrappedDrawable) {
                 clearColorFilter(((WrappedDrawable) drawable).getWrappedDrawable());
             } else if (drawable instanceof DrawableContainer) {
@@ -251,7 +241,7 @@
                 if (state != null) {
                     Drawable child;
                     for (int i = 0, count = state.getChildCount(); i < count; i++) {
-                        child = Api19Impl.getChild(state, i);
+                        child = state.getChild(i);
                         if (child != null) {
                             clearColorFilter(child);
                         }
@@ -435,39 +425,6 @@
     private DrawableCompat() {
     }
 
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setAutoMirrored(Drawable drawable, boolean mirrored) {
-            drawable.setAutoMirrored(mirrored);
-        }
-
-        @DoNotInline
-        static boolean isAutoMirrored(Drawable drawable) {
-            return drawable.isAutoMirrored();
-        }
-
-        @DoNotInline
-        static int getAlpha(Drawable drawable) {
-            return drawable.getAlpha();
-        }
-
-        @DoNotInline
-        static Drawable getChild(DrawableContainer.DrawableContainerState drawableContainerState,
-                int index) {
-            return drawableContainerState.getChild(index);
-        }
-
-        @DoNotInline
-        static Drawable getDrawable(InsetDrawable drawable) {
-            return drawable.getDrawable();
-        }
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() {
diff --git a/core/core/src/main/java/androidx/core/hardware/display/DisplayManagerCompat.java b/core/core/src/main/java/androidx/core/hardware/display/DisplayManagerCompat.java
index 4f6a511..396cadf 100644
--- a/core/core/src/main/java/androidx/core/hardware/display/DisplayManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/hardware/display/DisplayManagerCompat.java
@@ -18,14 +18,10 @@
 
 import android.content.Context;
 import android.hardware.display.DisplayManager;
-import android.os.Build;
 import android.view.Display;
-import android.view.WindowManager;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 /**
  * Helper for accessing features in {@link android.hardware.display.DisplayManager}.
@@ -73,17 +69,9 @@
     @Nullable
     @SuppressWarnings("deprecation")
     public Display getDisplay(int displayId) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return Api17Impl.getDisplay(
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE), displayId);
-        }
-
-        Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-        if (display.getDisplayId() == displayId) {
-            return display;
-        }
-        return null;
+        DisplayManager displayManager =
+                (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+        return displayManager.getDisplay(displayId);
     }
 
     /**
@@ -94,14 +82,7 @@
     @SuppressWarnings("deprecation")
     @NonNull
     public Display[] getDisplays() {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return Api17Impl.getDisplays(
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE));
-        }
-
-        Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-        return new Display[] { display };
+        return ((DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE)).getDisplays();
     }
 
     /**
@@ -123,33 +104,6 @@
     @NonNull
     @SuppressWarnings("deprecation")
     public Display[] getDisplays(@Nullable String category) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return Api17Impl.getDisplays(
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE));
-        }
-        if (category == null) {
-            return new Display[0];
-        }
-
-        Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-        return new Display[]{display};
-    }
-
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static Display getDisplay(DisplayManager displayManager, int displayId) {
-            return displayManager.getDisplay(displayId);
-        }
-
-        @DoNotInline
-        static Display[] getDisplays(DisplayManager displayManager) {
-            return displayManager.getDisplays();
-        }
+        return ((DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE)).getDisplays();
     }
 }
diff --git a/core/core/src/main/java/androidx/core/location/LocationCompat.java b/core/core/src/main/java/androidx/core/location/LocationCompat.java
index 634dea0..883ff8a 100644
--- a/core/core/src/main/java/androidx/core/location/LocationCompat.java
+++ b/core/core/src/main/java/androidx/core/location/LocationCompat.java
@@ -16,14 +16,12 @@
 
 package androidx.core.location;
 
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
 import android.annotation.SuppressLint;
 import android.location.Location;
 import android.os.Build.VERSION;
 import android.os.Bundle;
-import android.os.SystemClock;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.FloatRange;
@@ -111,11 +109,7 @@
      * location derivation is different from the system clock, the results may be inaccurate.
      */
     public static long getElapsedRealtimeNanos(@NonNull Location location) {
-        if (VERSION.SDK_INT >= 17) {
-            return Api17Impl.getElapsedRealtimeNanos(location);
-        } else {
-            return MILLISECONDS.toNanos(getElapsedRealtimeMillis(location));
-        }
+        return location.getElapsedRealtimeNanos();
     }
 
     /**
@@ -124,21 +118,7 @@
      * @see #getElapsedRealtimeNanos(Location)
      */
     public static long getElapsedRealtimeMillis(@NonNull Location location) {
-        if (VERSION.SDK_INT >= 17) {
-            return NANOSECONDS.toMillis(Api17Impl.getElapsedRealtimeNanos(location));
-        } else {
-            long timeDeltaMs = System.currentTimeMillis() - location.getTime();
-            long elapsedRealtimeMs = SystemClock.elapsedRealtime();
-            if (timeDeltaMs < 0) {
-                // don't return an elapsed realtime from the future
-                return elapsedRealtimeMs;
-            } else if (timeDeltaMs > elapsedRealtimeMs) {
-                // don't return an elapsed realtime from before boot
-                return 0;
-            } else {
-                return elapsedRealtimeMs - timeDeltaMs;
-            }
-        }
+        return NANOSECONDS.toMillis(location.getElapsedRealtimeNanos());
     }
 
     /**
@@ -517,16 +497,7 @@
      * @see android.location.LocationManager#addTestProvider
      */
     public static boolean isMock(@NonNull Location location) {
-        if (VERSION.SDK_INT >= 18) {
-            return Api18Impl.isMock(location);
-        } else {
-            Bundle extras = location.getExtras();
-            if (extras == null) {
-                return false;
-            }
-
-            return extras.getBoolean(EXTRA_IS_MOCK, false);
-        }
+        return location.isFromMockProvider();
     }
 
     /**
@@ -537,9 +508,9 @@
      * boolean extra with the key {@link #EXTRA_IS_MOCK} to mark the location as mock. Be aware that
      * this will overwrite any prior extra value under the same key.
      */
+    @SuppressLint("BanUncheckedReflection")
     public static void setMock(@NonNull Location location, boolean mock) {
-        if (VERSION.SDK_INT >= 18) {
-            try {
+        try {
                 getSetIsFromMockProviderMethod().invoke(location, mock);
             } catch (NoSuchMethodException e) {
                 Error error = new NoSuchMethodError();
@@ -552,25 +523,6 @@
             } catch (InvocationTargetException e) {
                 throw new RuntimeException(e);
             }
-        } else {
-            Bundle extras = location.getExtras();
-            if (extras == null) {
-                if (mock) {
-                    extras = new Bundle();
-                    extras.putBoolean(EXTRA_IS_MOCK, true);
-                    location.setExtras(extras);
-                }
-            } else {
-                if (mock) {
-                    extras.putBoolean(EXTRA_IS_MOCK, true);
-                } else {
-                    extras.remove(EXTRA_IS_MOCK);
-                    if (extras.isEmpty()) {
-                        location.setExtras(null);
-                    }
-                }
-            }
-        }
     }
 
     @RequiresApi(34)
@@ -960,30 +912,6 @@
         }
     }
 
-    @RequiresApi(18)
-    private static class Api18Impl {
-
-        private Api18Impl() {
-        }
-
-        @DoNotInline
-        static boolean isMock(Location location) {
-            return location.isFromMockProvider();
-        }
-    }
-
-    @RequiresApi(17)
-    private static class Api17Impl {
-
-        private Api17Impl() {
-        }
-
-        @DoNotInline
-        static long getElapsedRealtimeNanos(Location location) {
-            return location.getElapsedRealtimeNanos();
-        }
-    }
-
     private static Method getSetIsFromMockProviderMethod() throws NoSuchMethodException {
         if (sSetIsFromMockProviderMethod == null) {
             sSetIsFromMockProviderMethod = Location.class.getDeclaredMethod("setIsFromMockProvider",
diff --git a/core/core/src/main/java/androidx/core/location/LocationManagerCompat.java b/core/core/src/main/java/androidx/core/location/LocationManagerCompat.java
index da63ac2..c53c2e4 100644
--- a/core/core/src/main/java/androidx/core/location/LocationManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/location/LocationManagerCompat.java
@@ -281,7 +281,7 @@
         LocationListenerTransport transport = new LocationListenerTransport(
                 new LocationListenerKey(provider, listener), executor);
 
-        if (VERSION.SDK_INT >= 19 && Api19Impl.tryRequestLocationUpdates(
+        if (Api19Impl.tryRequestLocationUpdates(
                 locationManager, provider, locationRequest, transport)) {
             return;
         }
@@ -328,7 +328,7 @@
             return;
         }
 
-        if (VERSION.SDK_INT >= 19 && Api19Impl.tryRequestLocationUpdates(
+        if (Api19Impl.tryRequestLocationUpdates(
                     locationManager, provider, locationRequest, listener, looper)) {
             return;
         }
@@ -1316,7 +1316,6 @@
         }
     }
 
-    @RequiresApi(19)
     static class Api19Impl {
         private static Class<?> sLocationRequestClass;
         private static Method sRequestLocationUpdatesLooperMethod;
@@ -1325,79 +1324,79 @@
             // This class is not instantiable.
         }
 
+        @SuppressLint("BanUncheckedReflection")
         @SuppressWarnings("JavaReflectionMemberAccess")
         @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
         @DoNotInline
         static boolean tryRequestLocationUpdates(LocationManager locationManager,
                 String provider, LocationRequestCompat locationRequest,
                 LocationListenerTransport transport) {
-            if (VERSION.SDK_INT >= 19) { // Satisfy reflection lint check
-                try {
-                    if (sLocationRequestClass == null) {
-                        sLocationRequestClass = Class.forName("android.location.LocationRequest");
-                    }
-                    if (sRequestLocationUpdatesLooperMethod == null) {
-                        sRequestLocationUpdatesLooperMethod =
-                                LocationManager.class.getDeclaredMethod(
-                                        "requestLocationUpdates",
-                                        sLocationRequestClass, LocationListener.class,
-                                        Looper.class);
-                        sRequestLocationUpdatesLooperMethod.setAccessible(true);
-                    }
-
-                    LocationRequest request = locationRequest.toLocationRequest(provider);
-                    if (request != null) {
-                        synchronized (sLocationListeners) {
-                            sRequestLocationUpdatesLooperMethod.invoke(locationManager, request,
-                                    transport, Looper.getMainLooper());
-                            registerLocationListenerTransport(locationManager, transport);
-                            return true;
-                        }
-                    }
-                } catch (NoSuchMethodException
-                        | InvocationTargetException
-                        | IllegalAccessException
-                        | ClassNotFoundException
-                        | UnsupportedOperationException e) {
-                    // ignored
+            // Satisfy reflection lint check
+            try {
+                if (sLocationRequestClass == null) {
+                    sLocationRequestClass = Class.forName("android.location.LocationRequest");
                 }
+                if (sRequestLocationUpdatesLooperMethod == null) {
+                    sRequestLocationUpdatesLooperMethod =
+                            LocationManager.class.getDeclaredMethod(
+                                    "requestLocationUpdates",
+                                    sLocationRequestClass, LocationListener.class,
+                                    Looper.class);
+                    sRequestLocationUpdatesLooperMethod.setAccessible(true);
+                }
+
+                LocationRequest request = locationRequest.toLocationRequest(provider);
+                if (request != null) {
+                    synchronized (sLocationListeners) {
+                        sRequestLocationUpdatesLooperMethod.invoke(locationManager, request,
+                                transport, Looper.getMainLooper());
+                        registerLocationListenerTransport(locationManager, transport);
+                        return true;
+                    }
+                }
+            } catch (NoSuchMethodException
+                    | InvocationTargetException
+                    | IllegalAccessException
+                    | ClassNotFoundException
+                    | UnsupportedOperationException e) {
+                // ignored
             }
             return false;
         }
 
+        @SuppressLint("BanUncheckedReflection")
         @SuppressWarnings("JavaReflectionMemberAccess")
         @DoNotInline
         static boolean tryRequestLocationUpdates(LocationManager locationManager, String provider,
                 LocationRequestCompat locationRequest, LocationListenerCompat listener,
                 Looper looper) {
-            if (VERSION.SDK_INT >= 19) { // Satisfy reflection lint check
-                try {
-                    if (sLocationRequestClass == null) {
-                        sLocationRequestClass = Class.forName("android.location.LocationRequest");
-                    }
-
-                    if (sRequestLocationUpdatesLooperMethod == null) {
-                        sRequestLocationUpdatesLooperMethod =
-                                LocationManager.class.getDeclaredMethod(
-                                        "requestLocationUpdates",
-                                        sLocationRequestClass, LocationListener.class,
-                                        Looper.class);
-                        sRequestLocationUpdatesLooperMethod.setAccessible(true);
-                    }
-
-                    LocationRequest request = locationRequest.toLocationRequest(provider);
-                    if (request != null) {
-                        sRequestLocationUpdatesLooperMethod.invoke(
-                                locationManager, request, listener, looper);
-                        return true;
-                    }
-                } catch (NoSuchMethodException
-                        | InvocationTargetException
-                        | IllegalAccessException
-                        | ClassNotFoundException
-                        | UnsupportedOperationException e) {
-                    // ignored
+            // Satisfy reflection lint check
+            try {
+                if (sLocationRequestClass == null) {
+                    sLocationRequestClass = Class.forName("android.location.LocationRequest");
                 }
+
+                if (sRequestLocationUpdatesLooperMethod == null) {
+                    sRequestLocationUpdatesLooperMethod =
+                            LocationManager.class.getDeclaredMethod(
+                                    "requestLocationUpdates",
+                                    sLocationRequestClass, LocationListener.class,
+                                    Looper.class);
+                    sRequestLocationUpdatesLooperMethod.setAccessible(true);
+                }
+
+                LocationRequest request = locationRequest.toLocationRequest(provider);
+                if (request != null) {
+                    sRequestLocationUpdatesLooperMethod.invoke(
+                            locationManager, request, listener, looper);
+                    return true;
+                }
+            } catch (NoSuchMethodException
+                    | InvocationTargetException
+                    | IllegalAccessException
+                    | ClassNotFoundException
+                    | UnsupportedOperationException e) {
+                // ignored
             }
             return false;
         }
diff --git a/core/core/src/main/java/androidx/core/location/LocationRequestCompat.java b/core/core/src/main/java/androidx/core/location/LocationRequestCompat.java
index 1f6eba5..9c7d074 100644
--- a/core/core/src/main/java/androidx/core/location/LocationRequestCompat.java
+++ b/core/core/src/main/java/androidx/core/location/LocationRequestCompat.java
@@ -531,69 +531,69 @@
             // This class is not instantiable.
         }
 
+        @SuppressLint("BanUncheckedReflection")
         public static Object toLocationRequest(LocationRequestCompat obj, String provider) {
-            if (VERSION.SDK_INT >= 19) { // Satisfy reflection lint check
-                try {
-                    if (sLocationRequestClass == null) {
-                        sLocationRequestClass = Class.forName("android.location.LocationRequest");
-                    }
-                    if (sCreateFromDeprecatedProviderMethod == null) {
-                        sCreateFromDeprecatedProviderMethod =
-                                sLocationRequestClass.getDeclaredMethod(
-                                        "createFromDeprecatedProvider", String.class, long.class,
-                                        float.class,
-                                        boolean.class);
-                        sCreateFromDeprecatedProviderMethod.setAccessible(true);
-                    }
-
-                    Object request = sCreateFromDeprecatedProviderMethod.invoke(null,
-                                    provider,
-                                    obj.getIntervalMillis(),
-                                    obj.getMinUpdateDistanceMeters(), false);
-                    if (request == null) {
-                        return null;
-                    }
-
-                    if (sSetQualityMethod == null) {
-                        sSetQualityMethod = sLocationRequestClass.getDeclaredMethod(
-                                "setQuality", int.class);
-                        sSetQualityMethod.setAccessible(true);
-                    }
-                    sSetQualityMethod.invoke(request, obj.getQuality());
-
-                    if (sSetFastestIntervalMethod == null) {
-                        sSetFastestIntervalMethod = sLocationRequestClass.getDeclaredMethod(
-                                "setFastestInterval", long.class);
-                        sSetFastestIntervalMethod.setAccessible(true);
-                    }
-
-                    sSetFastestIntervalMethod.invoke(request, obj.getMinUpdateIntervalMillis());
-
-                    if (obj.getMaxUpdates() < Integer.MAX_VALUE) {
-                        if (sSetNumUpdatesMethod == null) {
-                            sSetNumUpdatesMethod = sLocationRequestClass.getDeclaredMethod(
-                                    "setNumUpdates", int.class);
-                            sSetNumUpdatesMethod.setAccessible(true);
-                        }
-
-                        sSetNumUpdatesMethod.invoke(request, obj.getMaxUpdates());
-                    }
-
-                    if (obj.getDurationMillis() < Long.MAX_VALUE) {
-                        if (sSetExpireInMethod == null) {
-                            sSetExpireInMethod = sLocationRequestClass.getDeclaredMethod(
-                                    "setExpireIn", long.class);
-                            sSetExpireInMethod.setAccessible(true);
-                        }
-
-                        sSetExpireInMethod.invoke(request, obj.getDurationMillis());
-                    }
-
-                    return request;
-                } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException
-                        | ClassNotFoundException e) {
-                    // Ignore
+            // Satisfy reflection lint check
+            try {
+                if (sLocationRequestClass == null) {
+                    sLocationRequestClass = Class.forName("android.location.LocationRequest");
                 }
+                if (sCreateFromDeprecatedProviderMethod == null) {
+                    sCreateFromDeprecatedProviderMethod =
+                            sLocationRequestClass.getDeclaredMethod(
+                                    "createFromDeprecatedProvider", String.class, long.class,
+                                    float.class,
+                                    boolean.class);
+                    sCreateFromDeprecatedProviderMethod.setAccessible(true);
+                }
+
+                Object request = sCreateFromDeprecatedProviderMethod.invoke(null,
+                        provider,
+                        obj.getIntervalMillis(),
+                        obj.getMinUpdateDistanceMeters(), false);
+                if (request == null) {
+                    return null;
+                }
+
+                if (sSetQualityMethod == null) {
+                    sSetQualityMethod = sLocationRequestClass.getDeclaredMethod(
+                            "setQuality", int.class);
+                    sSetQualityMethod.setAccessible(true);
+                }
+                sSetQualityMethod.invoke(request, obj.getQuality());
+
+                if (sSetFastestIntervalMethod == null) {
+                    sSetFastestIntervalMethod = sLocationRequestClass.getDeclaredMethod(
+                            "setFastestInterval", long.class);
+                    sSetFastestIntervalMethod.setAccessible(true);
+                }
+
+                sSetFastestIntervalMethod.invoke(request, obj.getMinUpdateIntervalMillis());
+
+                if (obj.getMaxUpdates() < Integer.MAX_VALUE) {
+                    if (sSetNumUpdatesMethod == null) {
+                        sSetNumUpdatesMethod = sLocationRequestClass.getDeclaredMethod(
+                                "setNumUpdates", int.class);
+                        sSetNumUpdatesMethod.setAccessible(true);
+                    }
+
+                    sSetNumUpdatesMethod.invoke(request, obj.getMaxUpdates());
+                }
+
+                if (obj.getDurationMillis() < Long.MAX_VALUE) {
+                    if (sSetExpireInMethod == null) {
+                        sSetExpireInMethod = sLocationRequestClass.getDeclaredMethod(
+                                "setExpireIn", long.class);
+                        sSetExpireInMethod.setAccessible(true);
+                    }
+
+                    sSetExpireInMethod.invoke(request, obj.getDurationMillis());
+                }
+
+                return request;
+            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException
+                     | ClassNotFoundException e) {
+                // Ignore
             }
             return null;
         }
diff --git a/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java b/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java
index 2d29936..e2fdc44 100644
--- a/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java
@@ -16,16 +16,6 @@
 
 package androidx.core.net;
 
-import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.TYPE_WIMAX;
-
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
 import android.Manifest;
@@ -100,33 +90,7 @@
     @SuppressWarnings("deprecation")
     @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
     public static boolean isActiveNetworkMetered(@NonNull ConnectivityManager cm) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.isActiveNetworkMetered(cm);
-        } else {
-            final NetworkInfo info = cm.getActiveNetworkInfo();
-            if (info == null) {
-                // err on side of caution
-                return true;
-            }
-
-            final int type = info.getType();
-            switch (type) {
-                case TYPE_MOBILE:
-                case TYPE_MOBILE_DUN:
-                case TYPE_MOBILE_HIPRI:
-                case TYPE_MOBILE_MMS:
-                case TYPE_MOBILE_SUPL:
-                case TYPE_WIMAX:
-                    return true;
-                case TYPE_WIFI:
-                case TYPE_BLUETOOTH:
-                case TYPE_ETHERNET:
-                    return false;
-                default:
-                    // err on side of caution
-                    return true;
-            }
-        }
+        return cm.isActiveNetworkMetered();
     }
 
     /**
@@ -169,19 +133,6 @@
 
     private ConnectivityManagerCompat() {}
 
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
-        @DoNotInline
-        static boolean isActiveNetworkMetered(ConnectivityManager connectivityManager) {
-            return connectivityManager.isActiveNetworkMetered();
-        }
-    }
-
     @RequiresApi(24)
     static class Api24Impl {
         private Api24Impl() {
diff --git a/core/core/src/main/java/androidx/core/os/BundleCompat.java b/core/core/src/main/java/androidx/core/os/BundleCompat.java
index 94555cf..3aea8a8 100644
--- a/core/core/src/main/java/androidx/core/os/BundleCompat.java
+++ b/core/core/src/main/java/androidx/core/os/BundleCompat.java
@@ -21,7 +21,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcelable;
-import android.util.Log;
 import android.util.SparseArray;
 
 import androidx.annotation.DoNotInline;
@@ -29,8 +28,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 /**
@@ -192,11 +189,7 @@
      */
     @Nullable
     public static IBinder getBinder(@NonNull Bundle bundle, @Nullable String key) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return Api18Impl.getBinder(bundle, key);
-        } else {
-            return BeforeApi18Impl.getBinder(bundle, key);
-        }
+        return bundle.getBinder(key);
     }
 
     /**
@@ -209,11 +202,7 @@
      */
     public static void putBinder(@NonNull Bundle bundle, @Nullable String key,
             @Nullable IBinder binder) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api18Impl.putBinder(bundle, key, binder);
-        } else {
-            BeforeApi18Impl.putBinder(bundle, key, binder);
-        }
+        bundle.putBinder(key, binder);
     }
 
     @RequiresApi(33)
@@ -246,84 +235,4 @@
             return in.getSparseParcelableArray(key, clazz);
         }
     }
-
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static IBinder getBinder(Bundle bundle, String key) {
-            return bundle.getBinder(key);
-        }
-
-        @DoNotInline
-        static void putBinder(Bundle bundle, String key, IBinder value) {
-            bundle.putBinder(key, value);
-        }
-    }
-
-    @SuppressLint("BanUncheckedReflection") // Only called prior to API 18
-    static class BeforeApi18Impl {
-        private static final String TAG = "BundleCompat";
-
-        private static Method sGetIBinderMethod;
-        private static boolean sGetIBinderMethodFetched;
-
-        private static Method sPutIBinderMethod;
-        private static boolean sPutIBinderMethodFetched;
-
-        private BeforeApi18Impl() {
-            // This class is not instantiable.
-        }
-
-        @SuppressWarnings("JavaReflectionMemberAccess")
-        public static IBinder getBinder(Bundle bundle, String key) {
-            if (!sGetIBinderMethodFetched) {
-                try {
-                    sGetIBinderMethod = Bundle.class.getMethod("getIBinder", String.class);
-                    sGetIBinderMethod.setAccessible(true);
-                } catch (NoSuchMethodException e) {
-                    Log.i(TAG, "Failed to retrieve getIBinder method", e);
-                }
-                sGetIBinderMethodFetched = true;
-            }
-
-            if (sGetIBinderMethod != null) {
-                try {
-                    return (IBinder) sGetIBinderMethod.invoke(bundle, key);
-                } catch (InvocationTargetException | IllegalAccessException
-                         | IllegalArgumentException e) {
-                    Log.i(TAG, "Failed to invoke getIBinder via reflection", e);
-                    sGetIBinderMethod = null;
-                }
-            }
-            return null;
-        }
-
-        @SuppressWarnings("JavaReflectionMemberAccess")
-        public static void putBinder(Bundle bundle, String key, IBinder binder) {
-            if (!sPutIBinderMethodFetched) {
-                try {
-                    sPutIBinderMethod =
-                            Bundle.class.getMethod("putIBinder", String.class, IBinder.class);
-                    sPutIBinderMethod.setAccessible(true);
-                } catch (NoSuchMethodException e) {
-                    Log.i(TAG, "Failed to retrieve putIBinder method", e);
-                }
-                sPutIBinderMethodFetched = true;
-            }
-
-            if (sPutIBinderMethod != null) {
-                try {
-                    sPutIBinderMethod.invoke(bundle, key, binder);
-                } catch (InvocationTargetException | IllegalAccessException
-                         | IllegalArgumentException e) {
-                    Log.i(TAG, "Failed to invoke putIBinder via reflection", e);
-                    sPutIBinderMethod = null;
-                }
-            }
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/os/CancellationSignal.java b/core/core/src/main/java/androidx/core/os/CancellationSignal.java
index 812a61d..85486f8 100644
--- a/core/core/src/main/java/androidx/core/os/CancellationSignal.java
+++ b/core/core/src/main/java/androidx/core/os/CancellationSignal.java
@@ -18,9 +18,7 @@
 
 import android.os.Build;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 /**
  * Static library support version of the framework's {@link android.os.CancellationSignal}.
@@ -87,8 +85,8 @@
             if (listener != null) {
                 listener.onCancel();
             }
-            if (obj != null && Build.VERSION.SDK_INT >= 16) {
-                Api16Impl.cancel(obj);
+            if (obj != null) {
+                ((android.os.CancellationSignal) obj).cancel();
             }
         } finally {
             synchronized (this) {
@@ -142,14 +140,11 @@
      */
     @Nullable
     public Object getCancellationSignalObject() {
-        if (Build.VERSION.SDK_INT < 16) {
-            return null;
-        }
         synchronized (this) {
             if (mCancellationSignalObj == null) {
-                mCancellationSignalObj = Api16Impl.createCancellationSignal();
+                mCancellationSignalObj = new android.os.CancellationSignal();
                 if (mIsCanceled) {
-                    Api16Impl.cancel(mCancellationSignalObj);
+                    ((android.os.CancellationSignal) mCancellationSignalObj).cancel();
                 }
             }
             return mCancellationSignalObj;
@@ -175,21 +170,4 @@
          */
         void onCancel();
     }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void cancel(Object cancellationSignal) {
-            ((android.os.CancellationSignal) cancellationSignal).cancel();
-        }
-
-        @DoNotInline
-        static android.os.CancellationSignal createCancellationSignal() {
-            return new android.os.CancellationSignal();
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/os/ConfigurationCompat.java b/core/core/src/main/java/androidx/core/os/ConfigurationCompat.java
index e5e80dc..d4438ce 100644
--- a/core/core/src/main/java/androidx/core/os/ConfigurationCompat.java
+++ b/core/core/src/main/java/androidx/core/os/ConfigurationCompat.java
@@ -57,20 +57,7 @@
             @NonNull Configuration configuration, @NonNull LocaleListCompat locales) {
         if (SDK_INT >= 24) {
             Api24Impl.setLocales(configuration, locales);
-        } else if (SDK_INT >= 17) {
-            Api17Impl.setLocale(configuration, locales);
-        }
-    }
-
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setLocale(
-                @NonNull Configuration configuration, @NonNull LocaleListCompat locales) {
+        } else {
             if (!locales.isEmpty()) {
                 configuration.setLocale(locales.get(0));
             }
diff --git a/core/core/src/main/java/androidx/core/os/EnvironmentCompat.java b/core/core/src/main/java/androidx/core/os/EnvironmentCompat.java
index 78d1f2a..98d1939 100644
--- a/core/core/src/main/java/androidx/core/os/EnvironmentCompat.java
+++ b/core/core/src/main/java/androidx/core/os/EnvironmentCompat.java
@@ -18,14 +18,12 @@
 
 import android.os.Build;
 import android.os.Environment;
-import android.util.Log;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
 import java.io.File;
-import java.io.IOException;
 
 /**
  * Helper for accessing features in {@link Environment}.
@@ -60,24 +58,9 @@
     public static String getStorageState(@NonNull File path) {
         if (Build.VERSION.SDK_INT >= 21) {
             return Api21Impl.getExternalStorageState(path);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getStorageState(path);
+        } else {
+            return Environment.getStorageState(path);
         }
-
-        try {
-            final String canonicalPath = path.getCanonicalPath();
-            @SuppressWarnings("deprecation")
-            final String canonicalExternal = Environment.getExternalStorageDirectory()
-                    .getCanonicalPath();
-
-            if (canonicalPath.startsWith(canonicalExternal)) {
-                return Environment.getExternalStorageState();
-            }
-        } catch (IOException e) {
-            Log.w(TAG, "Failed to resolve canonical path: " + e);
-        }
-
-        return MEDIA_UNKNOWN;
     }
 
     private EnvironmentCompat() {
@@ -94,16 +77,4 @@
             return Environment.getExternalStorageState(path);
         }
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static String getStorageState(File path) {
-            return Environment.getStorageState(path);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/os/ProcessCompat.java b/core/core/src/main/java/androidx/core/os/ProcessCompat.java
index 6343cf3..f2c38d0 100644
--- a/core/core/src/main/java/androidx/core/os/ProcessCompat.java
+++ b/core/core/src/main/java/androidx/core/os/ProcessCompat.java
@@ -54,12 +54,8 @@
     public static boolean isApplicationUid(int uid) {
         if (Build.VERSION.SDK_INT >= 24) {
             return Api24Impl.isApplicationUid(uid);
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            return Api17Impl.isApplicationUid(uid);
-        } else if (Build.VERSION.SDK_INT == 16) {
-            return Api16Impl.isApplicationUid(uid);
         } else {
-            return true;
+            return Api17Impl.isApplicationUid(uid);
         }
     }
 
@@ -76,7 +72,6 @@
         }
     }
 
-    @RequiresApi(17)
     static class Api17Impl {
         private static final Object sResolvedLock = new Object();
 
@@ -114,43 +109,4 @@
             return true;
         }
     }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private static final Object sResolvedLock = new Object();
-
-        private static Method sMethodUserIdIsAppMethod;
-        private static boolean sResolved;
-
-        private Api16Impl() {
-            // This class is non-instantiable.
-        }
-
-        @SuppressLint("PrivateApi")
-        @SuppressWarnings("CatchAndPrintStackTrace")
-        static boolean isApplicationUid(int uid) {
-            // In JELLY_BEAN_MR1, the equivalent isApp(int) hidden method was available on hidden
-            // class android.os.UserId.
-            try {
-                synchronized (sResolvedLock) {
-                    if (!sResolved) {
-                        sResolved = true;
-                        sMethodUserIdIsAppMethod = Class.forName("android.os.UserId")
-                                .getDeclaredMethod("isApp", int.class);
-                    }
-                }
-                if (sMethodUserIdIsAppMethod != null) {
-                    Boolean result = (Boolean) sMethodUserIdIsAppMethod.invoke(null, uid);
-                    if (result == null) {
-                        // This should never happen, as the method returns a boolean primitive.
-                        throw new NullPointerException();
-                    }
-                    return result;
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            return true;
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/os/TraceCompat.java b/core/core/src/main/java/androidx/core/os/TraceCompat.java
index f5022c6..7689534 100644
--- a/core/core/src/main/java/androidx/core/os/TraceCompat.java
+++ b/core/core/src/main/java/androidx/core/os/TraceCompat.java
@@ -81,7 +81,7 @@
     public static boolean isEnabled() {
         if (Build.VERSION.SDK_INT >= 29) {
             return Api29Impl.isEnabled();
-        } else if (Build.VERSION.SDK_INT >= 18) {
+        } else {
             try {
                 return (boolean) sIsTagEnabledMethod.invoke(null, sTraceTagApp);
             } catch (Exception e) {
@@ -105,9 +105,7 @@
      * most 127 Unicode code units long.
      */
     public static void beginSection(@NonNull String sectionName) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api18Impl.beginSection(sectionName);
-        }
+        Trace.beginSection(sectionName);
     }
 
     /**
@@ -118,9 +116,7 @@
      * thread.
      */
     public static void endSection() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api18Impl.endSection();
-        }
+        Trace.endSection();
     }
 
     /**
@@ -136,7 +132,7 @@
     public static void beginAsyncSection(@NonNull String methodName, int cookie) {
         if (Build.VERSION.SDK_INT >= 29) {
             Api29Impl.beginAsyncSection(methodName, cookie);
-        } else if (Build.VERSION.SDK_INT >= 18) {
+        } else {
             try {
                 sAsyncTraceBeginMethod.invoke(null, sTraceTagApp, methodName, cookie);
             } catch (Exception e) {
@@ -156,7 +152,7 @@
     public static void endAsyncSection(@NonNull String methodName, int cookie) {
         if (Build.VERSION.SDK_INT >= 29) {
             Api29Impl.endAsyncSection(methodName, cookie);
-        } else if (Build.VERSION.SDK_INT >= 18) {
+        } else {
             try {
                 sAsyncTraceEndMethod.invoke(null, sTraceTagApp, methodName, cookie);
             } catch (Exception e) {
@@ -175,7 +171,7 @@
     public static void setCounter(@NonNull String counterName, int counterValue) {
         if (Build.VERSION.SDK_INT >= 29) {
             Api29Impl.setCounter(counterName, counterValue);
-        } else if (Build.VERSION.SDK_INT >= 18) {
+        } else {
             try {
                 sTraceCounterMethod.invoke(null, sTraceTagApp, counterName, counterValue);
             } catch (Exception e) {
@@ -213,21 +209,4 @@
             Trace.setCounter(counterName, counterValue);
         }
     }
-
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void beginSection(String sectionName) {
-            Trace.beginSection(sectionName);
-        }
-
-        @DoNotInline
-        static void endSection() {
-            Trace.endSection();
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/provider/DocumentsContractCompat.java b/core/core/src/main/java/androidx/core/provider/DocumentsContractCompat.java
index 3765bfc..923f3c4 100644
--- a/core/core/src/main/java/androidx/core/provider/DocumentsContractCompat.java
+++ b/core/core/src/main/java/androidx/core/provider/DocumentsContractCompat.java
@@ -66,10 +66,7 @@
      * @see DocumentsContract#isDocumentUri(Context, Uri)
      */
     public static boolean isDocumentUri(@NonNull Context context, @Nullable Uri uri) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return DocumentsContractApi19Impl.isDocumentUri(context, uri);
-        }
-        return false;
+        return DocumentsContract.isDocumentUri(context, uri);
     }
 
     /**
@@ -96,10 +93,7 @@
      */
     @Nullable
     public static String getDocumentId(@NonNull Uri documentUri) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return DocumentsContractApi19Impl.getDocumentId(documentUri);
-        }
-        return null;
+        return DocumentsContract.getDocumentId(documentUri);
     }
 
     /**
@@ -124,10 +118,7 @@
      */
     @Nullable
     public static Uri buildDocumentUri(@NonNull String authority, @NonNull String documentId) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return DocumentsContractApi19Impl.buildDocumentUri(authority, documentId);
-        }
-        return null;
+        return DocumentsContract.buildDocumentUri(authority, documentId);
     }
 
     /**
@@ -243,39 +234,9 @@
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
             return DocumentsContractApi24Impl.removeDocument(content, documentUri,
                     parentDocumentUri);
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return DocumentsContractApi19Impl.deleteDocument(content, documentUri);
         } else {
-            return false;
-        }
-    }
-
-    @RequiresApi(19)
-    private static class DocumentsContractApi19Impl {
-
-        @DoNotInline
-        public static Uri buildDocumentUri(String authority, String documentId) {
-            return DocumentsContract.buildDocumentUri(authority, documentId);
-        }
-
-        @DoNotInline
-        static boolean isDocumentUri(Context context, @Nullable Uri uri) {
-            return DocumentsContract.isDocumentUri(context, uri);
-        }
-
-        @DoNotInline
-        static String getDocumentId(Uri documentUri) {
-            return DocumentsContract.getDocumentId(documentUri);
-        }
-
-        @DoNotInline
-        static boolean deleteDocument(ContentResolver content, Uri documentUri)
-                throws FileNotFoundException {
             return DocumentsContract.deleteDocument(content, documentUri);
         }
-
-        private DocumentsContractApi19Impl() {
-        }
     }
 
     @RequiresApi(21)
diff --git a/core/core/src/main/java/androidx/core/provider/FontProvider.java b/core/core/src/main/java/androidx/core/provider/FontProvider.java
index 6b2101b..1559dff 100644
--- a/core/core/src/main/java/androidx/core/provider/FontProvider.java
+++ b/core/core/src/main/java/androidx/core/provider/FontProvider.java
@@ -238,9 +238,7 @@
         void close();
 
         static ContentQueryWrapper make(Context context, Uri uri) {
-            if (Build.VERSION.SDK_INT < 16) {
-                return new ContentQueryWrapperBaseImpl(context);
-            } else if (Build.VERSION.SDK_INT < 24) {
+            if (Build.VERSION.SDK_INT < 24) {
                 return new ContentQueryWrapperApi16Impl(context, uri);
             } else {
                 return new ContentQueryWrapperApi24Impl(context, uri);
@@ -248,25 +246,6 @@
         }
     }
 
-    private static class ContentQueryWrapperBaseImpl implements ContentQueryWrapper {
-        private ContentResolver mResolver;
-        ContentQueryWrapperBaseImpl(Context context) {
-            mResolver = context.getContentResolver();
-        }
-
-        @Override
-        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-                String sortOrder, CancellationSignal cancellationSignal) {
-            return mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
-        }
-
-        @Override
-        public void close() {
-            mResolver = null;
-        }
-    }
-
-    @RequiresApi(16)
     private static class ContentQueryWrapperApi16Impl implements ContentQueryWrapper {
         private final ContentProviderClient mClient;
         ContentQueryWrapperApi16Impl(Context context, Uri uri) {
diff --git a/core/core/src/main/java/androidx/core/text/TextUtilsCompat.java b/core/core/src/main/java/androidx/core/text/TextUtilsCompat.java
index 3085998..bdcd81ee 100644
--- a/core/core/src/main/java/androidx/core/text/TextUtilsCompat.java
+++ b/core/core/src/main/java/androidx/core/text/TextUtilsCompat.java
@@ -16,14 +16,10 @@
 
 package androidx.core.text;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import android.text.TextUtils;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.core.view.ViewCompat;
 
 import java.util.Locale;
@@ -32,9 +28,6 @@
  * Backwards compatible version of {@link TextUtils}.
  */
 public final class TextUtilsCompat {
-    private static final Locale ROOT = new Locale("", "");
-    private static final String ARAB_SCRIPT_SUBTAG = "Arab";
-    private static final String HEBR_SCRIPT_SUBTAG = "Hebr";
 
     /**
      * Html-encode the string.
@@ -44,40 +37,7 @@
      */
     @NonNull
     public static String htmlEncode(@NonNull String s) {
-        if (SDK_INT >= 17) {
-            return TextUtils.htmlEncode(s);
-        } else {
-            StringBuilder sb = new StringBuilder();
-            char c;
-            for (int i = 0; i < s.length(); i++) {
-                c = s.charAt(i);
-                switch (c) {
-                    case '<':
-                        sb.append("&lt;"); //$NON-NLS-1$
-                        break;
-                    case '>':
-                        sb.append("&gt;"); //$NON-NLS-1$
-                        break;
-                    case '&':
-                        sb.append("&amp;"); //$NON-NLS-1$
-                        break;
-                    case '\'':
-                        //http://www.w3.org/TR/xhtml1
-                        // The named character reference &apos; (the apostrophe, U+0027) was
-                        // introduced in XML 1.0 but does not appear in HTML. Authors should
-                        // therefore use &#39; instead of &apos; to work as expected in HTML 4
-                        // user agents.
-                        sb.append("&#39;"); //$NON-NLS-1$
-                        break;
-                    case '"':
-                        sb.append("&quot;"); //$NON-NLS-1$
-                        break;
-                    default:
-                        sb.append(c);
-                }
-            }
-            return sb.toString();
-        }
+        return TextUtils.htmlEncode(s);
     }
 
     /**
@@ -89,58 +49,9 @@
      *         {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
      */
     public static int getLayoutDirectionFromLocale(@Nullable Locale locale) {
-        if (SDK_INT >= 17) {
-            return Api17Impl.getLayoutDirectionFromLocale(locale);
-        } else {
-            if (locale != null && !locale.equals(ROOT)) {
-                final String scriptSubtag = ICUCompat.maximizeAndGetScript(locale);
-                if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
-
-                // This is intentionally limited to Arabic and Hebrew scripts, since older
-                // versions of Android platform only considered those scripts to be right-to-left.
-                if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG)
-                        || scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
-                    return ViewCompat.LAYOUT_DIRECTION_RTL;
-                }
-            }
-            return ViewCompat.LAYOUT_DIRECTION_LTR;
-        }
-    }
-
-    /**
-     * Fallback algorithm to detect the locale direction. Rely on the first char of the
-     * localized locale name. This will not work if the localized locale name is in English
-     * (this is the case for ICU 4.4 and "Urdu" script)
-     *
-     * @param locale the {@link Locale} for which we want the layout direction, maybe be
-     *               {@code null}.
-     * @return the layout direction, either {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
-     *         {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
-     */
-    private static int getLayoutDirectionFromFirstChar(@NonNull Locale locale) {
-        switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
-                return ViewCompat.LAYOUT_DIRECTION_RTL;
-
-            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
-            default:
-                return ViewCompat.LAYOUT_DIRECTION_LTR;
-        }
+        return TextUtils.getLayoutDirectionFromLocale(locale);
     }
 
     private TextUtilsCompat() {
     }
-
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getLayoutDirectionFromLocale(Locale locale) {
-            return TextUtils.getLayoutDirectionFromLocale(locale);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/util/ObjectsCompat.java b/core/core/src/main/java/androidx/core/util/ObjectsCompat.java
index e9e5ccb..b7b9a03 100644
--- a/core/core/src/main/java/androidx/core/util/ObjectsCompat.java
+++ b/core/core/src/main/java/androidx/core/util/ObjectsCompat.java
@@ -15,12 +15,8 @@
  */
 package androidx.core.util;
 
-import android.os.Build;
-
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -51,11 +47,7 @@
      */
     @SuppressWarnings("EqualsReplaceableByObjectsCall")
     public static boolean equals(@Nullable Object a, @Nullable Object b) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.equals(a, b);
-        } else {
-            return (a == b) || (a != null && a.equals(b));
-        }
+        return Objects.equals(a, b);
     }
 
     /**
@@ -93,11 +85,7 @@
      * @see Arrays#hashCode(Object[])
      */
     public static int hash(@Nullable Object... values) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.hash(values);
-        } else {
-            return Arrays.hashCode(values);
-        }
+        return Objects.hash(values);
     }
 
     /**
@@ -159,21 +147,4 @@
         if (obj == null) throw new NullPointerException(message);
         return obj;
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean equals(Object a, Object b) {
-            return Objects.equals(a, b);
-        }
-
-        @DoNotInline
-        static int hash(Object... values) {
-            return Objects.hash(values);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/AccessibilityDelegateCompat.java b/core/core/src/main/java/androidx/core/view/AccessibilityDelegateCompat.java
index 8306bd8..8102330 100644
--- a/core/core/src/main/java/androidx/core/view/AccessibilityDelegateCompat.java
+++ b/core/core/src/main/java/androidx/core/view/AccessibilityDelegateCompat.java
@@ -30,7 +30,6 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
@@ -325,11 +324,9 @@
      */
     @Nullable
     public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(@NonNull View host) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Object provider = Api16Impl.getAccessibilityNodeProvider(mOriginalDelegate, host);
-            if (provider != null) {
-                return new AccessibilityNodeProviderCompat(provider);
-            }
+        Object provider = mOriginalDelegate.getAccessibilityNodeProvider(host);
+        if (provider != null) {
+            return new AccessibilityNodeProviderCompat(provider);
         }
         return null;
     }
@@ -364,8 +361,8 @@
                 break;
             }
         }
-        if (!success && Build.VERSION.SDK_INT >= 16) {
-            success = Api16Impl.performAccessibilityAction(mOriginalDelegate, host, action, args);
+        if (!success) {
+            success = mOriginalDelegate.performAccessibilityAction(host, action, args);
         }
         if (!success && action == R.id.accessibility_action_clickable_span && args != null) {
             success = performClickableSpanAction(
@@ -411,23 +408,4 @@
                 view.getTag(R.id.tag_accessibility_actions);
         return actions == null ? Collections.emptyList() : actions;
     }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static AccessibilityNodeProvider getAccessibilityNodeProvider(
-                AccessibilityDelegate accessibilityDelegate, View host) {
-            return accessibilityDelegate.getAccessibilityNodeProvider(host);
-        }
-
-        @DoNotInline
-        static boolean performAccessibilityAction(AccessibilityDelegate accessibilityDelegate,
-                View host, int action, Bundle args) {
-            return accessibilityDelegate.performAccessibilityAction(host, action, args);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/GravityCompat.java b/core/core/src/main/java/androidx/core/view/GravityCompat.java
index 5935241..b7e1215 100644
--- a/core/core/src/main/java/androidx/core/view/GravityCompat.java
+++ b/core/core/src/main/java/androidx/core/view/GravityCompat.java
@@ -17,14 +17,10 @@
 
 package androidx.core.view;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import android.graphics.Rect;
 import android.view.Gravity;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 
 /**
  * Compatibility shim for accessing newer functionality from {@link Gravity}.
@@ -65,11 +61,7 @@
      */
     public static void apply(int gravity, int w, int h, @NonNull Rect container,
             @NonNull Rect outRect, int layoutDirection) {
-        if (SDK_INT >= 17) {
-            Api17Impl.apply(gravity, w, h, container, outRect, layoutDirection);
-        } else {
-            Gravity.apply(gravity, w, h, container, outRect);
-        }
+        Gravity.apply(gravity, w, h, container, outRect, layoutDirection);
     }
 
     /**
@@ -99,11 +91,7 @@
      */
     public static void apply(int gravity, int w, int h, @NonNull Rect container,
             int xAdj, int yAdj, @NonNull Rect outRect, int layoutDirection) {
-        if (SDK_INT >= 17) {
-            Api17Impl.apply(gravity, w, h, container, xAdj, yAdj, outRect, layoutDirection);
-        } else {
-            Gravity.apply(gravity, w, h, container, xAdj, yAdj, outRect);
-        }
+        Gravity.apply(gravity, w, h, container, xAdj, yAdj, outRect, layoutDirection);
     }
 
     /**
@@ -128,11 +116,7 @@
      */
     public static void applyDisplay(int gravity, @NonNull Rect display, @NonNull Rect inoutObj,
             int layoutDirection) {
-        if (SDK_INT >= 17) {
-            Api17Impl.applyDisplay(gravity, display, inoutObj, layoutDirection);
-        } else {
-            Gravity.applyDisplay(gravity, display, inoutObj);
-        }
+        Gravity.applyDisplay(gravity, display, inoutObj, layoutDirection);
     }
 
     /**
@@ -147,38 +131,9 @@
      * @return gravity converted to absolute (horizontal) values.
      */
     public static int getAbsoluteGravity(int gravity, int layoutDirection) {
-        if (SDK_INT >= 17) {
-            return Gravity.getAbsoluteGravity(gravity, layoutDirection);
-        } else {
-            // Just strip off the relative bit to get LEFT/RIGHT.
-            return gravity & ~RELATIVE_LAYOUT_DIRECTION;
-        }
+        return Gravity.getAbsoluteGravity(gravity, layoutDirection);
     }
 
     private GravityCompat() {
     }
-
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void apply(int gravity, int w, int h, Rect container, Rect outRect,
-                int layoutDirection) {
-            Gravity.apply(gravity, w, h, container, outRect, layoutDirection);
-        }
-
-        @DoNotInline
-        static void apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj,
-                Rect outRect, int layoutDirection) {
-            Gravity.apply(gravity, w, h, container, xAdj, yAdj, outRect, layoutDirection);
-        }
-
-        @DoNotInline
-        static void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection) {
-            Gravity.applyDisplay(gravity, display, inoutObj, layoutDirection);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/MarginLayoutParamsCompat.java b/core/core/src/main/java/androidx/core/view/MarginLayoutParamsCompat.java
index 4237d43..8039d09 100644
--- a/core/core/src/main/java/androidx/core/view/MarginLayoutParamsCompat.java
+++ b/core/core/src/main/java/androidx/core/view/MarginLayoutParamsCompat.java
@@ -17,14 +17,10 @@
 
 package androidx.core.view;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import android.view.View;
 import android.view.ViewGroup;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 
 /**
  * Helper for accessing API features in
@@ -44,11 +40,7 @@
      * @return the margin along the starting edge in pixels
      */
     public static int getMarginStart(@NonNull ViewGroup.MarginLayoutParams lp) {
-        if (SDK_INT >= 17) {
-            return Api17Impl.getMarginStart(lp);
-        } else {
-            return lp.leftMargin;
-        }
+        return lp.getMarginStart();
     }
 
     /**
@@ -63,11 +55,7 @@
      * @return the margin along the ending edge in pixels
      */
     public static int getMarginEnd(@NonNull ViewGroup.MarginLayoutParams lp) {
-        if (SDK_INT >= 17) {
-            return Api17Impl.getMarginEnd(lp);
-        } else {
-            return lp.rightMargin;
-        }
+        return lp.getMarginEnd();
     }
 
     /**
@@ -82,11 +70,7 @@
      * @param marginStart the desired start margin in pixels
      */
     public static void setMarginStart(@NonNull ViewGroup.MarginLayoutParams lp, int marginStart) {
-        if (SDK_INT >= 17) {
-            Api17Impl.setMarginStart(lp, marginStart);
-        } else {
-            lp.leftMargin = marginStart;
-        }
+        lp.setMarginStart(marginStart);
     }
 
     /**
@@ -101,11 +85,7 @@
      * @param marginEnd the desired end margin in pixels
      */
     public static void setMarginEnd(@NonNull ViewGroup.MarginLayoutParams lp, int marginEnd) {
-        if (SDK_INT >= 17) {
-            Api17Impl.setMarginEnd(lp, marginEnd);
-        } else {
-            lp.rightMargin = marginEnd;
-        }
+        lp.setMarginEnd(marginEnd);
     }
 
     /**
@@ -114,11 +94,7 @@
      * @return true if either marginStart or marginEnd has been set.
      */
     public static boolean isMarginRelative(@NonNull ViewGroup.MarginLayoutParams lp) {
-        if (SDK_INT >= 17) {
-            return Api17Impl.isMarginRelative(lp);
-        } else {
-            return false;
-        }
+        return lp.isMarginRelative();
     }
 
     /**
@@ -129,11 +105,7 @@
      */
     public static int getLayoutDirection(@NonNull ViewGroup.MarginLayoutParams lp) {
         int result;
-        if (SDK_INT >= 17) {
-            result = Api17Impl.getLayoutDirection(lp);
-        } else {
-            result = ViewCompat.LAYOUT_DIRECTION_LTR;
-        }
+        result = lp.getLayoutDirection();
 
         if ((result != ViewCompat.LAYOUT_DIRECTION_LTR)
                 && (result != ViewCompat.LAYOUT_DIRECTION_RTL)) {
@@ -154,9 +126,7 @@
      */
     public static void setLayoutDirection(@NonNull ViewGroup.MarginLayoutParams lp,
             int layoutDirection) {
-        if (SDK_INT >= 17) {
-            Api17Impl.setLayoutDirection(lp, layoutDirection);
-        }
+        lp.setLayoutDirection(layoutDirection);
     }
 
     /**
@@ -165,60 +135,10 @@
      */
     public static void resolveLayoutDirection(@NonNull ViewGroup.MarginLayoutParams lp,
             int layoutDirection) {
-        if (SDK_INT >= 17) {
-            Api17Impl.resolveLayoutDirection(lp, layoutDirection);
-        }
+        lp.resolveLayoutDirection(layoutDirection);
     }
 
     private MarginLayoutParamsCompat() {
     }
 
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getMarginStart(ViewGroup.MarginLayoutParams marginLayoutParams) {
-            return marginLayoutParams.getMarginStart();
-        }
-
-        @DoNotInline
-        static int getMarginEnd(ViewGroup.MarginLayoutParams marginLayoutParams) {
-            return marginLayoutParams.getMarginEnd();
-        }
-
-        @DoNotInline
-        static void setMarginStart(ViewGroup.MarginLayoutParams marginLayoutParams, int start) {
-            marginLayoutParams.setMarginStart(start);
-        }
-
-        @DoNotInline
-        static void setMarginEnd(ViewGroup.MarginLayoutParams marginLayoutParams, int end) {
-            marginLayoutParams.setMarginEnd(end);
-        }
-
-        @DoNotInline
-        static boolean isMarginRelative(ViewGroup.MarginLayoutParams marginLayoutParams) {
-            return marginLayoutParams.isMarginRelative();
-        }
-
-        @DoNotInline
-        static int getLayoutDirection(ViewGroup.MarginLayoutParams marginLayoutParams) {
-            return marginLayoutParams.getLayoutDirection();
-        }
-
-        @DoNotInline
-        static void setLayoutDirection(ViewGroup.MarginLayoutParams marginLayoutParams,
-                int layoutDirection) {
-            marginLayoutParams.setLayoutDirection(layoutDirection);
-        }
-
-        @DoNotInline
-        static void resolveLayoutDirection(ViewGroup.MarginLayoutParams marginLayoutParams,
-                int layoutDirection) {
-            marginLayoutParams.resolveLayoutDirection(layoutDirection);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/ScaleGestureDetectorCompat.java b/core/core/src/main/java/androidx/core/view/ScaleGestureDetectorCompat.java
index 317f3b4..f24ea50 100644
--- a/core/core/src/main/java/androidx/core/view/ScaleGestureDetectorCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ScaleGestureDetectorCompat.java
@@ -16,12 +16,9 @@
 
 package androidx.core.view;
 
-import android.os.Build;
 import android.view.ScaleGestureDetector;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 
 /**
  * Helper for accessing features in {@link ScaleGestureDetector}.
@@ -56,9 +53,7 @@
      */
     public static void setQuickScaleEnabled(
             @NonNull ScaleGestureDetector scaleGestureDetector, boolean enabled) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.setQuickScaleEnabled(scaleGestureDetector, enabled);
-        }
+        scaleGestureDetector.setQuickScaleEnabled(enabled);
     }
 
     /**
@@ -81,28 +76,6 @@
      * {@link #setQuickScaleEnabled(ScaleGestureDetector, boolean)}.
      */
     public static boolean isQuickScaleEnabled(@NonNull ScaleGestureDetector scaleGestureDetector) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.isQuickScaleEnabled(scaleGestureDetector);
-        } else {
-            return false;
-        }
-    }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setQuickScaleEnabled(ScaleGestureDetector scaleGestureDetector,
-                boolean scales) {
-            scaleGestureDetector.setQuickScaleEnabled(scales);
-        }
-
-        @DoNotInline
-        static boolean isQuickScaleEnabled(ScaleGestureDetector scaleGestureDetector) {
-            return scaleGestureDetector.isQuickScaleEnabled();
-        }
+        return scaleGestureDetector.isQuickScaleEnabled();
     }
 }
diff --git a/core/core/src/main/java/androidx/core/view/ViewCompat.java b/core/core/src/main/java/androidx/core/view/ViewCompat.java
index 32cba97..a916ccf 100644
--- a/core/core/src/main/java/androidx/core/view/ViewCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewCompat.java
@@ -20,7 +20,6 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
-import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.ClipData;
@@ -513,11 +512,6 @@
 
     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
 
-    private static Field sMinWidthField;
-    private static boolean sMinWidthFieldFetched;
-    private static Field sMinHeightField;
-    private static boolean sMinHeightFieldFetched;
-
     private static Method sDispatchStartTemporaryDetach;
     private static Method sDispatchFinishTemporaryDetach;
     private static boolean sTempDetachBound;
@@ -1271,10 +1265,7 @@
      * @return true if the view has transient state
      */
     public static boolean hasTransientState(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.hasTransientState(view);
-        }
-        return false;
+        return view.hasTransientState();
     }
 
     /**
@@ -1285,9 +1276,7 @@
      * @param hasTransientState true if this view has transient state
      */
     public static void setHasTransientState(@NonNull View view, boolean hasTransientState) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.setHasTransientState(view, hasTransientState);
-        }
+        view.setHasTransientState(hasTransientState);
     }
 
     /**
@@ -1300,11 +1289,7 @@
      * @param view View to invalidate
      */
     public static void postInvalidateOnAnimation(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.postInvalidateOnAnimation(view);
-        } else {
-            view.postInvalidate();
-        }
+        view.postInvalidateOnAnimation();
     }
 
     /**
@@ -1322,11 +1307,7 @@
      */
     public static void postInvalidateOnAnimation(@NonNull View view, int left, int top,
             int right, int bottom) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.postInvalidateOnAnimation(view, left, top, right, bottom);
-        } else {
-            view.postInvalidate(left, top, right, bottom);
-        }
+        view.postInvalidateOnAnimation(left, top, right, bottom);
     }
 
     /**
@@ -1340,11 +1321,7 @@
      * @param action The Runnable that will be executed.
      */
     public static void postOnAnimation(@NonNull View view, @NonNull Runnable action) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.postOnAnimation(view, action);
-        } else {
-            view.postDelayed(action, ValueAnimator.getFrameDelay());
-        }
+        view.postOnAnimation(action);
     }
 
     /**
@@ -1363,11 +1340,7 @@
     @SuppressLint("LambdaLast")
     public static void postOnAnimationDelayed(@NonNull View view, @NonNull Runnable action,
             long delayMillis) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.postOnAnimationDelayed(view, action, delayMillis);
-        } else {
-            view.postDelayed(action, ValueAnimator.getFrameDelay() + delayMillis);
-        }
+        view.postOnAnimationDelayed(action, delayMillis);
     }
 
     /**
@@ -1385,10 +1358,7 @@
      */
     @ImportantForAccessibility
     public static int getImportantForAccessibility(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getImportantForAccessibility(view);
-        }
-        return IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+        return view.getImportantForAccessibility();
     }
 
     /**
@@ -1413,18 +1383,7 @@
     @UiThread
     public static void setImportantForAccessibility(@NonNull View view,
             @ImportantForAccessibility int mode) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api16Impl.setImportantForAccessibility(view, mode);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS is not available
-            // on this platform so replace with IMPORTANT_FOR_ACCESSIBILITY_NO
-            // which is closer semantically.
-            if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
-                mode = IMPORTANT_FOR_ACCESSIBILITY_NO;
-            }
-            //noinspection WrongConstant
-            Api16Impl.setImportantForAccessibility(view, mode);
-        }
+        view.setImportantForAccessibility(mode);
     }
 
     /**
@@ -1493,10 +1452,7 @@
      */
     public static boolean performAccessibilityAction(@NonNull View view, int action,
             @Nullable Bundle arguments) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.performAccessibilityAction(view, action, arguments);
-        }
-        return false;
+        return view.performAccessibilityAction(action, arguments);
     }
 
     /**
@@ -1817,11 +1773,9 @@
      */
     @Nullable
     public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            AccessibilityNodeProvider provider = Api16Impl.getAccessibilityNodeProvider(view);
-            if (provider != null) {
-                return new AccessibilityNodeProviderCompat(provider);
-            }
+        AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
+        if (provider != null) {
+            return new AccessibilityNodeProviderCompat(provider);
         }
         return null;
     }
@@ -2024,10 +1978,7 @@
      */
     @Nullable
     public static ViewParent getParentForAccessibility(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getParentForAccessibility(view);
-        }
-        return view.getParent();
+        return view.getParentForAccessibility();
     }
 
     /**
@@ -2392,30 +2343,7 @@
     @SuppressWarnings({"JavaReflectionMemberAccess", "ConstantConditions"})
     // Reflective access to private field, unboxing result of reflective get()
     public static int getMinimumWidth(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getMinimumWidth(view);
-        } else {
-            if (!sMinWidthFieldFetched) {
-                try {
-                    sMinWidthField = View.class.getDeclaredField("mMinWidth");
-                    sMinWidthField.setAccessible(true);
-                } catch (NoSuchFieldException e) {
-                    // Couldn't find the field. Abort!
-                }
-                sMinWidthFieldFetched = true;
-            }
-
-            if (sMinWidthField != null) {
-                try {
-                    return (int) sMinWidthField.get(view);
-                } catch (Exception e) {
-                    // Field get failed. Oh well...
-                }
-            }
-        }
-
-        // We failed, return 0
-        return 0;
+        return view.getMinimumWidth();
     }
 
     /**
@@ -2428,30 +2356,7 @@
     @SuppressWarnings({"JavaReflectionMemberAccess", "ConstantConditions"})
     // Reflective access to private field, unboxing result of reflective get()
     public static int getMinimumHeight(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getMinimumHeight(view);
-        } else {
-            if (!sMinHeightFieldFetched) {
-                try {
-                    sMinHeightField = View.class.getDeclaredField("mMinHeight");
-                    sMinHeightField.setAccessible(true);
-                } catch (NoSuchFieldException e) {
-                    // Couldn't find the field. Abort!
-                }
-                sMinHeightFieldFetched = true;
-            }
-
-            if (sMinHeightField != null) {
-                try {
-                    return (int) sMinHeightField.get(view);
-                } catch (Exception e) {
-                    // Field get failed. Oh well...
-                }
-            }
-        }
-
-        // We failed, return 0
-        return 0;
+        return view.getMinimumHeight();
     }
 
     /**
@@ -2849,10 +2754,7 @@
      */
     @Deprecated
     public static int getWindowSystemUiVisibility(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getWindowSystemUiVisibility(view);
-        }
-        return 0;
+        return view.getWindowSystemUiVisibility();
     }
 
     /**
@@ -2864,8 +2766,8 @@
     public static void requestApplyInsets(@NonNull View view) {
         if (Build.VERSION.SDK_INT >= 20) {
             Api20Impl.requestApplyInsets(view);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.requestFitSystemWindows(view);
+        } else {
+            view.requestFitSystemWindows();
         }
     }
 
@@ -2911,10 +2813,7 @@
      * @param view view for which to get the state.
      */
     public static boolean getFitsSystemWindows(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getFitsSystemWindows(view);
-        }
-        return false;
+        return view.getFitsSystemWindows();
     }
 
     /**
@@ -3401,10 +3300,7 @@
      * @return true if the content in this view might overlap, false otherwise.
      */
     public static boolean hasOverlappingRendering(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.hasOverlappingRendering(view);
-        }
-        return true;
+        return view.hasOverlappingRendering();
     }
 
     /**
@@ -3430,11 +3326,7 @@
      * @param background the drawable to use as view background.
      */
     public static void setBackground(@NonNull View view, @Nullable Drawable background) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.setBackground(view, background);
-        } else {
-            view.setBackgroundDrawable(background);
-        }
+        view.setBackground(background);
     }
 
     /**
@@ -3475,7 +3367,7 @@
                     if (background.isStateful()) {
                         background.setState(view.getDrawableState());
                     }
-                    Api16Impl.setBackground(view, background);
+                    view.setBackground(background);
                 }
             }
         } else if (view instanceof TintableBackgroundView) {
@@ -3523,7 +3415,7 @@
                     if (background.isStateful()) {
                         background.setState(view.getDrawableState());
                     }
-                    Api16Impl.setBackground(view, background);
+                    view.setBackground(background);
                 }
             }
         } else if (view instanceof TintableBackgroundView) {
@@ -5082,7 +4974,7 @@
         @RequiresApi(19)
         private void unregisterForLayoutCallback(View view) {
             ViewTreeObserver observer = view.getViewTreeObserver();
-            Api16Impl.removeOnGlobalLayoutListener(observer, this);
+            observer.removeOnGlobalLayoutListener(this);
         }
     }
 
@@ -5870,109 +5762,6 @@
         }
     }
 
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean hasTransientState(View view) {
-            return view.hasTransientState();
-        }
-
-        @DoNotInline
-        static void setHasTransientState(View view, boolean hasTransientState) {
-            view.setHasTransientState(hasTransientState);
-        }
-
-        @DoNotInline
-        static void postInvalidateOnAnimation(View view) {
-            view.postInvalidateOnAnimation();
-        }
-
-        @DoNotInline
-        static void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
-            view.postInvalidateOnAnimation(left, top, right, bottom);
-        }
-
-        @DoNotInline
-        static void postOnAnimation(View view, Runnable action) {
-            view.postOnAnimation(action);
-        }
-
-        @DoNotInline
-        static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
-            view.postOnAnimationDelayed(action, delayMillis);
-        }
-
-        @DoNotInline
-        static int getImportantForAccessibility(View view) {
-            return view.getImportantForAccessibility();
-        }
-
-        @DoNotInline
-        static void setImportantForAccessibility(View view, int mode) {
-            view.setImportantForAccessibility(mode);
-        }
-
-        @DoNotInline
-        static AccessibilityNodeProvider getAccessibilityNodeProvider(View view) {
-            return view.getAccessibilityNodeProvider();
-        }
-
-        @DoNotInline
-        static ViewParent getParentForAccessibility(View view) {
-            return view.getParentForAccessibility();
-        }
-
-        @DoNotInline
-        static int getMinimumWidth(View view) {
-            return view.getMinimumWidth();
-        }
-
-        @DoNotInline
-        static int getMinimumHeight(View view) {
-            return view.getMinimumHeight();
-        }
-
-        @DoNotInline
-        static int getWindowSystemUiVisibility(View view) {
-            return view.getWindowSystemUiVisibility();
-        }
-
-        @DoNotInline
-        static void requestFitSystemWindows(View view) {
-            view.requestFitSystemWindows();
-        }
-
-        @DoNotInline
-        static boolean getFitsSystemWindows(View view) {
-            return view.getFitsSystemWindows();
-        }
-
-        @DoNotInline
-        static boolean performAccessibilityAction(View view, int action, Bundle arguments) {
-            return view.performAccessibilityAction(action, arguments);
-        }
-
-        @DoNotInline
-        static boolean hasOverlappingRendering(View view) {
-            return view.hasOverlappingRendering();
-        }
-
-        @DoNotInline
-        static void setBackground(View view, Drawable background) {
-            view.setBackground(background);
-        }
-
-        @DoNotInline
-        static void removeOnGlobalLayoutListener(ViewTreeObserver viewTreeObserver,
-                ViewTreeObserver.OnGlobalLayoutListener victim) {
-            viewTreeObserver.removeOnGlobalLayoutListener(victim);
-        }
-    }
-
     @RequiresApi(28)
     static class Api28Impl {
         private Api28Impl() {
diff --git a/core/core/src/main/java/androidx/core/view/ViewGroupCompat.java b/core/core/src/main/java/androidx/core/view/ViewGroupCompat.java
index 207e55f..3034440 100644
--- a/core/core/src/main/java/androidx/core/view/ViewGroupCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewGroupCompat.java
@@ -113,10 +113,7 @@
      * @see #setLayoutMode(ViewGroup, int)
      */
     public static int getLayoutMode(@NonNull ViewGroup group) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return Api18Impl.getLayoutMode(group);
-        }
-        return LAYOUT_MODE_CLIP_BOUNDS;
+        return group.getLayoutMode();
     }
 
     /**
@@ -130,9 +127,7 @@
      * @see #getLayoutMode(ViewGroup)
      */
     public static void setLayoutMode(@NonNull ViewGroup group, int mode) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api18Impl.setLayoutMode(group, mode);
-        }
+        group.setLayoutMode(mode);
     }
 
     /**
@@ -191,23 +186,6 @@
         return ViewCompat.SCROLL_AXIS_NONE;
     }
 
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getLayoutMode(ViewGroup viewGroup) {
-            return viewGroup.getLayoutMode();
-        }
-
-        @DoNotInline
-        static void setLayoutMode(ViewGroup viewGroup, int layoutMode) {
-            viewGroup.setLayoutMode(layoutMode);
-        }
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() {
diff --git a/core/core/src/main/java/androidx/core/view/ViewParentCompat.java b/core/core/src/main/java/androidx/core/view/ViewParentCompat.java
index 517fc9b8..1e3cdef 100644
--- a/core/core/src/main/java/androidx/core/view/ViewParentCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewParentCompat.java
@@ -507,9 +507,7 @@
      */
     public static void notifySubtreeAccessibilityStateChanged(@NonNull ViewParent parent,
             @NonNull View child, @NonNull View source, int changeType) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.notifySubtreeAccessibilityStateChanged(parent, child, source, changeType);
-        }
+        parent.notifySubtreeAccessibilityStateChanged(child, source, changeType);
     }
 
     private static int[] getTempNestedScrollConsumed() {
@@ -522,19 +520,6 @@
         return sTempNestedScrollConsumed;
     }
 
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void notifySubtreeAccessibilityStateChanged(ViewParent viewParent, View view,
-                View view1, int i) {
-            viewParent.notifySubtreeAccessibilityStateChanged(view, view1, i);
-        }
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() {
diff --git a/core/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java b/core/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java
index 30f216e..daa7481 100644
--- a/core/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java
@@ -228,13 +228,8 @@
     public ViewPropertyAnimatorCompat withEndAction(@NonNull Runnable runnable) {
         View view;
         if ((view = mView.get()) != null) {
-            if (Build.VERSION.SDK_INT >= 16) {
-                ViewPropertyAnimator animator = view.animate();
-                Api16Impl.withEndAction(animator, runnable);
-            } else {
-                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
-                mEndAction = runnable;
-            }
+            ViewPropertyAnimator animator = view.animate();
+            animator.withEndAction(runnable);
         }
         return this;
     }
@@ -282,10 +277,8 @@
     public Interpolator getInterpolator() {
         View view;
         if ((view = mView.get()) != null) {
-            if (Build.VERSION.SDK_INT >= 18) {
-                ViewPropertyAnimator animator = view.animate();
-                return Api18Impl.getInterpolator(animator);
-            }
+            ViewPropertyAnimator animator = view.animate();
+            return (Interpolator) animator.getInterpolator();
         }
         return null;
     }
@@ -722,13 +715,8 @@
     public ViewPropertyAnimatorCompat withLayer() {
         View view;
         if ((view = mView.get()) != null) {
-            if (Build.VERSION.SDK_INT >= 16) {
-                ViewPropertyAnimator animator = view.animate();
-                Api16Impl.withLayer(animator);
-            } else {
-                mOldLayerType = view.getLayerType();
-                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
-            }
+            ViewPropertyAnimator animator = view.animate();
+            animator.withLayer();
         }
         return this;
     }
@@ -752,13 +740,8 @@
     public ViewPropertyAnimatorCompat withStartAction(@NonNull Runnable runnable) {
         View view;
         if ((view = mView.get()) != null) {
-            if (Build.VERSION.SDK_INT >= 16) {
-                ViewPropertyAnimator animator = view.animate();
-                Api16Impl.withStartAction(animator, runnable);
-            } else {
-                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
-                mStartAction = runnable;
-            }
+            ViewPropertyAnimator animator = view.animate();
+            animator.withStartAction(runnable);
         }
         return this;
     }
@@ -776,12 +759,7 @@
             final @Nullable ViewPropertyAnimatorListener listener) {
         final View view;
         if ((view = mView.get()) != null) {
-            if (Build.VERSION.SDK_INT >= 16) {
-                setListenerInternal(view, listener);
-            } else {
-                view.setTag(LISTENER_TAG_ID, listener);
-                setListenerInternal(view, new ViewPropertyAnimatorListenerApi14(this));
-            }
+            setListenerInternal(view, listener);
         }
         return this;
     }
@@ -824,55 +802,16 @@
             final @Nullable ViewPropertyAnimatorUpdateListener listener) {
         final View view;
         if ((view = mView.get()) != null) {
-            if (Build.VERSION.SDK_INT >= 19) {
-                ValueAnimator.AnimatorUpdateListener wrapped = null;
-                if (listener != null) {
+            ValueAnimator.AnimatorUpdateListener wrapped = null;
+            if (listener != null) {
                     wrapped = valueAnimator -> listener.onAnimationUpdate(view);
                 }
-                ViewPropertyAnimator animator = view.animate();
-                Api19Impl.setUpdateListener(animator, wrapped);
-            }
+            ViewPropertyAnimator animator = view.animate();
+            animator.setUpdateListener(wrapped);
         }
         return this;
     }
 
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static ViewPropertyAnimator withEndAction(ViewPropertyAnimator viewPropertyAnimator,
-                Runnable runnable) {
-            return viewPropertyAnimator.withEndAction(runnable);
-        }
-
-        @DoNotInline
-        static ViewPropertyAnimator withLayer(ViewPropertyAnimator viewPropertyAnimator) {
-            return viewPropertyAnimator.withLayer();
-        }
-
-        @DoNotInline
-        static ViewPropertyAnimator withStartAction(ViewPropertyAnimator viewPropertyAnimator,
-                Runnable runnable) {
-            return viewPropertyAnimator.withStartAction(runnable);
-        }
-    }
-
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static Interpolator getInterpolator(ViewPropertyAnimator viewPropertyAnimator) {
-            return (Interpolator) viewPropertyAnimator.getInterpolator();
-        }
-
-    }
-
     @RequiresApi(21)
     static class Api21Impl {
         private Api21Impl() {
@@ -901,18 +840,4 @@
             return viewPropertyAnimator.zBy(value);
         }
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static ViewPropertyAnimator setUpdateListener(ViewPropertyAnimator viewPropertyAnimator,
-                ValueAnimator.AnimatorUpdateListener listener) {
-            return viewPropertyAnimator.setUpdateListener(listener);
-        }
-
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/WindowCompat.java b/core/core/src/main/java/androidx/core/view/WindowCompat.java
index 4cdb4dd..b3bb0b1 100644
--- a/core/core/src/main/java/androidx/core/view/WindowCompat.java
+++ b/core/core/src/main/java/androidx/core/view/WindowCompat.java
@@ -118,7 +118,7 @@
             final boolean decorFitsSystemWindows) {
         if (Build.VERSION.SDK_INT >= 30) {
             Api30Impl.setDecorFitsSystemWindows(window, decorFitsSystemWindows);
-        } else if (Build.VERSION.SDK_INT >= 16) {
+        } else {
             Api16Impl.setDecorFitsSystemWindows(window, decorFitsSystemWindows);
         }
     }
@@ -136,13 +136,11 @@
         return new WindowInsetsControllerCompat(window, view);
     }
 
-    @RequiresApi(16)
     static class Api16Impl {
         private Api16Impl() {
             // This class is not instantiable.
         }
 
-        @DoNotInline
         static void setDecorFitsSystemWindows(@NonNull Window window,
                 final boolean decorFitsSystemWindows) {
             final int decorFitsFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
index c8cd11d..30470be 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
@@ -18,6 +18,7 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
+import android.annotation.SuppressLint;
 import android.os.Build;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
@@ -431,9 +432,7 @@
      */
     public static void setContentChangeTypes(@NonNull AccessibilityEvent event,
             @ContentChangeType int changeTypes) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.setContentChangeTypes(event, changeTypes);
-        }
+        event.setContentChangeTypes(changeTypes);
     }
 
     /**
@@ -450,13 +449,10 @@
      *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED}
      *         </ul>
      */
+    @SuppressLint("WrongConstant")
     @ContentChangeType
     public static int getContentChangeTypes(@NonNull AccessibilityEvent event) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getContentChangeTypes(event);
-        } else {
-            return 0;
-        }
+        return event.getContentChangeTypes();
     }
 
     /**
@@ -468,9 +464,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public static void setMovementGranularity(@NonNull AccessibilityEvent event, int granularity) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.setMovementGranularity(event, granularity);
-        }
+        event.setMovementGranularity(granularity);
     }
 
     /**
@@ -479,11 +473,7 @@
      * @return The granularity.
      */
     public static int getMovementGranularity(@NonNull AccessibilityEvent event) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getMovementGranularity(event);
-        } else {
-            return 0;
-        }
+        return event.getMovementGranularity();
     }
 
     /**
@@ -505,9 +495,7 @@
      * @see AccessibilityNodeInfoCompat#performAction(int)
      */
     public static void setAction(@NonNull AccessibilityEvent event, int action) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.setAction(event, action);
-        }
+        event.setAction(action);
     }
 
     /**
@@ -516,11 +504,7 @@
      * @return The action.
      */
     public static int getAction(@NonNull AccessibilityEvent event) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getAction(event);
-        } else {
-            return 0;
-        }
+        return event.getAction();
     }
 
     /**
@@ -589,47 +573,4 @@
             event.setAccessibilityDataSensitive(accessibilityDataSensitive);
         }
     }
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setContentChangeTypes(AccessibilityEvent accessibilityEvent, int changeTypes) {
-            accessibilityEvent.setContentChangeTypes(changeTypes);
-        }
-
-        @DoNotInline
-        static int getContentChangeTypes(AccessibilityEvent accessibilityEvent) {
-            return accessibilityEvent.getContentChangeTypes();
-        }
-    }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setMovementGranularity(AccessibilityEvent accessibilityEvent, int granularity) {
-            accessibilityEvent.setMovementGranularity(granularity);
-        }
-
-        @DoNotInline
-        static int getMovementGranularity(AccessibilityEvent accessibilityEvent) {
-            return accessibilityEvent.getMovementGranularity();
-        }
-
-        @DoNotInline
-        static void setAction(AccessibilityEvent accessibilityEvent, int action) {
-            accessibilityEvent.setAction(action);
-        }
-
-        @DoNotInline
-        static int getAction(AccessibilityEvent accessibilityEvent) {
-            return accessibilityEvent.getAction();
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityManagerCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityManagerCompat.java
index a5e0a2b..0073c4b 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityManagerCompat.java
@@ -168,11 +168,8 @@
     public static boolean addTouchExplorationStateChangeListener(
             @NonNull AccessibilityManager manager,
             @NonNull TouchExplorationStateChangeListener listener) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.addTouchExplorationStateChangeListenerWrapper(manager, listener);
-        } else {
-            return false;
-        }
+        return manager.addTouchExplorationStateChangeListener(
+                new TouchExplorationStateChangeListenerWrapper(listener));
     }
 
     /**
@@ -185,11 +182,8 @@
     public static boolean removeTouchExplorationStateChangeListener(
             @NonNull AccessibilityManager manager,
             @NonNull TouchExplorationStateChangeListener listener) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.removeTouchExplorationStateChangeListenerWrapper(manager, listener);
-        } else {
-            return false;
-        }
+        return manager.removeTouchExplorationStateChangeListener(
+                new TouchExplorationStateChangeListenerWrapper(listener));
     }
 
 
@@ -316,26 +310,4 @@
             return accessibilityManager.isRequestFromAccessibilityTool();
         }
     }
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean addTouchExplorationStateChangeListenerWrapper(
-                AccessibilityManager accessibilityManager,
-                TouchExplorationStateChangeListener listener) {
-            return accessibilityManager.addTouchExplorationStateChangeListener(
-                    new TouchExplorationStateChangeListenerWrapper(listener));
-        }
-
-        @DoNotInline
-        static boolean removeTouchExplorationStateChangeListenerWrapper(
-                AccessibilityManager accessibilityManager,
-                TouchExplorationStateChangeListener listener) {
-            return accessibilityManager.removeTouchExplorationStateChangeListener(
-                    new TouchExplorationStateChangeListenerWrapper(listener));
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 7316184..596cb43 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -994,11 +994,9 @@
             if (Build.VERSION.SDK_INT >= 21) {
                 return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
                         rowCount, columnCount, hierarchical, selectionMode));
-            } else if (Build.VERSION.SDK_INT >= 19) {
+            } else {
                 return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
                         rowCount, columnCount, hierarchical));
-            } else {
-                return new CollectionInfoCompat(null);
             }
         }
 
@@ -1013,12 +1011,8 @@
          */
         public static CollectionInfoCompat obtain(int rowCount, int columnCount,
                 boolean hierarchical) {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
-                        rowCount, columnCount, hierarchical));
-            } else {
-                return new CollectionInfoCompat(null);
-            }
+            return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
+                    rowCount, columnCount, hierarchical));
         }
 
         CollectionInfoCompat(Object info) {
@@ -1031,11 +1025,7 @@
          * @return The column count, or -1 if count is unknown.
          */
         public int getColumnCount() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getColumnCount();
-            } else {
-                return -1;
-            }
+            return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getColumnCount();
         }
 
         /**
@@ -1044,11 +1034,7 @@
          * @return The row count, or -1 if count is unknown.
          */
         public int getRowCount() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getRowCount();
-            } else {
-                return -1;
-            }
+            return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getRowCount();
         }
 
         /**
@@ -1057,11 +1043,7 @@
          * @return Whether the collection is hierarchical.
          */
         public boolean isHierarchical() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionInfo) mInfo).isHierarchical();
-            } else {
-                return false;
-            }
+            return ((AccessibilityNodeInfo.CollectionInfo) mInfo).isHierarchical();
         }
 
         /**
@@ -1115,11 +1097,9 @@
             if (Build.VERSION.SDK_INT >= 21) {
                 return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
                         rowIndex, rowSpan, columnIndex, columnSpan, heading, selected));
-            } else if (Build.VERSION.SDK_INT >= 19) {
+            } else {
                 return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
                         rowIndex, rowSpan, columnIndex, columnSpan, heading));
-            } else {
-                return new CollectionItemInfoCompat(null);
             }
         }
 
@@ -1137,12 +1117,8 @@
          */
         public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan,
                 int columnIndex, int columnSpan, boolean heading) {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
-                        rowIndex, rowSpan, columnIndex, columnSpan, heading));
-            } else {
-                return new CollectionItemInfoCompat(null);
-            }
+            return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
+                    rowIndex, rowSpan, columnIndex, columnSpan, heading));
         }
 
         CollectionItemInfoCompat(Object info) {
@@ -1155,11 +1131,7 @@
          * @return The column index.
          */
         public int getColumnIndex() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnIndex();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnIndex();
         }
 
         /**
@@ -1168,11 +1140,7 @@
          * @return The column span.
          */
         public int getColumnSpan() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnSpan();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnSpan();
         }
 
         /**
@@ -1181,11 +1149,7 @@
          * @return The row index.
          */
         public int getRowIndex() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowIndex();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowIndex();
         }
 
         /**
@@ -1194,11 +1158,7 @@
          * @return The row span.
          */
         public int getRowSpan() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowSpan();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowSpan();
         }
 
         /**
@@ -1211,11 +1171,7 @@
         @SuppressWarnings("deprecation")
         @Deprecated
         public boolean isHeading() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).isHeading();
-            } else {
-                return false;
-            }
+            return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).isHeading();
         }
 
         /**
@@ -1385,11 +1341,11 @@
                 } else if (Build.VERSION.SDK_INT >= 21) {
                     return Api21Impl.createCollectionItemInfo(mRowIndex, mRowSpan, mColumnIndex,
                             mColumnSpan, mHeading, mSelected);
-                } else if (Build.VERSION.SDK_INT >= 19) {
-                    return Api19Impl.createCollectionItemInfo(mRowIndex, mRowSpan, mColumnIndex,
-                            mColumnSpan, mHeading);
                 } else {
-                    return new CollectionItemInfoCompat(null);
+                    return new CollectionItemInfoCompat(
+                            AccessibilityNodeInfo.CollectionItemInfo.obtain(mRowIndex, mRowSpan,
+                                    mColumnIndex,
+                                    mColumnSpan, mHeading));
                 }
             }
         }
@@ -1416,12 +1372,8 @@
          * @return The instance
          */
         public static RangeInfoCompat obtain(int type, float min, float max, float current) {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return new RangeInfoCompat(
-                        AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current));
-            } else {
-                return new RangeInfoCompat(null);
-            }
+            return new RangeInfoCompat(
+                    AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current));
         }
 
         final Object mInfo;
@@ -1443,10 +1395,8 @@
         public RangeInfoCompat(int type, float min, float max, float current) {
             if (Build.VERSION.SDK_INT >= 30) {
                 mInfo = Api30Impl.createRangeInfo(type, min, max, current);
-            } else if (Build.VERSION.SDK_INT >= 19) {
-                mInfo = Api19Impl.createRangeInfo(type, min, max, current);
             } else {
-                mInfo = null;
+                mInfo = AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current);
             }
         }
 
@@ -1456,11 +1406,7 @@
          * @return The current value.
          */
         public float getCurrent() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.RangeInfo) mInfo).getCurrent();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.RangeInfo) mInfo).getCurrent();
         }
 
         /**
@@ -1469,11 +1415,7 @@
          * @return The max value.
          */
         public float getMax() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMax();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMax();
         }
 
         /**
@@ -1482,11 +1424,7 @@
          * @return The min value.
          */
         public float getMin() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMin();
-            } else {
-                return 0;
-            }
+            return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMin();
         }
 
         /**
@@ -1499,11 +1437,7 @@
          * @see #RANGE_TYPE_PERCENT
          */
         public int getType() {
-            if (Build.VERSION.SDK_INT >= 19) {
-                return ((AccessibilityNodeInfo.RangeInfo) mInfo).getType();
-            } else {
-                return RANGE_TYPE_INT;
-            }
+            return ((AccessibilityNodeInfo.RangeInfo) mInfo).getType();
         }
     }
 
@@ -2357,12 +2291,8 @@
      * @see #setSource(View, int)
      */
     public static AccessibilityNodeInfoCompat obtain(View root, int virtualDescendantId) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return AccessibilityNodeInfoCompat.wrapNonNullInstance(
-                    AccessibilityNodeInfo.obtain(root, virtualDescendantId));
-        } else {
-            return null;
-        }
+        return AccessibilityNodeInfoCompat.wrapNonNullInstance(
+                AccessibilityNodeInfo.obtain(root, virtualDescendantId));
     }
 
     /**
@@ -2420,9 +2350,7 @@
         // Store the ID anyway, since we may need it for equality checks.
         mVirtualDescendantId = virtualDescendantId;
 
-        if (Build.VERSION.SDK_INT >= 16) {
-            mInfo.setSource(root, virtualDescendantId);
-        }
+        mInfo.setSource(root, virtualDescendantId);
     }
 
     /**
@@ -2437,11 +2365,7 @@
      * @see #FOCUS_ACCESSIBILITY
      */
     public AccessibilityNodeInfoCompat findFocus(int focus) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.findFocus(focus));
-        } else {
-            return null;
-        }
+        return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.findFocus(focus));
     }
 
     /**
@@ -2459,11 +2383,7 @@
      * @return The node info for the view that can take accessibility focus.
      */
     public AccessibilityNodeInfoCompat focusSearch(int direction) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.focusSearch(direction));
-        } else {
-            return null;
-        }
+        return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.focusSearch(direction));
     }
 
     /**
@@ -2546,9 +2466,7 @@
      * @param virtualDescendantId The id of the virtual child.
      */
     public void addChild(View root, int virtualDescendantId) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            mInfo.addChild(root, virtualDescendantId);
-        }
+        mInfo.addChild(root, virtualDescendantId);
     }
 
     /**
@@ -2623,14 +2541,11 @@
     }
 
     private List<Integer> extrasIntList(String key) {
-        if (Build.VERSION.SDK_INT < 19) {
-            return new ArrayList<Integer>();
-        }
-        ArrayList<Integer> list = Api19Impl.getExtras(mInfo)
+        ArrayList<Integer> list = mInfo.getExtras()
                 .getIntegerArrayList(key);
         if (list == null) {
             list = new ArrayList<Integer>();
-            Api19Impl.getExtras(mInfo).putIntegerArrayList(key, list);
+            mInfo.getExtras().putIntegerArrayList(key, list);
         }
         return list;
     }
@@ -2714,11 +2629,7 @@
      * @throws IllegalStateException If called outside of an AccessibilityService.
      */
     public boolean performAction(int action, Bundle arguments) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return mInfo.performAction(action, arguments);
-        } else {
-            return false;
-        }
+        return mInfo.performAction(action, arguments);
     }
 
     /**
@@ -2734,9 +2645,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setMovementGranularities(int granularities) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            mInfo.setMovementGranularities(granularities);
-        }
+        mInfo.setMovementGranularities(granularities);
     }
 
     /**
@@ -2745,11 +2654,7 @@
      * @return The bit mask with granularities.
      */
     public int getMovementGranularities() {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return mInfo.getMovementGranularities();
-        } else {
-            return 0;
-        }
+        return mInfo.getMovementGranularities();
     }
 
     /**
@@ -2856,9 +2761,7 @@
         // Store the ID anyway, since we may need it for equality checks.
         mParentVirtualDescendantId = virtualDescendantId;
 
-        if (Build.VERSION.SDK_INT >= 16) {
-            mInfo.setParent(root, virtualDescendantId);
-        }
+        mInfo.setParent(root, virtualDescendantId);
     }
 
     /**
@@ -2942,8 +2845,8 @@
     public void getBoundsInWindow(@NonNull  Rect outBounds) {
         if (Build.VERSION.SDK_INT >= 34) {
             Api34Impl.getBoundsInWindow(mInfo, outBounds);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Rect extraBounds = Api19Impl.getExtras(mInfo).getParcelable(BOUNDS_IN_WINDOW_KEY);
+        } else {
+            Rect extraBounds = mInfo.getExtras().getParcelable(BOUNDS_IN_WINDOW_KEY);
             if (extraBounds != null) {
                 outBounds.set(extraBounds.left, extraBounds.top, extraBounds.right,
                         extraBounds.bottom);
@@ -2970,8 +2873,8 @@
     public void setBoundsInWindow(@NonNull Rect bounds) {
         if (Build.VERSION.SDK_INT >= 34) {
             Api34Impl.setBoundsInWindow(mInfo, bounds);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putParcelable(BOUNDS_IN_WINDOW_KEY, bounds);
+        } else {
+            mInfo.getExtras().putParcelable(BOUNDS_IN_WINDOW_KEY, bounds);
         }
     }
 
@@ -3077,11 +2980,7 @@
      * @return Whether the node is visible to the user.
      */
     public boolean isVisibleToUser() {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return mInfo.isVisibleToUser();
-        } else {
-            return false;
-        }
+        return mInfo.isVisibleToUser();
     }
 
     /**
@@ -3097,9 +2996,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setVisibleToUser(boolean visibleToUser) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            mInfo.setVisibleToUser(visibleToUser);
-        }
+        mInfo.setVisibleToUser(visibleToUser);
     }
 
     /**
@@ -3108,11 +3005,7 @@
      * @return True if the node is accessibility focused.
      */
     public boolean isAccessibilityFocused() {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return mInfo.isAccessibilityFocused();
-        } else {
-            return false;
-        }
+        return mInfo.isAccessibilityFocused();
     }
 
     /**
@@ -3128,9 +3021,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setAccessibilityFocused(boolean focused) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            mInfo.setAccessibilityFocused(focused);
-        }
+        mInfo.setAccessibilityFocused(focused);
     }
 
     /**
@@ -3372,10 +3263,9 @@
     public long getMinDurationBetweenContentChangesMillis() {
         if (Build.VERSION.SDK_INT >= 34) {
             return Api34Impl.getMinDurationBetweenContentChangeMillis(mInfo);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY);
+        } else {
+            return mInfo.getExtras().getLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY);
         }
-        return 0;
     }
 
     /**
@@ -3395,8 +3285,8 @@
     public void setMinDurationBetweenContentChangesMillis(long duration) {
         if (Build.VERSION.SDK_INT >= 34) {
             Api34Impl.setMinDurationBetweenContentChangeMillis(mInfo, duration);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY, duration);
+        } else {
+            mInfo.getExtras().putLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY, duration);
         }
     }
 
@@ -3570,7 +3460,7 @@
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
     public void addSpansToExtras(CharSequence text, View view) {
-        if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 26) {
+        if (Build.VERSION.SDK_INT < 26) {
             clearExtrasSpans();
             removeCollectedSpans(view);
             ClickableSpan[] spans = getClickableSpans(text);
@@ -3631,12 +3521,10 @@
     }
 
     private void clearExtrasSpans() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).remove(SPANS_START_KEY);
-            Api19Impl.getExtras(mInfo).remove(SPANS_END_KEY);
-            Api19Impl.getExtras(mInfo).remove(SPANS_FLAGS_KEY);
-            Api19Impl.getExtras(mInfo).remove(SPANS_ID_KEY);
-        }
+        mInfo.getExtras().remove(SPANS_START_KEY);
+        mInfo.getExtras().remove(SPANS_END_KEY);
+        mInfo.getExtras().remove(SPANS_FLAGS_KEY);
+        mInfo.getExtras().remove(SPANS_ID_KEY);
     }
 
     private void addSpanLocationToExtras(ClickableSpan span, Spanned spanned, int id) {
@@ -3678,11 +3566,10 @@
      */
     public @Nullable CharSequence getStateDescription() {
         if (Build.VERSION.SDK_INT >= 30) {
-            return  Api30Impl.getStateDescription(mInfo);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getCharSequence(STATE_DESCRIPTION_KEY);
+            return Api30Impl.getStateDescription(mInfo);
+        } else {
+            return mInfo.getExtras().getCharSequence(STATE_DESCRIPTION_KEY);
         }
-        return null;
     }
 
     /**
@@ -3714,8 +3601,8 @@
     public void setStateDescription(@Nullable CharSequence stateDescription) {
         if (Build.VERSION.SDK_INT >= 30) {
             Api30Impl.setStateDescription(mInfo, stateDescription);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putCharSequence(STATE_DESCRIPTION_KEY, stateDescription);
+        } else {
+            mInfo.getExtras().putCharSequence(STATE_DESCRIPTION_KEY, stateDescription);
         }
     }
 
@@ -3728,10 +3615,9 @@
     public @Nullable String getUniqueId() {
         if (Build.VERSION.SDK_INT >= 33) {
             return Api33Impl.getUniqueId(mInfo);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getString(UNIQUE_ID_KEY);
+        } else {
+            return mInfo.getExtras().getString(UNIQUE_ID_KEY);
         }
-        return null;
     }
 
     /**
@@ -3748,8 +3634,8 @@
     public void setUniqueId(@Nullable String uniqueId) {
         if (Build.VERSION.SDK_INT >= 33) {
             Api33Impl.setUniqueId(mInfo, uniqueId);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putString(UNIQUE_ID_KEY, uniqueId);
+        } else {
+            mInfo.getExtras().putString(UNIQUE_ID_KEY, uniqueId);
         }
     }
 
@@ -3785,8 +3671,8 @@
     public void setContainerTitle(@Nullable CharSequence containerTitle) {
         if (Build.VERSION.SDK_INT >= 34) {
             Api34Impl.setContainerTitle(mInfo, containerTitle);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putCharSequence(CONTAINER_TITLE_KEY, containerTitle);
+        } else {
+            mInfo.getExtras().putCharSequence(CONTAINER_TITLE_KEY, containerTitle);
         }
     }
 
@@ -3803,10 +3689,9 @@
     public CharSequence getContainerTitle() {
         if (Build.VERSION.SDK_INT >= 34) {
             return Api34Impl.getContainerTitle(mInfo);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getCharSequence(CONTAINER_TITLE_KEY);
+        } else {
+            return mInfo.getExtras().getCharSequence(CONTAINER_TITLE_KEY);
         }
-        return null;
     }
 
     /**
@@ -3832,9 +3717,7 @@
      * @param viewId The id resource name.
      */
     public void setViewIdResourceName(String viewId) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            mInfo.setViewIdResourceName(viewId);
-        }
+        mInfo.setViewIdResourceName(viewId);
     }
 
     /**
@@ -3850,11 +3733,7 @@
      * @return The id resource name.
      */
     public String getViewIdResourceName() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return mInfo.getViewIdResourceName();
-        } else {
-            return null;
-        }
+        return mInfo.getViewIdResourceName();
     }
 
     /**
@@ -3876,11 +3755,7 @@
      * @see ViewCompat#getAccessibilityLiveRegion(View)
      */
     public int getLiveRegion() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.getLiveRegion();
-        } else {
-            return ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE;
-        }
+        return mInfo.getLiveRegion();
     }
 
     /**
@@ -3896,9 +3771,7 @@
      * @see ViewCompat#setAccessibilityLiveRegion(View, int)
      */
     public void setLiveRegion(int mode) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setLiveRegion(mode);
-        }
+        mInfo.setLiveRegion(mode);
     }
 
     /**
@@ -3944,30 +3817,24 @@
      * @return The collection info.
      */
     public CollectionInfoCompat getCollectionInfo() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            AccessibilityNodeInfo.CollectionInfo info = mInfo.getCollectionInfo();
-            if (info != null) {
-                return new CollectionInfoCompat(info);
-            }
+        AccessibilityNodeInfo.CollectionInfo info = mInfo.getCollectionInfo();
+        if (info != null) {
+            return new CollectionInfoCompat(info);
         }
         return null;
     }
 
     public void setCollectionInfo(Object collectionInfo) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setCollectionInfo((collectionInfo == null) ? null
-                    : (AccessibilityNodeInfo.CollectionInfo) ((CollectionInfoCompat)
-                            collectionInfo).mInfo);
-        }
+        mInfo.setCollectionInfo((collectionInfo == null) ? null
+                : (AccessibilityNodeInfo.CollectionInfo) ((CollectionInfoCompat)
+                        collectionInfo).mInfo);
 
     }
 
     public void setCollectionItemInfo(Object collectionItemInfo) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setCollectionItemInfo((collectionItemInfo == null) ? null
-                    : (AccessibilityNodeInfo.CollectionItemInfo) ((CollectionItemInfoCompat)
-                            collectionItemInfo).mInfo);
-        }
+        mInfo.setCollectionItemInfo((collectionItemInfo == null) ? null
+                : (AccessibilityNodeInfo.CollectionItemInfo) ((CollectionItemInfoCompat)
+                        collectionItemInfo).mInfo);
     }
 
     /**
@@ -3977,11 +3844,9 @@
      * @return The collection item info.
      */
     public CollectionItemInfoCompat getCollectionItemInfo() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            AccessibilityNodeInfo.CollectionItemInfo info = mInfo.getCollectionItemInfo();
-            if (info != null) {
-                return new CollectionItemInfoCompat(info);
-            }
+        AccessibilityNodeInfo.CollectionItemInfo info = mInfo.getCollectionItemInfo();
+        if (info != null) {
+            return new CollectionItemInfoCompat(info);
         }
         return null;
     }
@@ -3992,11 +3857,9 @@
      * @return The range.
      */
     public RangeInfoCompat getRangeInfo() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            AccessibilityNodeInfo.RangeInfo info = mInfo.getRangeInfo();
-            if (info != null) {
-                return new RangeInfoCompat(info);
-            }
+        AccessibilityNodeInfo.RangeInfo info = mInfo.getRangeInfo();
+        if (info != null) {
+            return new RangeInfoCompat(info);
         }
         return null;
     }
@@ -4012,9 +3875,7 @@
      * @param rangeInfo The range info.
      */
     public void setRangeInfo(RangeInfoCompat rangeInfo) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setRangeInfo((AccessibilityNodeInfo.RangeInfo) rangeInfo.mInfo);
-        }
+        mInfo.setRangeInfo((AccessibilityNodeInfo.RangeInfo) rangeInfo.mInfo);
     }
 
     /**
@@ -4075,9 +3936,7 @@
      * @param contentInvalid If the node content is invalid.
      */
     public void setContentInvalid(boolean contentInvalid) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setContentInvalid(contentInvalid);
-        }
+        mInfo.setContentInvalid(contentInvalid);
     }
 
     /**
@@ -4087,11 +3946,7 @@
      * @return If the node content is invalid.
      */
     public boolean isContentInvalid() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.isContentInvalid();
-        } else {
-            return false;
-        }
+        return mInfo.isContentInvalid();
     }
 
     /**
@@ -4132,10 +3987,9 @@
     public @Nullable CharSequence getHintText() {
         if (Build.VERSION.SDK_INT >= 26) {
             return mInfo.getHintText();
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getCharSequence(HINT_TEXT_KEY);
+        } else {
+            return mInfo.getExtras().getCharSequence(HINT_TEXT_KEY);
         }
-        return null;
     }
 
     /**
@@ -4154,8 +4008,8 @@
     public void setHintText(@Nullable CharSequence hintText) {
         if (Build.VERSION.SDK_INT >= 26) {
             mInfo.setHintText(hintText);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putCharSequence(HINT_TEXT_KEY, hintText);
+        } else {
+            mInfo.getExtras().putCharSequence(HINT_TEXT_KEY, hintText);
         }
     }
 
@@ -4198,9 +4052,7 @@
      * @param labeled The view for which this info serves as a label.
      */
     public void setLabelFor(View labeled) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            mInfo.setLabelFor(labeled);
-        }
+        mInfo.setLabelFor(labeled);
     }
 
     /**
@@ -4218,9 +4070,7 @@
      * @param virtualDescendantId The id of the virtual descendant.
      */
     public void setLabelFor(View root, int virtualDescendantId) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            mInfo.setLabelFor(root, virtualDescendantId);
-        }
+        mInfo.setLabelFor(root, virtualDescendantId);
     }
 
     /**
@@ -4230,11 +4080,7 @@
      * @return The labeled info.
      */
     public AccessibilityNodeInfoCompat getLabelFor() {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabelFor());
-        } else {
-            return null;
-        }
+        return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabelFor());
     }
 
     /**
@@ -4244,9 +4090,7 @@
      * @param label The view that labels this node's source.
      */
     public void setLabeledBy(View label) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            mInfo.setLabeledBy(label);
-        }
+        mInfo.setLabeledBy(label);
     }
 
     /**
@@ -4269,9 +4113,7 @@
      * @param virtualDescendantId The id of the virtual descendant.
      */
     public void setLabeledBy(View root, int virtualDescendantId) {
-        if (Build.VERSION.SDK_INT >= 17) {
-            mInfo.setLabeledBy(root, virtualDescendantId);
-        }
+        mInfo.setLabeledBy(root, virtualDescendantId);
     }
 
     /**
@@ -4281,11 +4123,7 @@
      * @return The label.
      */
     public AccessibilityNodeInfoCompat getLabeledBy() {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabeledBy());
-        } else {
-            return null;
-        }
+        return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabeledBy());
     }
 
     /**
@@ -4294,11 +4132,7 @@
      * @return If the the node opens a popup.
      */
     public boolean canOpenPopup() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.canOpenPopup();
-        } else {
-            return false;
-        }
+        return mInfo.canOpenPopup();
     }
 
     /**
@@ -4312,9 +4146,7 @@
      * @param opensPopup If the the node opens a popup.
      */
     public void setCanOpenPopup(boolean opensPopup) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setCanOpenPopup(opensPopup);
-        }
+        mInfo.setCanOpenPopup(opensPopup);
     }
 
     /**
@@ -4362,11 +4194,7 @@
      * @return The bundle.
      */
     public Bundle getExtras() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo);
-        } else {
-            return new Bundle();
-        }
+        return mInfo.getExtras();
     }
 
     /**
@@ -4375,11 +4203,7 @@
      * @return The input type.
      */
     public int getInputType() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.getInputType();
-        } else {
-            return InputType.TYPE_NULL;
-        }
+        return mInfo.getInputType();
     }
 
     /**
@@ -4396,9 +4220,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setInputType(int inputType) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setInputType(inputType);
-        }
+        mInfo.setInputType(inputType);
     }
 
     /**
@@ -4492,9 +4314,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setTextSelection(int start, int end) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            mInfo.setTextSelection(start, end);
-        }
+        mInfo.setTextSelection(start, end);
     }
 
     /**
@@ -4503,11 +4323,7 @@
      * @return The text selection start if there is selection or -1.
      */
     public int getTextSelectionStart() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return mInfo.getTextSelectionStart();
-        } else {
-            return -1;
-        }
+        return mInfo.getTextSelectionStart();
     }
 
     /**
@@ -4516,11 +4332,7 @@
      * @return The text selection end if there is selection or -1.
      */
     public int getTextSelectionEnd() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return mInfo.getTextSelectionEnd();
-        } else {
-            return -1;
-        }
+        return mInfo.getTextSelectionEnd();
     }
 
     /**
@@ -4672,11 +4484,7 @@
      * @return If the node can be dismissed.
      */
     public boolean isDismissable() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.isDismissable();
-        } else {
-            return false;
-        }
+        return mInfo.isDismissable();
     }
 
     /**
@@ -4690,9 +4498,7 @@
      * @param dismissable If the node can be dismissed.
      */
     public void setDismissable(boolean dismissable) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setDismissable(dismissable);
-        }
+        mInfo.setDismissable(dismissable);
     }
 
     /**
@@ -4701,11 +4507,7 @@
      * @return True if the node is editable, false otherwise.
      */
     public boolean isEditable() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return mInfo.isEditable();
-        } else {
-            return false;
-        }
+        return mInfo.isEditable();
     }
 
     /**
@@ -4721,9 +4523,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setEditable(boolean editable) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            mInfo.setEditable(editable);
-        }
+        mInfo.setEditable(editable);
     }
 
     /**
@@ -4732,11 +4532,7 @@
      * @return True if the node is multi line.
      */
     public boolean isMultiLine() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.isMultiLine();
-        } else {
-            return false;
-        }
+        return mInfo.isMultiLine();
     }
 
     /**
@@ -4750,9 +4546,7 @@
      * @param multiLine True if the node is multi line.
      */
     public void setMultiLine(boolean multiLine) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.setMultiLine(multiLine);
-        }
+        mInfo.setMultiLine(multiLine);
     }
 
     /**
@@ -4764,10 +4558,9 @@
     public CharSequence getTooltipText() {
         if (Build.VERSION.SDK_INT >= 28) {
             return mInfo.getTooltipText();
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getCharSequence(TOOLTIP_TEXT_KEY);
+        } else {
+            return mInfo.getExtras().getCharSequence(TOOLTIP_TEXT_KEY);
         }
-        return null;
     }
 
     /**
@@ -4786,8 +4579,8 @@
     public void setTooltipText(@Nullable CharSequence tooltipText) {
         if (Build.VERSION.SDK_INT >= 28) {
             mInfo.setTooltipText(tooltipText);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putCharSequence(TOOLTIP_TEXT_KEY, tooltipText);
+        } else {
+            mInfo.getExtras().putCharSequence(TOOLTIP_TEXT_KEY, tooltipText);
         }
     }
 
@@ -4806,8 +4599,8 @@
     public void setPaneTitle(@Nullable CharSequence paneTitle) {
         if (Build.VERSION.SDK_INT >= 28) {
             mInfo.setPaneTitle(paneTitle);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putCharSequence(PANE_TITLE_KEY, paneTitle);
+        } else {
+            mInfo.getExtras().putCharSequence(PANE_TITLE_KEY, paneTitle);
         }
     }
 
@@ -4820,10 +4613,9 @@
     public @Nullable CharSequence getPaneTitle() {
         if (Build.VERSION.SDK_INT >= 28) {
             return mInfo.getPaneTitle();
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getCharSequence(PANE_TITLE_KEY);
+        } else {
+            return mInfo.getExtras().getCharSequence(PANE_TITLE_KEY);
         }
-        return null;
     }
 
     /**
@@ -5017,11 +4809,7 @@
      * @return Whether the refresh succeeded.
      */
     public boolean refresh() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return mInfo.refresh();
-        } else {
-            return false;
-        }
+        return mInfo.refresh();
     }
 
     /**
@@ -5029,11 +4817,7 @@
      * @return The role description.
      */
     public @Nullable CharSequence getRoleDescription() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getExtras(mInfo).getCharSequence(ROLE_DESCRIPTION_KEY);
-        } else {
-            return null;
-        }
+        return mInfo.getExtras().getCharSequence(ROLE_DESCRIPTION_KEY);
     }
 
     /**
@@ -5061,9 +4845,7 @@
      * @param roleDescription The role description.
      */
     public void setRoleDescription(@Nullable CharSequence roleDescription) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.getExtras(mInfo).putCharSequence(ROLE_DESCRIPTION_KEY, roleDescription);
-        }
+        mInfo.getExtras().putCharSequence(ROLE_DESCRIPTION_KEY, roleDescription);
     }
 
     /**
@@ -5384,31 +5166,6 @@
         }
     }
 
-    @RequiresApi(19)
-    private static class Api19Impl {
-        private Api19Impl() {
-            // This class is non instantiable.
-        }
-
-        @DoNotInline
-        public static Bundle getExtras(AccessibilityNodeInfo info) {
-            return info.getExtras();
-        }
-
-        @DoNotInline
-        public static Object createRangeInfo(int type, float min, float max, float current) {
-            return AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current);
-        }
-
-        @DoNotInline
-        public static CollectionItemInfoCompat createCollectionItemInfo(int rowIndex, int rowSpan,
-                int columnIndex, int columnSpan, boolean heading) {
-            return new CollectionItemInfoCompat(
-                    AccessibilityNodeInfo.CollectionItemInfo.obtain(rowIndex, rowSpan, columnIndex,
-                            columnSpan, heading));
-        }
-    }
-
     @RequiresApi(21)
     private static class Api21Impl {
         private Api21Impl() {
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeProviderCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeProviderCompat.java
index 6b12814..77eba4d 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeProviderCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeProviderCompat.java
@@ -125,12 +125,8 @@
     public AccessibilityNodeProviderCompat() {
         if (Build.VERSION.SDK_INT >= 26) {
             mProvider = new AccessibilityNodeProviderApi26(this);
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            mProvider = new AccessibilityNodeProviderApi19(this);
-        } else if (Build.VERSION.SDK_INT >= 16) {
-            mProvider = new AccessibilityNodeProviderApi16(this);
         } else {
-            mProvider = null;
+            mProvider = new AccessibilityNodeProviderApi19(this);
         }
     }
 
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityRecordCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityRecordCompat.java
index efe18e68..4cdb3ea 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityRecordCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityRecordCompat.java
@@ -17,17 +17,14 @@
 package androidx.core.view.accessibility;
 
 import android.annotation.SuppressLint;
-import android.os.Build;
 import android.os.Parcelable;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityRecord;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 import java.util.List;
 
@@ -142,9 +139,7 @@
      */
     public static void setSource(@NonNull AccessibilityRecord record, @Nullable View root,
             int virtualDescendantId) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            Api16Impl.setSource(record, root, virtualDescendantId);
-        }
+        record.setSource(root, virtualDescendantId);
     }
 
     /**
@@ -486,11 +481,7 @@
      * @return The max scroll.
      */
     public static int getMaxScrollX(@NonNull AccessibilityRecord record) {
-        if (Build.VERSION.SDK_INT >= 15) {
-            return Api15Impl.getMaxScrollX(record);
-        } else {
-            return 0;
-        }
+        return record.getMaxScrollX();
     }
 
     /**
@@ -512,9 +503,7 @@
      * @param maxScrollX The max scroll.
      */
     public static void setMaxScrollX(@NonNull AccessibilityRecord record, int maxScrollX) {
-        if (Build.VERSION.SDK_INT >= 15) {
-            Api15Impl.setMaxScrollX(record, maxScrollX);
-        }
+        record.setMaxScrollX(maxScrollX);
     }
 
     /**
@@ -536,11 +525,7 @@
      * @return The max scroll.
      */
     public static int getMaxScrollY(@NonNull AccessibilityRecord record) {
-        if (Build.VERSION.SDK_INT >= 15) {
-            return Api15Impl.getMaxScrollY(record);
-        } else {
-            return 0;
-        }
+        return record.getMaxScrollY();
     }
 
     /**
@@ -562,9 +547,7 @@
      * @param maxScrollY The max scroll.
      */
     public static void setMaxScrollY(@NonNull AccessibilityRecord record, int maxScrollY) {
-        if (Build.VERSION.SDK_INT >= 15) {
-            Api15Impl.setMaxScrollY(record, maxScrollY);
-        }
+        record.setMaxScrollY(maxScrollY);
     }
 
     /**
@@ -779,45 +762,4 @@
         }
         return mRecord.equals(other.mRecord);
     }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setSource(AccessibilityRecord accessibilityRecord, View root,
-                int virtualDescendantId) {
-            accessibilityRecord.setSource(root, virtualDescendantId);
-        }
-
-    }
-
-    @RequiresApi(15)
-    static class Api15Impl {
-        private Api15Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getMaxScrollX(AccessibilityRecord accessibilityRecord) {
-            return accessibilityRecord.getMaxScrollX();
-        }
-
-        @DoNotInline
-        static void setMaxScrollX(AccessibilityRecord accessibilityRecord, int maxScrollX) {
-            accessibilityRecord.setMaxScrollX(maxScrollX);
-        }
-
-        @DoNotInline
-        static int getMaxScrollY(AccessibilityRecord accessibilityRecord) {
-            return accessibilityRecord.getMaxScrollY();
-        }
-
-        @DoNotInline
-        static void setMaxScrollY(AccessibilityRecord accessibilityRecord, int maxScrollY) {
-            accessibilityRecord.setMaxScrollY(maxScrollY);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/inputmethod/EditorInfoCompat.java b/core/core/src/main/java/androidx/core/view/inputmethod/EditorInfoCompat.java
index 5f89ffe..7ef503a 100644
--- a/core/core/src/main/java/androidx/core/view/inputmethod/EditorInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/inputmethod/EditorInfoCompat.java
@@ -34,6 +34,7 @@
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
@@ -103,6 +104,8 @@
     private static final String CONTENT_SELECTION_END_KEY =
             "androidx.core.view.inputmethod.EditorInfoCompat.CONTENT_SELECTION_END";
 
+    private static final String STYLUS_HANDWRITING_ENABLED_KEY =
+            "androidx.core.view.inputmethod.EditorInfoCompat.STYLUS_HANDWRITING_ENABLED";
 
     @Retention(SOURCE)
     @IntDef({Protocol.Unknown, Protocol.PlatformApi, Protocol.SupportLib, Protocol.AndroidX_1_0_0,
@@ -196,6 +199,37 @@
     }
 
     /**
+     * Set {@code true} if the editor has {@link InputMethodManager#startStylusHandwriting stylus
+     * handwriting} enabled.
+     * {@code false} by default, editor must set it {@code true} to indicate that it supports
+     * stylus handwriting.
+     * @param editorInfo the editor with which we set handwriting enabled.
+     * @param enabled {@code true} if stylus handwriting is enabled.
+     * @see View#setAutoHandwritingEnabled(boolean)
+     */
+    public static void setStylusHandwritingEnabled(@NonNull EditorInfo editorInfo,
+            boolean enabled) {
+        if (editorInfo.extras == null) {
+            editorInfo.extras = new Bundle();
+        }
+        editorInfo.extras.putBoolean(STYLUS_HANDWRITING_ENABLED_KEY, enabled);
+    }
+
+    /**
+     * Returns {@code true} when an editor has stylus handwriting enabled. {@code false} by default.
+     * @param editorInfo the editor from which we get stylus handwriting enabled.
+     * @see #setStylusHandwritingEnabled(EditorInfo, boolean)
+     * @see InputMethodManager#isStylusHandwritingAvailable()
+     */
+    public static boolean isStylusHandwritingEnabled(@NonNull EditorInfo editorInfo) {
+        if (editorInfo.extras == null) {
+            // disabled by default
+            return false;
+        }
+        return editorInfo.extras.getBoolean(STYLUS_HANDWRITING_ENABLED_KEY);
+    }
+
+    /**
      * Editors may use this method to provide initial input text to IMEs. As the surrounding text
      * could be used to provide various input assistance, we recommend editors to provide the
      * complete initial input text in its {@link View#onCreateInputConnection(EditorInfo)} callback.
diff --git a/core/core/src/main/java/androidx/core/widget/CheckedTextViewCompat.java b/core/core/src/main/java/androidx/core/widget/CheckedTextViewCompat.java
index 1e9ab56..35078e0 100644
--- a/core/core/src/main/java/androidx/core/widget/CheckedTextViewCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/CheckedTextViewCompat.java
@@ -21,7 +21,6 @@
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.widget.CheckedTextView;
 
 import androidx.annotation.NonNull;
@@ -29,13 +28,10 @@
 import androidx.annotation.RequiresApi;
 import androidx.core.graphics.drawable.DrawableCompat;
 
-import java.lang.reflect.Field;
-
 /**
  * Helper for accessing {@link CheckedTextView}.
  */
 public final class CheckedTextViewCompat {
-    private static final String TAG = "CheckedTextViewCompat";
 
     private CheckedTextViewCompat() {
     }
@@ -120,11 +116,7 @@
      */
     @Nullable
     public static Drawable getCheckMarkDrawable(@NonNull CheckedTextView textView) {
-        if (SDK_INT >= 16) {
-            return Api16Impl.getCheckMarkDrawable(textView);
-        } else {
-            return Api14Impl.getCheckMarkDrawable(textView);
-        }
+        return textView.getCheckMarkDrawable();
     }
 
     @RequiresApi(21)
@@ -153,49 +145,4 @@
             return textView.getCheckMarkTintMode();
         }
     }
-
-    @RequiresApi(16)
-    private static class Api16Impl {
-
-        private Api16Impl() {
-        }
-
-        @Nullable
-        static Drawable getCheckMarkDrawable(@NonNull CheckedTextView textView) {
-            return textView.getCheckMarkDrawable();
-        }
-    }
-
-    private static class Api14Impl {
-
-        private static Field sCheckMarkDrawableField;
-        private static boolean sResolved;
-
-        private Api14Impl() {
-        }
-
-        @Nullable
-        static Drawable getCheckMarkDrawable(@NonNull CheckedTextView textView) {
-            if (!sResolved) {
-                try {
-                    sCheckMarkDrawableField =
-                            CheckedTextView.class.getDeclaredField("mCheckMarkDrawable");
-                    sCheckMarkDrawableField.setAccessible(true);
-                } catch (NoSuchFieldException e) {
-                    Log.i(TAG, "Failed to retrieve mCheckMarkDrawable field", e);
-                }
-                sResolved = true;
-            }
-
-            if (sCheckMarkDrawableField != null) {
-                try {
-                    return (Drawable) sCheckMarkDrawableField.get(textView);
-                } catch (IllegalAccessException e) {
-                    Log.i(TAG, "Failed to get check mark drawable via reflection", e);
-                    sCheckMarkDrawableField = null;
-                }
-            }
-            return null;
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/widget/ListPopupWindowCompat.java b/core/core/src/main/java/androidx/core/widget/ListPopupWindowCompat.java
index 1c49b95..4b8c16c 100644
--- a/core/core/src/main/java/androidx/core/widget/ListPopupWindowCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/ListPopupWindowCompat.java
@@ -21,10 +21,8 @@
 import android.view.View.OnTouchListener;
 import android.widget.ListPopupWindow;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 /**
  * Helper for accessing features in {@link ListPopupWindow}.
@@ -96,22 +94,6 @@
     @Nullable
     public static OnTouchListener createDragToOpenListener(
             @NonNull ListPopupWindow listPopupWindow, @NonNull View src) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.createDragToOpenListener(listPopupWindow, src);
-        } else {
-            return null;
-        }
-    }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static OnTouchListener createDragToOpenListener(ListPopupWindow listPopupWindow, View src) {
-            return listPopupWindow.createDragToOpenListener(src);
-        }
+        return listPopupWindow.createDragToOpenListener(src);
     }
 }
diff --git a/core/core/src/main/java/androidx/core/widget/PopupMenuCompat.java b/core/core/src/main/java/androidx/core/widget/PopupMenuCompat.java
index 67c3263..01a7071 100644
--- a/core/core/src/main/java/androidx/core/widget/PopupMenuCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/PopupMenuCompat.java
@@ -20,10 +20,8 @@
 import android.view.View.OnTouchListener;
 import android.widget.PopupMenu;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 /**
  * Helper for accessing features in {@link PopupMenu}.
@@ -54,22 +52,6 @@
      */
     @Nullable
     public static OnTouchListener getDragToOpenListener(@NonNull Object popupMenu) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Api19Impl.getDragToOpenListener((PopupMenu) popupMenu);
-        } else {
-            return null;
-        }
-    }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static OnTouchListener getDragToOpenListener(PopupMenu popupMenu) {
-            return popupMenu.getDragToOpenListener();
-        }
+        return ((PopupMenu) popupMenu).getDragToOpenListener();
     }
 }
diff --git a/core/core/src/main/java/androidx/core/widget/PopupWindowCompat.java b/core/core/src/main/java/androidx/core/widget/PopupWindowCompat.java
index 415bedd..b87351b 100644
--- a/core/core/src/main/java/androidx/core/widget/PopupWindowCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/PopupWindowCompat.java
@@ -18,15 +18,12 @@
 
 import android.os.Build;
 import android.util.Log;
-import android.view.Gravity;
 import android.view.View;
 import android.widget.PopupWindow;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
-import androidx.core.view.GravityCompat;
-import androidx.core.view.ViewCompat;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -67,19 +64,7 @@
      */
     public static void showAsDropDown(@NonNull PopupWindow popup, @NonNull View anchor,
             int xoff, int yoff, int gravity) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.showAsDropDown(popup, anchor, xoff, yoff, gravity);
-        } else {
-            int xoff1 = xoff;
-            final int hgrav = GravityCompat.getAbsoluteGravity(gravity,
-                    ViewCompat.getLayoutDirection(anchor)) & Gravity.HORIZONTAL_GRAVITY_MASK;
-            if (hgrav == Gravity.RIGHT) {
-                // Flip the location to align the right sides of the popup and
-                // anchor instead of left.
-                xoff1 -= (popup.getWidth() - anchor.getWidth());
-            }
-            popup.showAsDropDown(anchor, xoff1, yoff);
-        }
+        popup.showAsDropDown(anchor, xoff, yoff, gravity);
     }
 
     /**
@@ -236,17 +221,4 @@
             return popupWindow.getWindowLayoutType();
         }
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void showAsDropDown(PopupWindow popupWindow, View anchor, int xoff, int yoff,
-                int gravity) {
-            popupWindow.showAsDropDown(anchor, xoff, yoff, gravity);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/widget/TextViewCompat.java b/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
index 9c5cabf..df34fd0 100644
--- a/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
@@ -43,7 +43,6 @@
 import android.text.TextDirectionHeuristics;
 import android.text.TextPaint;
 import android.text.method.PasswordTransformationMethod;
-import android.util.Log;
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.Menu;
@@ -68,7 +67,6 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -80,8 +78,6 @@
  * Helper for accessing features in {@link TextView}.
  */
 public final class TextViewCompat {
-    private static final String LOG_TAG = "TextViewCompat";
-
     /**
      * The TextView does not auto-size text (default).
      */
@@ -98,41 +94,9 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface AutoSizeTextType {}
 
-    private static Field sMaximumField;
-    private static boolean sMaximumFieldFetched;
-    private static Field sMaxModeField;
-    private static boolean sMaxModeFieldFetched;
-
-    private static Field sMinimumField;
-    private static boolean sMinimumFieldFetched;
-    private static Field sMinModeField;
-    private static boolean sMinModeFieldFetched;
-
-    private static final int LINES = 1;
-
     // Hide constructor
     private TextViewCompat() {}
 
-    private static Field retrieveField(String fieldName) {
-        Field field = null;
-        try {
-            field = TextView.class.getDeclaredField(fieldName);
-            field.setAccessible(true);
-        } catch (NoSuchFieldException e) {
-            Log.e(LOG_TAG, "Could not retrieve " + fieldName + " field.");
-        }
-        return field;
-    }
-
-    private static int retrieveIntFromField(Field field, TextView textView) {
-        try {
-            return field.getInt(textView);
-        } catch (IllegalAccessException e) {
-            Log.d(LOG_TAG, "Could not retrieve value of " + field.getName() + " field.");
-        }
-        return -1;
-    }
-
     /**
      * Sets the Drawables (if any) to appear to the start of, above, to the end
      * of, and below the text. Use {@code null} if you do not want a Drawable
@@ -156,14 +120,7 @@
     public static void setCompoundDrawablesRelative(@NonNull TextView textView,
             @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
             @Nullable Drawable bottom) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api17Impl.setCompoundDrawablesRelative(textView, start, top, end, bottom);
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            boolean rtl = Api17Impl.getLayoutDirection(textView) == View.LAYOUT_DIRECTION_RTL;
-            textView.setCompoundDrawables(rtl ? end : start, top, rtl ? start : end, bottom);
-        } else {
-            textView.setCompoundDrawables(start, top, end, bottom);
-        }
+        textView.setCompoundDrawablesRelative(start, top, end, bottom);
     }
 
     /**
@@ -188,16 +145,7 @@
     public static void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
             @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
             @Nullable Drawable bottom) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api17Impl.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end,
-                    bottom);
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            boolean rtl = Api17Impl.getLayoutDirection(textView) == View.LAYOUT_DIRECTION_RTL;
-            textView.setCompoundDrawablesWithIntrinsicBounds(rtl ? end : start, top,
-                    rtl ? start : end,  bottom);
-        } else {
-            textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
-        }
+        textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
     }
 
     /**
@@ -221,16 +169,7 @@
     public static void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
             @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
             @DrawableRes int bottom) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            Api17Impl.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end,
-                    bottom);
-        } else if (Build.VERSION.SDK_INT >= 17) {
-            boolean rtl = Api17Impl.getLayoutDirection(textView) == View.LAYOUT_DIRECTION_RTL;
-            textView.setCompoundDrawablesWithIntrinsicBounds(rtl ? end : start, top,
-                    rtl ? start : end, bottom);
-        } else {
-            textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
-        }
+        textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
     }
 
     /**
@@ -238,25 +177,7 @@
      * height was set in pixels instead.
      */
     public static int getMaxLines(@NonNull TextView textView) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getMaxLines(textView);
-        }
-
-        if (!sMaxModeFieldFetched) {
-            sMaxModeField = retrieveField("mMaxMode");
-            sMaxModeFieldFetched = true;
-        }
-        if (sMaxModeField != null && retrieveIntFromField(sMaxModeField, textView) == LINES) {
-            // If the max mode is using lines, we can grab the maximum value
-            if (!sMaximumFieldFetched) {
-                sMaximumField = retrieveField("mMaximum");
-                sMaximumFieldFetched = true;
-            }
-            if (sMaximumField != null) {
-                return retrieveIntFromField(sMaximumField, textView);
-            }
-        }
-        return -1;
+        return textView.getMaxLines();
     }
 
     /**
@@ -264,25 +185,7 @@
      * height was set in pixels instead.
      */
     public static int getMinLines(@NonNull TextView textView) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.getMinLines(textView);
-        }
-
-        if (!sMinModeFieldFetched) {
-            sMinModeField = retrieveField("mMinMode");
-            sMinModeFieldFetched = true;
-        }
-        if (sMinModeField != null && retrieveIntFromField(sMinModeField, textView) == LINES) {
-            // If the min mode is using lines, we can grab the maximum value
-            if (!sMinimumFieldFetched) {
-                sMinimumField = retrieveField("mMinimum");
-                sMinimumFieldFetched = true;
-            }
-            if (sMinimumField != null) {
-                return retrieveIntFromField(sMinimumField, textView);
-            }
-        }
-        return -1;
+        return textView.getMinLines();
     }
 
     /**
@@ -307,22 +210,7 @@
      */
     @NonNull
     public static Drawable[] getCompoundDrawablesRelative(@NonNull TextView textView) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return Api17Impl.getCompoundDrawablesRelative(textView);
-        }
-        if (Build.VERSION.SDK_INT >= 17) {
-            final boolean rtl = Api17Impl.getLayoutDirection(textView) == View.LAYOUT_DIRECTION_RTL;
-            final Drawable[] compounds = textView.getCompoundDrawables();
-            if (rtl) {
-                // If we're on RTL, we need to invert the horizontal result like above
-                final Drawable start = compounds[2];
-                final Drawable end = compounds[0];
-                compounds[0] = start;
-                compounds[2] = end;
-            }
-            return compounds;
-        }
-        return textView.getCompoundDrawables();
+        return textView.getCompoundDrawablesRelative();
     }
 
     /**
@@ -736,10 +624,7 @@
 
         final Paint.FontMetricsInt fontMetrics = textView.getPaint().getFontMetricsInt();
         final int fontMetricsTop;
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN
-                // The includeFontPadding attribute was introduced
-                // in SDK16, and it is true by default.
-                || Api16Impl.getIncludeFontPadding(textView)) {
+        if (textView.getIncludeFontPadding()) {
             fontMetricsTop = fontMetrics.top;
         } else {
             fontMetricsTop = fontMetrics.ascent;
@@ -778,10 +663,7 @@
 
         final Paint.FontMetricsInt fontMetrics = textView.getPaint().getFontMetricsInt();
         final int fontMetricsBottom;
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN
-                // The includeFontPadding attribute was introduced
-                // in SDK16, and it is true by default.
-                || Api16Impl.getIncludeFontPadding(textView)) {
+        if (textView.getIncludeFontPadding()) {
             fontMetricsBottom = fontMetrics.bottom;
         } else {
             fontMetricsBottom = fontMetrics.descent;
@@ -893,9 +775,7 @@
                 builder.setBreakStrategy(Api23Impl.getBreakStrategy(textView));
                 builder.setHyphenationFrequency(Api23Impl.getHyphenationFrequency(textView));
             }
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-                builder.setTextDirection(getTextDirectionHeuristic(textView));
-            }
+            builder.setTextDirection(getTextDirectionHeuristic(textView));
             return builder.build();
         }
     }
@@ -911,9 +791,7 @@
 
         // There is no way of setting text direction heuristics to TextView.
         // Convert to the View's text direction int values.
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-            Api17Impl.setTextDirection(textView, getTextDirection(params.getTextDirection()));
-        }
+        textView.setTextDirection(getTextDirection(params.getTextDirection()));
 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
             float paintTextScaleX = params.getTextPaint().getTextScaleX();
@@ -988,7 +866,7 @@
                 // have LTR digits, but some locales, such as those written in the Adlam or N'Ko
                 // scripts, have RTL digits.
                 final DecimalFormatSymbols symbols =
-                        Api24Impl.getInstance(Api17Impl.getTextLocale(textView));
+                        Api24Impl.getInstance(textView.getTextLocale());
                 final String zero = Api28Impl.getDigitStrings(symbols)[0];
                 // In case the zero digit is multi-codepoint, just use the first codepoint to
                 // determine direction.
@@ -1005,10 +883,10 @@
 
         // Always need to resolve layout direction first
         final boolean defaultIsRtl =
-                (Api17Impl.getLayoutDirection(textView) == View.LAYOUT_DIRECTION_RTL);
+                (textView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
 
         // Now, we can select the heuristic
-        switch (Api17Impl.getTextDirection(textView)) {
+        switch (textView.getTextDirection()) {
             default:
             case TEXT_DIRECTION_FIRST_STRONG:
                 return (defaultIsRtl ? TextDirectionHeuristics.FIRSTSTRONG_RTL :
@@ -1031,7 +909,6 @@
     /**
      * Convert TextDirectionHeuristic to TextDirection int values
      */
-    @RequiresApi(18)
     private static int getTextDirection(@NonNull  TextDirectionHeuristic heuristic) {
         if (heuristic == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
             return TEXT_DIRECTION_FIRST_STRONG;
@@ -1123,78 +1000,6 @@
         return null;
     }
 
-    @RequiresApi(17)
-    static class Api17Impl {
-        private Api17Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void setCompoundDrawablesRelative(TextView textView, Drawable start, Drawable top,
-                Drawable end, Drawable bottom) {
-            textView.setCompoundDrawablesRelative(start, top, end, bottom);
-        }
-
-        @DoNotInline
-        static int getLayoutDirection(View view) {
-            return view.getLayoutDirection();
-        }
-
-        @DoNotInline
-        static void setCompoundDrawablesRelativeWithIntrinsicBounds(TextView textView,
-                Drawable start, Drawable top, Drawable end, Drawable bottom) {
-            textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
-        }
-
-        @DoNotInline
-        static void setCompoundDrawablesRelativeWithIntrinsicBounds(TextView textView, int start,
-                int top, int end, int bottom) {
-            textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
-        }
-
-        @DoNotInline
-        static Drawable[] getCompoundDrawablesRelative(TextView textView) {
-            return textView.getCompoundDrawablesRelative();
-        }
-
-        @DoNotInline
-        static void setTextDirection(View view, int textDirection) {
-            view.setTextDirection(textDirection);
-        }
-
-        @DoNotInline
-        static Locale getTextLocale(TextView textView) {
-            return textView.getTextLocale();
-        }
-
-        @DoNotInline
-        static int getTextDirection(View view) {
-            return view.getTextDirection();
-        }
-    }
-
-    @RequiresApi(16)
-    static class Api16Impl {
-        private Api16Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static int getMaxLines(TextView textView) {
-            return textView.getMaxLines();
-        }
-
-        @DoNotInline
-        static int getMinLines(TextView textView) {
-            return textView.getMinLines();
-        }
-
-        @DoNotInline
-        static boolean getIncludeFontPadding(TextView textView) {
-            return textView.getIncludeFontPadding();
-        }
-    }
-
     @RequiresApi(26)
     static class Api26Impl {
         private Api26Impl() {
diff --git a/core/core/src/main/java/androidx/core/widget/TextViewOnReceiveContentListener.java b/core/core/src/main/java/androidx/core/widget/TextViewOnReceiveContentListener.java
index 50a82bd..988b94e 100644
--- a/core/core/src/main/java/androidx/core/widget/TextViewOnReceiveContentListener.java
+++ b/core/core/src/main/java/androidx/core/widget/TextViewOnReceiveContentListener.java
@@ -22,7 +22,6 @@
 
 import android.content.ClipData;
 import android.content.Context;
-import android.os.Build;
 import android.text.Editable;
 import android.text.Selection;
 import android.text.Spanned;
@@ -32,7 +31,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.core.view.ContentInfoCompat;
 import androidx.core.view.ContentInfoCompat.Flags;
@@ -90,10 +88,11 @@
 
     private static CharSequence coerceToText(@NonNull Context context, @NonNull ClipData.Item item,
             @Flags int flags) {
-        if (Build.VERSION.SDK_INT >= 16) {
-            return Api16Impl.coerce(context, item, flags);
+        if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) {
+            CharSequence text = item.coerceToText(context);
+            return (text instanceof Spanned) ? text.toString() : text;
         } else {
-            return ApiImpl.coerce(context, item, flags);
+            return item.coerceToStyledText(context);
         }
     }
 
@@ -106,32 +105,4 @@
         Selection.setSelection(editable, end);
         editable.replace(start, end, replacement);
     }
-
-    @RequiresApi(16) // For ClipData.Item.coerceToStyledText()
-    private static final class Api16Impl {
-        private Api16Impl() {}
-
-        static CharSequence coerce(@NonNull Context context, @NonNull ClipData.Item item,
-                @Flags int flags) {
-            if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) {
-                CharSequence text = item.coerceToText(context);
-                return (text instanceof Spanned) ? text.toString() : text;
-            } else {
-                return item.coerceToStyledText(context);
-            }
-        }
-    }
-
-    private static final class ApiImpl {
-        private ApiImpl() {}
-
-        static CharSequence coerce(@NonNull Context context, @NonNull ClipData.Item item,
-                @Flags int flags) {
-            CharSequence text = item.coerceToText(context);
-            if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0 && text instanceof Spanned) {
-                text = text.toString();
-            }
-            return text;
-        }
-    }
 }
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
index 55b92f5..6e280c7 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
@@ -159,7 +159,7 @@
         // This points to the min APK version of GMS that contains required changes
         // to make passkeys work well
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-        const val MIN_GMS_APK_VERSION = 231200000
+        const val MIN_GMS_APK_VERSION = 230815045
 
         internal fun cancellationReviewerWithCallback(
             cancellationSignal: CancellationSignal?,
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt
index 8b89fd5..be677f8 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt
@@ -18,7 +18,6 @@
 
 import android.app.Activity
 import android.os.Looper
-import androidx.annotation.RequiresApi
 import androidx.credentials.exceptions.ClearCredentialException
 import androidx.credentials.exceptions.ClearCredentialProviderConfigurationException
 import androidx.credentials.exceptions.CreateCredentialException
@@ -44,8 +43,7 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
-@RequiresApi(16)
-@SdkSuppress(minSdkVersion = 16, maxSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+@SdkSuppress(maxSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
 class CredentialManagerPreUTest {
     private val context = InstrumentationRegistry.getInstrumentation().context
 
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index 491d65e..9fecfb4 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -30,6 +30,7 @@
 Configuration cache entry reused\.
 [0-9]+ actionable tasks: [0-9]+ executed, [0-9]+ from cache
 Configuration cache entry stored\.
+Calculating task graph as no cached configuration is available for tasks.*
 See the profiling report at\: file\:\/\/\$OUT_DIR\/androidx\/build\/reports\/profile\/profile\-[0-9]+\-[0-9]+\-[0-9]+\-[0-9]+\-[0-9]+\-[0-9]+\.html
 # > Task :lifecycle:lifecycle-common:compileJava
 Note: \$[^ ]+ uses or overrides a deprecated API\.
diff --git a/development/update-verification-metadata.sh b/development/update-verification-metadata.sh
index e588ec0..70b1472 100755
--- a/development/update-verification-metadata.sh
+++ b/development/update-verification-metadata.sh
@@ -73,10 +73,6 @@
 
   # rename keyring
   mv gradle/verification-keyring-dryrun.keys gradle/verification-keyring.keys 2>/dev/null || true
-
-  # remove temporary files
-  rm -f gradle/verification-keyring-dryrun.gpg
-  rm -f gradle/verification-keyring.gpg
 }
 regenerateVerificationMetadata
 
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 20bc9fd..4ae0c8d 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -8,10 +8,10 @@
 }
 
 dependencies {
-    docs("androidx.activity:activity:1.8.1")
-    docs("androidx.activity:activity-compose:1.8.1")
-    samples("androidx.activity:activity-compose-samples:1.8.1")
-    docs("androidx.activity:activity-ktx:1.8.1")
+    docs("androidx.activity:activity:1.9.0-alpha01")
+    docs("androidx.activity:activity-compose:1.9.0-alpha01")
+    samples("androidx.activity:activity-compose-samples:1.9.0-alpha01")
+    docs("androidx.activity:activity-ktx:1.9.0-alpha01")
     // ads-identifier is deprecated
     docsWithoutApiSince("androidx.ads:ads-identifier:1.0.0-alpha05")
     docsWithoutApiSince("androidx.ads:ads-identifier-common:1.0.0-alpha05")
@@ -32,16 +32,16 @@
     docs("androidx.asynclayoutinflater:asynclayoutinflater:1.1.0-alpha01")
     docs("androidx.asynclayoutinflater:asynclayoutinflater-appcompat:1.1.0-alpha01")
     docs("androidx.autofill:autofill:1.3.0-alpha01")
-    docs("androidx.benchmark:benchmark-common:1.2.1")
-    docs("androidx.benchmark:benchmark-junit4:1.2.1")
-    docs("androidx.benchmark:benchmark-macro:1.2.1")
-    docs("androidx.benchmark:benchmark-macro-junit4:1.2.1")
+    docs("androidx.benchmark:benchmark-common:1.2.2")
+    docs("androidx.benchmark:benchmark-junit4:1.2.2")
+    docs("androidx.benchmark:benchmark-macro:1.2.2")
+    docs("androidx.benchmark:benchmark-macro-junit4:1.2.2")
     docs("androidx.biometric:biometric:1.2.0-alpha05")
     docs("androidx.biometric:biometric-ktx:1.2.0-alpha05")
     samples("androidx.biometric:biometric-ktx-samples:1.2.0-alpha05")
-    docs("androidx.bluetooth:bluetooth:1.0.0-alpha01")
-    docs("androidx.bluetooth:bluetooth-testing:1.0.0-alpha01")
-    docs("androidx.browser:browser:1.8.0-alpha01")
+    docs("androidx.bluetooth:bluetooth:1.0.0-alpha02")
+    docs("androidx.bluetooth:bluetooth-testing:1.0.0-alpha02")
+    docs("androidx.browser:browser:1.8.0-beta01")
     docs("androidx.camera:camera-camera2:1.4.0-alpha02")
     docs("androidx.camera:camera-core:1.4.0-alpha02")
     docs("androidx.camera:camera-extensions:1.4.0-alpha02")
@@ -58,60 +58,60 @@
     docs("androidx.car.app:app-projected:1.4.0-rc01")
     docs("androidx.car.app:app-testing:1.4.0-rc01")
     docs("androidx.cardview:cardview:1.0.0")
-    kmpDocs("androidx.collection:collection:1.4.0-beta01")
-    docs("androidx.collection:collection-ktx:1.4.0-beta01")
-    kmpDocs("androidx.compose.animation:animation:1.6.0-beta01")
-    kmpDocs("androidx.compose.animation:animation-core:1.6.0-beta01")
-    kmpDocs("androidx.compose.animation:animation-graphics:1.6.0-beta01")
-    samples("androidx.compose.animation:animation-samples:1.6.0-beta01")
-    samples("androidx.compose.animation:animation-core-samples:1.6.0-beta01")
-    samples("androidx.compose.animation:animation-graphics-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.foundation:foundation:1.6.0-beta01")
-    kmpDocs("androidx.compose.foundation:foundation-layout:1.6.0-beta01")
-    samples("androidx.compose.foundation:foundation-layout-samples:1.6.0-beta01")
-    samples("androidx.compose.foundation:foundation-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.material3:material3:1.2.0-alpha11")
-    docs("androidx.compose.material3:material3-adaptive:1.0.0-alpha01")
-    samples("androidx.compose.material3:material3-adaptive-navigation-suite-samples:1.2.0-alpha11")
-    samples("androidx.compose.material3:material3-adaptive-samples:1.2.0-alpha11")
-    samples("androidx.compose.material3:material3-samples:1.2.0-alpha11")
-    kmpDocs("androidx.compose.material3:material3-window-size-class:1.2.0-alpha11")
-    samples("androidx.compose.material3:material3-window-size-class-samples:1.2.0-alpha10")
-    kmpDocs("androidx.compose.material:material:1.6.0-beta01")
-    kmpDocs("androidx.compose.material:material-icons-core:1.6.0-beta01")
-    samples("androidx.compose.material:material-icons-core-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.material:material-ripple:1.6.0-beta01")
-    samples("androidx.compose.material:material-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.runtime:runtime:1.6.0-beta01")
-    docs("androidx.compose.runtime:runtime-livedata:1.6.0-beta01")
-    samples("androidx.compose.runtime:runtime-livedata-samples:1.6.0-beta01")
-    docs("androidx.compose.runtime:runtime-rxjava2:1.6.0-beta01")
-    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.6.0-beta01")
-    docs("androidx.compose.runtime:runtime-rxjava3:1.6.0-beta01")
-    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.runtime:runtime-saveable:1.6.0-beta01")
-    samples("androidx.compose.runtime:runtime-saveable-samples:1.6.0-beta01")
-    samples("androidx.compose.runtime:runtime-samples:1.6.0-beta01")
-    docs("androidx.compose.runtime:runtime-tracing:1.0.0-alpha05")
-    kmpDocs("androidx.compose.ui:ui:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-geometry:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-graphics:1.6.0-beta01")
-    samples("androidx.compose.ui:ui-graphics-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-test:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-test-junit4:1.6.0-beta01")
-    samples("androidx.compose.ui:ui-test-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-text:1.6.0-beta01")
-    docs("androidx.compose.ui:ui-text-google-fonts:1.6.0-beta01")
-    samples("androidx.compose.ui:ui-text-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-tooling:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-tooling-data:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-tooling-preview:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-unit:1.6.0-beta01")
-    samples("androidx.compose.ui:ui-unit-samples:1.6.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-util:1.6.0-beta01")
-    docs("androidx.compose.ui:ui-viewbinding:1.6.0-beta01")
-    samples("androidx.compose.ui:ui-viewbinding-samples:1.6.0-beta01")
-    samples("androidx.compose.ui:ui-samples:1.6.0-beta01")
+    kmpDocs("androidx.collection:collection:1.4.0-beta02")
+    docs("androidx.collection:collection-ktx:1.4.0-beta02")
+    kmpDocs("androidx.compose.animation:animation:1.6.0-beta02")
+    kmpDocs("androidx.compose.animation:animation-core:1.6.0-beta02")
+    kmpDocs("androidx.compose.animation:animation-graphics:1.6.0-beta02")
+    samples("androidx.compose.animation:animation-samples:1.6.0-beta02")
+    samples("androidx.compose.animation:animation-core-samples:1.6.0-beta02")
+    samples("androidx.compose.animation:animation-graphics-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.foundation:foundation:1.6.0-beta02")
+    kmpDocs("androidx.compose.foundation:foundation-layout:1.6.0-beta02")
+    samples("androidx.compose.foundation:foundation-layout-samples:1.6.0-beta02")
+    samples("androidx.compose.foundation:foundation-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.material3:material3:1.2.0-alpha12")
+    docs("androidx.compose.material3:material3-adaptive:1.0.0-alpha02")
+    samples("androidx.compose.material3:material3-adaptive-navigation-suite-samples:1.2.0-alpha12")
+    samples("androidx.compose.material3:material3-adaptive-samples:1.2.0-alpha12")
+    samples("androidx.compose.material3:material3-samples:1.2.0-alpha12")
+    kmpDocs("androidx.compose.material3:material3-window-size-class:1.2.0-alpha12")
+    samples("androidx.compose.material3:material3-window-size-class-samples:1.2.0-alpha12")
+    kmpDocs("androidx.compose.material:material:1.6.0-beta02")
+    kmpDocs("androidx.compose.material:material-icons-core:1.6.0-beta02")
+    samples("androidx.compose.material:material-icons-core-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.material:material-ripple:1.6.0-beta02")
+    samples("androidx.compose.material:material-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.runtime:runtime:1.7.0-alpha01")
+    docs("androidx.compose.runtime:runtime-livedata:1.7.0-alpha01")
+    samples("androidx.compose.runtime:runtime-livedata-samples:1.7.0-alpha01")
+    docs("androidx.compose.runtime:runtime-rxjava2:1.7.0-alpha01")
+    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.7.0-alpha01")
+    docs("androidx.compose.runtime:runtime-rxjava3:1.7.0-alpha01")
+    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.runtime:runtime-saveable:1.7.0-alpha01")
+    samples("androidx.compose.runtime:runtime-saveable-samples:1.7.0-alpha01")
+    samples("androidx.compose.runtime:runtime-samples:1.7.0-alpha01")
+    docs("androidx.compose.runtime:runtime-tracing:1.0.0-beta01")
+    kmpDocs("androidx.compose.ui:ui:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-geometry:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-graphics:1.6.0-beta02")
+    samples("androidx.compose.ui:ui-graphics-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-test:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-test-junit4:1.6.0-beta02")
+    samples("androidx.compose.ui:ui-test-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-text:1.6.0-beta02")
+    docs("androidx.compose.ui:ui-text-google-fonts:1.6.0-beta02")
+    samples("androidx.compose.ui:ui-text-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-tooling:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-tooling-data:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-tooling-preview:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-unit:1.6.0-beta02")
+    samples("androidx.compose.ui:ui-unit-samples:1.6.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-util:1.6.0-beta02")
+    docs("androidx.compose.ui:ui-viewbinding:1.6.0-beta02")
+    samples("androidx.compose.ui:ui-viewbinding-samples:1.6.0-beta02")
+    samples("androidx.compose.ui:ui-samples:1.6.0-beta02")
     docs("androidx.concurrent:concurrent-futures:1.2.0-alpha02")
     docs("androidx.concurrent:concurrent-futures-ktx:1.2.0-alpha02")
     docs("androidx.constraintlayout:constraintlayout:2.2.0-alpha13")
@@ -119,13 +119,13 @@
     docs("androidx.constraintlayout:constraintlayout-core:1.1.0-alpha13")
     docs("androidx.contentpager:contentpager:1.0.0")
     docs("androidx.coordinatorlayout:coordinatorlayout:1.3.0-alpha02")
-    docs("androidx.core:core:1.13.0-alpha01")
+    docs("androidx.core:core:1.13.0-alpha02")
     // TODO(b/294531403): Turn on apiSince for core-animation when it releases as alpha
     docsWithoutApiSince("androidx.core:core-animation:1.0.0-rc01")
     docsWithoutApiSince("androidx.core:core-animation-testing:1.0.0-rc01")
     docs("androidx.core:core-google-shortcuts:1.2.0-alpha01")
     docs("androidx.core:core-i18n:1.0.0-alpha01")
-    docs("androidx.core:core-ktx:1.13.0-alpha01")
+    docs("androidx.core:core-ktx:1.13.0-alpha02")
     docs("androidx.core:core-location-altitude:1.0.0-alpha01")
     docs("androidx.core:core-performance:1.0.0-beta02")
     docs("androidx.core:core-performance-play-services:1.0.0-beta02")
@@ -135,7 +135,7 @@
     docs("androidx.core:core-role:1.2.0-alpha01")
     docs("androidx.core:core-splashscreen:1.1.0-alpha02")
     docs("androidx.core:core-telecom:1.0.0-alpha02")
-    docs("androidx.core:core-testing:1.13.0-alpha01")
+    docs("androidx.core:core-testing:1.13.0-alpha02")
     docs("androidx.core.uwb:uwb:1.0.0-alpha07")
     docs("androidx.core.uwb:uwb-rxjava3:1.0.0-alpha07")
     docs("androidx.credentials:credentials:1.2.0")
@@ -146,15 +146,15 @@
     docs("androidx.customview:customview:1.2.0-alpha02")
     // TODO(b/294531403): Turn on apiSince for customview-poolingcontainer when it releases as alpha
     docsWithoutApiSince("androidx.customview:customview-poolingcontainer:1.0.0-rc01")
-    kmpDocs("androidx.datastore:datastore:1.1.0-alpha05")
-    kmpDocs("androidx.datastore:datastore-core:1.1.0-alpha05")
-    kmpDocs("androidx.datastore:datastore-core-okio:1.1.0-alpha05")
-    kmpDocs("androidx.datastore:datastore-preferences:1.1.0-alpha05")
-    kmpDocs("androidx.datastore:datastore-preferences-core:1.1.0-alpha05")
-    docs("androidx.datastore:datastore-preferences-rxjava2:1.1.0-alpha05")
-    docs("androidx.datastore:datastore-preferences-rxjava3:1.1.0-alpha05")
-    docs("androidx.datastore:datastore-rxjava2:1.1.0-alpha05")
-    docs("androidx.datastore:datastore-rxjava3:1.1.0-alpha05")
+    kmpDocs("androidx.datastore:datastore:1.1.0-alpha07")
+    kmpDocs("androidx.datastore:datastore-core:1.1.0-alpha07")
+    kmpDocs("androidx.datastore:datastore-core-okio:1.1.0-alpha07")
+    kmpDocs("androidx.datastore:datastore-preferences:1.1.0-alpha07")
+    kmpDocs("androidx.datastore:datastore-preferences-core:1.1.0-alpha07")
+    docs("androidx.datastore:datastore-preferences-rxjava2:1.1.0-alpha07")
+    docs("androidx.datastore:datastore-preferences-rxjava3:1.1.0-alpha07")
+    docs("androidx.datastore:datastore-rxjava2:1.1.0-alpha07")
+    docs("androidx.datastore:datastore-rxjava3:1.1.0-alpha07")
     docs("androidx.documentfile:documentfile:1.1.0-alpha01")
     docs("androidx.draganddrop:draganddrop:1.0.0")
     docs("androidx.drawerlayout:drawerlayout:1.2.0")
@@ -171,9 +171,9 @@
     docs("androidx.enterprise:enterprise-feedback:1.1.0")
     docs("androidx.enterprise:enterprise-feedback-testing:1.1.0")
     docs("androidx.exifinterface:exifinterface:1.3.6")
-    docs("androidx.fragment:fragment:1.7.0-alpha06")
-    docs("androidx.fragment:fragment-ktx:1.7.0-alpha06")
-    docs("androidx.fragment:fragment-testing:1.7.0-alpha06")
+    docs("androidx.fragment:fragment:1.7.0-alpha07")
+    docs("androidx.fragment:fragment-ktx:1.7.0-alpha07")
+    docs("androidx.fragment:fragment-testing:1.7.0-alpha07")
     docs("androidx.glance:glance:1.0.0")
     docs("androidx.glance:glance-appwidget:1.0.0")
     samples("androidx.glance:glance-appwidget-samples:1.0.0")
@@ -186,6 +186,7 @@
     docs("androidx.glance:glance-wear-tiles-preview:1.0.0-alpha06")
     docs("androidx.graphics:graphics-core:1.0.0-alpha05")
     samples("androidx.graphics:graphics-core-samples:1.0.0-alpha05")
+    docs("androidx.graphics:graphics-path:1.0.0-beta01")
     docs("androidx.gridlayout:gridlayout:1.1.0-beta01")
     docs("androidx.health.connect:connect-client:1.1.0-alpha06")
     samples("androidx.health.connect:connect-client-samples:1.1.0-alpha06")
@@ -229,11 +230,11 @@
     docs("androidx.loader:loader:1.1.0")
     // localbroadcastmanager is deprecated
     docsWithoutApiSince("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")
-    docs("androidx.media2:media2-common:1.3.0-alpha01")
-    docs("androidx.media2:media2-player:1.3.0-alpha01")
-    docs("androidx.media2:media2-session:1.3.0-alpha01")
-    docs("androidx.media2:media2-widget:1.3.0-alpha01")
-    docs("androidx.media:media:1.7.0-rc01")
+    docs("androidx.media2:media2-common:1.3.0-beta01")
+    docs("androidx.media2:media2-player:1.3.0-beta01")
+    docs("androidx.media2:media2-session:1.3.0-beta01")
+    docs("androidx.media2:media2-widget:1.3.0-beta01")
+    docs("androidx.media:media:1.7.0")
     // androidx.media3 is not hosted in androidx
     docsWithoutApiSince("androidx.media3:media3-cast:1.2.0")
     docsWithoutApiSince("androidx.media3:media3-common:1.2.0")
@@ -312,18 +313,18 @@
     docs("androidx.recyclerview:recyclerview-selection:2.0.0-alpha01")
     docs("androidx.remotecallback:remotecallback:1.0.0-alpha02")
     docs("androidx.resourceinspection:resourceinspection-annotation:1.0.1")
-    docs("androidx.room:room-common:2.6.0")
-    docs("androidx.room:room-guava:2.6.0")
-    docs("androidx.room:room-ktx:2.6.0")
-    docs("androidx.room:room-migration:2.6.0")
-    docs("androidx.room:room-paging:2.6.0")
-    docs("androidx.room:room-paging-guava:2.6.0")
-    docs("androidx.room:room-paging-rxjava2:2.6.0")
-    docs("androidx.room:room-paging-rxjava3:2.6.0")
-    docs("androidx.room:room-runtime:2.6.0")
-    docs("androidx.room:room-rxjava2:2.6.0")
-    docs("androidx.room:room-rxjava3:2.6.0")
-    docs("androidx.room:room-testing:2.6.0")
+    docs("androidx.room:room-common:2.6.1")
+    docs("androidx.room:room-guava:2.6.1")
+    docs("androidx.room:room-ktx:2.6.1")
+    docs("androidx.room:room-migration:2.6.1")
+    docs("androidx.room:room-paging:2.6.1")
+    docs("androidx.room:room-paging-guava:2.6.1")
+    docs("androidx.room:room-paging-rxjava2:2.6.1")
+    docs("androidx.room:room-paging-rxjava3:2.6.1")
+    docs("androidx.room:room-runtime:2.6.1")
+    docs("androidx.room:room-rxjava2:2.6.1")
+    docs("androidx.room:room-rxjava3:2.6.1")
+    docs("androidx.room:room-testing:2.6.1")
     docs("androidx.savedstate:savedstate:1.2.1")
     docs("androidx.savedstate:savedstate-ktx:1.2.1")
     docs("androidx.security:security-app-authenticator:1.0.0-alpha02")
@@ -371,8 +372,8 @@
     // TODO(243405142) clean-up
     docsWithoutApiSince("androidx.tracing:tracing-perfetto-common:1.0.0-alpha16")
     docs("androidx.tracing:tracing-perfetto-handshake:1.0.0")
-    docs("androidx.transition:transition:1.5.0-alpha04")
-    docs("androidx.transition:transition-ktx:1.5.0-alpha04")
+    docs("androidx.transition:transition:1.5.0-alpha05")
+    docs("androidx.transition:transition-ktx:1.5.0-alpha05")
     docs("androidx.tv:tv-foundation:1.0.0-alpha10")
     docs("androidx.tv:tv-material:1.0.0-alpha10")
     samples("androidx.tv:tv-samples:1.0.0-alpha10")
@@ -380,7 +381,7 @@
     docs("androidx.vectordrawable:vectordrawable:1.2.0-beta01")
     docs("androidx.vectordrawable:vectordrawable-animated:1.2.0-alpha01")
     docs("androidx.vectordrawable:vectordrawable-seekable:1.0.0-beta01")
-    docs("androidx.versionedparcelable:versionedparcelable:1.2.0-alpha01")
+    docs("androidx.versionedparcelable:versionedparcelable:1.2.0-beta01")
     docs("androidx.viewpager2:viewpager2:1.1.0-beta02")
     docs("androidx.viewpager:viewpager:1.1.0-alpha01")
     docs("androidx.wear.compose:compose-foundation:1.3.0-beta01")
@@ -393,36 +394,35 @@
     docs("androidx.wear.compose:compose-navigation:1.3.0-beta01")
     samples("androidx.wear.compose:compose-navigation-samples:1.3.0-beta01")
     docs("androidx.wear.compose:compose-ui-tooling:1.3.0-beta01")
-    docs("androidx.wear.protolayout:protolayout:1.1.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-expression:1.1.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-expression-pipeline:1.1.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-material:1.1.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-material-core:1.1.0-alpha02")
-    docs("androidx.wear.protolayout:protolayout-renderer:1.1.0-alpha02")
-    docs("androidx.wear.tiles:tiles:1.3.0-alpha02")
-    docs("androidx.wear.tiles:tiles-material:1.3.0-alpha02")
-    docs("androidx.wear.tiles:tiles-renderer:1.3.0-alpha02")
-    docs("androidx.wear.tiles:tiles-testing:1.3.0-alpha02")
-    docs("androidx.wear.tiles:tiles-tooling:1.3.0-alpha02")
-    docs("androidx.wear.tiles:tiles-tooling-preview:1.3.0-alpha02")
-    docs("androidx.wear.watchface:watchface:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-client:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-client-guava:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-complications:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-complications-data:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-complications-data-source:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.0-rc01")
-    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-complications-rendering:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-data:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-editor:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-editor-guava:1.2.0-rc01")
-    samples("androidx.wear.watchface:watchface-editor-samples:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-guava:1.2.0-rc01")
-    samples("androidx.wear.watchface:watchface-samples:1.2.0-rc01")
-    docs("androidx.wear.watchface:watchface-style:1.2.0-rc01")
-    // TODO(b/294531403): Turn on apiSince for wear when it releases as alpha
-    docsWithoutApiSince("androidx.wear:wear:1.4.0-alpha01")
+    docs("androidx.wear.protolayout:protolayout:1.1.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-expression:1.1.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-expression-pipeline:1.1.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-material:1.1.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-material-core:1.1.0-alpha03")
+    docs("androidx.wear.protolayout:protolayout-renderer:1.1.0-alpha03")
+    docs("androidx.wear.tiles:tiles:1.3.0-alpha03")
+    docs("androidx.wear.tiles:tiles-material:1.3.0-alpha03")
+    docs("androidx.wear.tiles:tiles-renderer:1.3.0-alpha03")
+    docs("androidx.wear.tiles:tiles-testing:1.3.0-alpha03")
+    docs("androidx.wear.tiles:tiles-tooling:1.3.0-alpha03")
+    docs("androidx.wear.tiles:tiles-tooling-preview:1.3.0-alpha03")
+    docs("androidx.wear.watchface:watchface:1.2.0")
+    docs("androidx.wear.watchface:watchface-client:1.2.0")
+    docs("androidx.wear.watchface:watchface-client-guava:1.2.0")
+    docs("androidx.wear.watchface:watchface-complications:1.2.0")
+    docs("androidx.wear.watchface:watchface-complications-data:1.2.0")
+    docs("androidx.wear.watchface:watchface-complications-data-source:1.2.0")
+    docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.0")
+    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.0")
+    docs("androidx.wear.watchface:watchface-complications-rendering:1.2.0")
+    docs("androidx.wear.watchface:watchface-data:1.2.0")
+    docs("androidx.wear.watchface:watchface-editor:1.2.0")
+    docs("androidx.wear.watchface:watchface-editor-guava:1.2.0")
+    samples("androidx.wear.watchface:watchface-editor-samples:1.2.0")
+    docs("androidx.wear.watchface:watchface-guava:1.2.0")
+    samples("androidx.wear.watchface:watchface-samples:1.2.0")
+    docs("androidx.wear.watchface:watchface-style:1.2.0")
+    docs("androidx.wear:wear:1.4.0-alpha01")
     stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
     docs("androidx.wear:wear-input:1.2.0-alpha02")
     samples("androidx.wear:wear-input-samples:1.2.0-alpha01")
@@ -430,8 +430,8 @@
     docs("androidx.wear:wear-ongoing:1.1.0-alpha01")
     docs("androidx.wear:wear-phone-interactions:1.1.0-alpha03")
     docs("androidx.wear:wear-remote-interactions:1.1.0-alpha01")
-    docs("androidx.wear:wear-tooling-preview:1.0.0-rc01")
-    docs("androidx.webkit:webkit:1.9.0-rc01")
+    docs("androidx.wear:wear-tooling-preview:1.0.0")
+    docs("androidx.webkit:webkit:1.10.0-alpha01")
     docs("androidx.window.extensions.core:core:1.0.0")
     docs("androidx.window:window:1.3.0-alpha01")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
@@ -442,13 +442,13 @@
     docs("androidx.window:window-rxjava3:1.3.0-alpha01")
     samples("androidx.window:window-samples:1.3.0-alpha01")
     docs("androidx.window:window-testing:1.3.0-alpha01")
-    docs("androidx.work:work-gcm:2.9.0-rc01")
-    docs("androidx.work:work-multiprocess:2.9.0-rc01")
-    docs("androidx.work:work-runtime:2.9.0-rc01")
-    docs("androidx.work:work-runtime-ktx:2.9.0-rc01")
-    docs("androidx.work:work-rxjava2:2.9.0-rc01")
-    docs("androidx.work:work-rxjava3:2.9.0-rc01")
-    docs("androidx.work:work-testing:2.9.0-rc01")
+    docs("androidx.work:work-gcm:2.9.0")
+    docs("androidx.work:work-multiprocess:2.9.0")
+    docs("androidx.work:work-runtime:2.9.0")
+    docs("androidx.work:work-runtime-ktx:2.9.0")
+    docs("androidx.work:work-rxjava2:2.9.0")
+    docs("androidx.work:work-rxjava3:2.9.0")
+    docs("androidx.work:work-testing:2.9.0")
 
     // Force upgrade to jsoup 1.16.2 (b/309773103)
     stubs("org.jsoup:jsoup:1.16.2")
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index 615e26d..c2a1a61 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -398,7 +398,9 @@
     docs(project(":wear:wear-input-testing"))
     docs(project(":wear:wear-ongoing"))
     docs(project(":wear:wear-phone-interactions"))
+    samples(project(":wear:wear-phone-interactions-samples"))
     docs(project(":wear:wear-remote-interactions"))
+    samples(project(":wear:wear-remote-interactions-samples"))
     docs(project(":webkit:webkit"))
     docs(project(":window:window"))
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release.aar"]))
diff --git a/docs/testing.md b/docs/testing.md
index 0a256ad..2df00c1 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -7,6 +7,35 @@
 useful for demonstrating how to use features as well as performing manual
 testing.
 
+## Motivation
+
+Jetpack libraries are developed with the intention that they are functionally
+stable and production-ready as of the first public `alpha01` release, and that
+they remain production-ready at tip-of-tree thereafter.
+
+For this reason, we emphasize that continuous integration testing -- both pre-
+and post-submit -- is the ultimate source of truth for library correctness. If
+tests are failing at head, the library is not only at risk of blocking public
+releases but at risk of breaking production Google apps that rely on its
+tip-of-tree builds.
+
+### API level coverage in CI
+
+Generally, we aim to test Jetpack libraries against (1) the earliest supported
+API level, (2) the latest stable API level, (3) API levels with major changes,
+(4) API levels with high concentration of devices in the field, and (5) the next
+pre-release API level.
+
+In practice, this is limited by device and emulator availability and
+reliability. As of November 2023, we run tests on the following API levels:
+
+-   API level 21: the lowest API level supported by Firebase Test Lab (FTL)
+-   API level 26: the lowest supported ARM-based emulator FTL runner, which has
+    much greater performance and stability
+-   API level 28: provides coverage between 26 and 30
+-   API levels 30, 31, 33: the latest supported API levels, which represent the
+    majority of devices in the field
+
 ## Adding tests {#adding}
 
 For an example of how to set up simple unit and integration tests in a new
diff --git a/documentfile/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java b/documentfile/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
index f29d0a1..743daa3 100644
--- a/documentfile/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
+++ b/documentfile/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
@@ -114,11 +114,7 @@
      */
     @Nullable
     public static DocumentFile fromSingleUri(@NonNull Context context, @NonNull Uri singleUri) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return new SingleDocumentFile(null, context, singleUri);
-        } else {
-            return null;
-        }
+        return new SingleDocumentFile(null, context, singleUri);
     }
 
     /**
diff --git a/drawerlayout/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java b/drawerlayout/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
index 0eab442..0ffddb8 100644
--- a/drawerlayout/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
+++ b/drawerlayout/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
@@ -41,7 +41,6 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.accessibility.AccessibilityEvent;
 import android.window.OnBackInvokedCallback;
 import android.window.OnBackInvokedDispatcher;
@@ -194,9 +193,6 @@
             android.R.attr.layout_gravity
     };
 
-    /** Whether we can use NO_HIDE_DESCENDANTS accessibility importance. */
-    static final boolean CAN_HIDE_DESCENDANTS = Build.VERSION.SDK_INT >= 19;
-
     /** Whether the drawer shadow comes from setting elevation on the drawer. */
     private static final boolean SET_DRAWER_SHADOW_FROM_ELEVATION =
             Build.VERSION.SDK_INT >= 21;
@@ -2181,11 +2177,6 @@
                     ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
 
-        // We only need a delegate here if the framework doesn't understand
-        // NO_HIDE_DESCENDANTS importance.
-        if (!CAN_HIDE_DESCENDANTS) {
-            ViewCompat.setAccessibilityDelegate(child, mChildAccessibilityDelegate);
-        }
     }
 
     static boolean includeChildForAccessibility(View child) {
@@ -2461,25 +2452,7 @@
 
         @Override
         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
-            if (CAN_HIDE_DESCENDANTS) {
-                super.onInitializeAccessibilityNodeInfo(host, info);
-            } else {
-                // Obtain a node for the host, then manually generate the list
-                // of children to only include non-obscured views.
-                final AccessibilityNodeInfoCompat superNode =
-                        AccessibilityNodeInfoCompat.obtain(info);
-                super.onInitializeAccessibilityNodeInfo(host, superNode);
-
-                info.setSource(host);
-                final ViewParent parent = ViewCompat.getParentForAccessibility(host);
-                if (parent instanceof View) {
-                    info.setParent((View) parent);
-                }
-                copyNodeInfoNoChildren(info, superNode);
-                superNode.recycle();
-
-                addChildrenForAccessibility(info, (ViewGroup) host);
-            }
+            super.onInitializeAccessibilityNodeInfo(host, info);
 
             info.setClassName(ACCESSIBILITY_CLASS_NAME);
 
@@ -2523,15 +2496,6 @@
             return super.dispatchPopulateAccessibilityEvent(host, event);
         }
 
-        @Override
-        public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
-                AccessibilityEvent event) {
-            if (CAN_HIDE_DESCENDANTS || includeChildForAccessibility(child)) {
-                return super.onRequestSendAccessibilityEvent(host, child, event);
-            }
-            return false;
-        }
-
         private void addChildrenForAccessibility(AccessibilityNodeInfoCompat info, ViewGroup v) {
             final int childCount = v.getChildCount();
             for (int i = 0; i < childCount; i++) {
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/ConfigTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/ConfigTest.java
index 8c9c7c3..59cd55e 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/ConfigTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/ConfigTest.java
@@ -40,7 +40,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -74,7 +73,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testBuild_withDefaultValues() {
         final EmojiCompat.Config config = new ValidTestConfig().setReplaceAll(true);
 
@@ -101,7 +99,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19) //Fail callback never called for pre 19
     public void testInitCallback_callsFailCallback() {
         final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
         final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
@@ -166,7 +163,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testGlyphCheckerInstance_EmojiSpan_isNotAdded_whenHasGlyph_returnsTrue() {
         final EmojiCompat.GlyphChecker glyphChecker = mock(EmojiCompat.GlyphChecker.class);
         when(glyphChecker.hasGlyph(any(CharSequence.class), anyInt(), anyInt(), anyInt()))
@@ -186,7 +182,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testGlyphCheckerInstance_EmojiSpan_isAdded_whenHasGlyph_returnsFalse() {
         final EmojiCompat.GlyphChecker glyphChecker = mock(EmojiCompat.GlyphChecker.class);
         when(glyphChecker.hasGlyph(any(CharSequence.class), anyInt(), anyInt(), anyInt()))
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiCompatTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiCompatTest.java
index f659cee..f78dc84 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiCompatTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiCompatTest.java
@@ -39,7 +39,6 @@
 import static androidx.emoji.util.EmojiMatcher.hasEmoji;
 import static androidx.emoji.util.EmojiMatcher.hasEmojiAt;
 import static androidx.emoji.util.EmojiMatcher.hasEmojiCount;
-import static androidx.emoji.util.KeyboardUtil.del;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.instanceOf;
@@ -58,26 +57,21 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.annotation.SuppressLint;
 import android.os.Bundle;
 import android.text.Editable;
-import android.text.Selection;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.SpannedString;
-import android.view.KeyEvent;
 import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
 
 import androidx.emoji.util.Emoji.EmojiMapping;
 import androidx.emoji.util.TestString;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -166,58 +160,36 @@
     }
 
     @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testProcess_returnsSameCharSequence_pre19() {
-        assertNull(EmojiCompat.get().process(null));
-
-        CharSequence testString = "abc";
-        assertSame(testString, EmojiCompat.get().process(testString));
-
-        testString = new SpannableString("abc");
-        assertSame(testString, EmojiCompat.get().process(testString));
-
-        testString = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE}).toString();
-        assertSame(testString, EmojiCompat.get().process(testString));
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsSingleCodePointEmoji() {
         assertCodePointMatch(EMOJI_SINGLE_CODEPOINT);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsFlagEmoji() {
         assertCodePointMatch(EMOJI_FLAG);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsUnknownFlagEmoji() {
         assertCodePointMatch(EMOJI_UNKNOWN_FLAG);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsRegionalIndicatorSymbol() {
         assertCodePointMatch(EMOJI_REGIONAL_SYMBOL);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsKeyCapEmoji() {
         assertCodePointMatch(EMOJI_DIGIT_KEYCAP);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_doesNotAddEmojiForNumbers() {
         assertCodePointDoesNotMatch(new int[] {CHAR_DIGIT});
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_doesNotAddEmojiForNumbers_1() {
         final TestString string = new TestString(EMOJI_SINGLE_CODEPOINT).append('1', 'f');
         CharSequence charSequence = EmojiCompat.get().process(string.toString());
@@ -225,19 +197,16 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsVariantSelectorEmoji() {
         assertCodePointMatch(EMOJI_DIGIT_ES);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_doesNotAddVariantSelectorTextStyle() {
         assertCodePointDoesNotMatch(new int[]{CHAR_DIGIT, CHAR_VS_TEXT});
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsVariantSelectorAndKeyCapEmoji() {
         assertCodePointMatch(EMOJI_DIGIT_ES_KEYCAP);
     }
@@ -248,26 +217,22 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsAsteriskKeyCapEmoji() {
         assertCodePointMatch(EMOJI_ASTERISK_KEYCAP);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsSkinModifierEmoji() {
         assertCodePointMatch(EMOJI_SKIN_MODIFIER);
         assertCodePointMatch(EMOJI_SKIN_MODIFIER_TYPE_ONE);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsSkinModifierEmoji_withVariantSelector() {
         assertCodePointMatch(EMOJI_SKIN_MODIFIER_WITH_VS);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsSkinModifierEmoji_270c_withVariantSelector() {
         // 0x270c is a Standardized Variant Base, Emoji Modifier Base and also Emoji
         // therefore it is different than i.e. 0x1f3c3. The code actually failed for this test
@@ -276,14 +241,12 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_defaultStyleDoesNotAddSpan() {
         assertCodePointDoesNotMatch(new int[]{CHAR_DEFAULT_TEXT_STYLE});
         assertCodePointMatch(DEFAULT_TEXT_STYLE);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_defaultEmojiStyle_withTextStyleVs() {
         assertCodePointMatch(EMOJI_SINGLE_CODEPOINT.id(),
                 new int[]{CHAR_DEFAULT_EMOJI_STYLE, CHAR_VS_EMOJI});
@@ -291,14 +254,12 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_genderEmoji() {
         assertCodePointMatch(EMOJI_GENDER);
         assertCodePointMatch(EMOJI_GENDER_WITHOUT_VS);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_standardizedVariantEmojiExceptions() {
         final int[][] exceptions = new int[][]{
                 {0x2600, 0xF034D},
@@ -322,13 +283,11 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsZwjEmoji() {
         assertCodePointMatch(EMOJI_WITH_ZWJ);
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_doesNotAddEmojiForNumbersAfterZwjEmo() {
         TestString string = new TestString(EMOJI_WITH_ZWJ).append(0x20, 0x2B, 0x31)
                 .withSuffix().withPrefix();
@@ -343,7 +302,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_addsEmojiThatFollowsDigit() {
         TestString string = new TestString(EMOJI_SINGLE_CODEPOINT).prepend('N', '5');
         CharSequence charSequence = EmojiCompat.get().process(string.toString());
@@ -359,7 +317,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withAppend() {
         final Editable editable = new SpannableStringBuilder(new TestString('a').withPrefix()
                 .withSuffix().toString());
@@ -383,7 +340,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_reprocess() {
         final String string = new TestString(EMOJI_SINGLE_CODEPOINT)
                 .append(EMOJI_SINGLE_CODEPOINT)
@@ -428,7 +384,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withMaxEmojiSetToOne() {
         final String original = new TestString(EMOJI_SINGLE_CODEPOINT).toString();
 
@@ -440,7 +395,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withMaxEmojiSetToLessThenExistingSpanCount() {
         final String original = new TestString(EMOJI_SINGLE_CODEPOINT)
                 .append(EMOJI_SINGLE_CODEPOINT)
@@ -462,7 +416,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withMaxEmojiSet_withExistingEmojis() {
         // test string with two emoji characters
         final String original = new TestString(EMOJI_SINGLE_CODEPOINT)
@@ -500,7 +453,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withReplaceNonExistent_callsGlyphChecker() {
         final EmojiCompat.GlyphChecker glyphChecker = mock(EmojiCompat.GlyphChecker.class);
         final EmojiCompat.Config config = TestConfigBuilder.freshConfig()
@@ -525,7 +477,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withReplaceDefault_doesNotCallGlyphChecker() {
         final EmojiCompat.GlyphChecker glyphChecker = mock(EmojiCompat.GlyphChecker.class);
         final EmojiCompat.Config config = TestConfigBuilder.freshConfig()
@@ -550,7 +501,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testProcess_withSpanned_replaceNonExistent() {
         final EmojiCompat.GlyphChecker glyphChecker = mock(EmojiCompat.GlyphChecker.class);
         final EmojiCompat.Config config = TestConfigBuilder.freshConfig()
@@ -597,21 +547,6 @@
     }
 
     @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testHasEmojiGlyph_pre19() {
-        String sequence = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE}).toString();
-        assertFalse(EmojiCompat.get().hasEmojiGlyph(sequence));
-    }
-
-    @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testHasEmojiGlyph_withMetaVersion_pre19() {
-        String sequence = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE}).toString();
-        assertFalse(EmojiCompat.get().hasEmojiGlyph(sequence, Integer.MAX_VALUE));
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testHasEmojiGlyph_returnsTrueForExistingEmoji() {
         final String sequence = new TestString(EMOJI_FLAG).toString();
         assertTrue(EmojiCompat.get().hasEmojiGlyph(sequence));
@@ -624,7 +559,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testHashEmojiGlyph_withDefaultEmojiStyles() {
         String sequence = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE}).toString();
         assertTrue(EmojiCompat.get().hasEmojiGlyph(sequence));
@@ -637,7 +571,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testHashEmojiGlyph_withMetadataVersion() {
         final String sequence = new TestString(EMOJI_SINGLE_CODEPOINT).toString();
         assertFalse(EmojiCompat.get().hasEmojiGlyph(sequence, 0));
@@ -645,13 +578,6 @@
     }
 
     @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testGetLoadState_returnsSuccess_pre19() {
-        assertEquals(EmojiCompat.get().getLoadState(), EmojiCompat.LOAD_STATE_SUCCEEDED);
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testGetLoadState_returnsSuccessIfLoadSuccess() throws InterruptedException {
         final TestConfigBuilder.WaitingDataLoader
                 metadataLoader = new TestConfigBuilder.WaitingDataLoader(true /*success*/);
@@ -668,7 +594,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testGetLoadState_returnsFailIfLoadFail() throws InterruptedException {
         final TestConfigBuilder.WaitingDataLoader
                 metadataLoader = new TestConfigBuilder.WaitingDataLoader(false/*fail*/);
@@ -713,24 +638,6 @@
     }
 
     @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testLoad_pre19() {
-        final EmojiCompat.MetadataRepoLoader loader = spy(new TestConfigBuilder
-                .TestEmojiDataLoader());
-        final EmojiCompat.Config config = new TestConfigBuilder.TestConfig(loader)
-                .setMetadataLoadStrategy(EmojiCompat.LOAD_STRATEGY_MANUAL);
-
-        EmojiCompat.reset(config);
-
-        verify(loader, never()).load(any(EmojiCompat.MetadataRepoLoaderCallback.class));
-        assertEquals(EmojiCompat.LOAD_STATE_DEFAULT, EmojiCompat.get().getLoadState());
-
-        EmojiCompat.get().load();
-        assertEquals(EmojiCompat.LOAD_STATE_SUCCEEDED, EmojiCompat.get().getLoadState());
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_startsLoading() {
         final EmojiCompat.MetadataRepoLoader loader = spy(new TestConfigBuilder
                 .TestEmojiDataLoader());
@@ -748,7 +655,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_onceSuccessDoesNotStartLoading() {
         final EmojiCompat.MetadataRepoLoader loader = spy(new TestConfigBuilder
                 .TestEmojiDataLoader());
@@ -768,7 +674,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_onceLoadingDoesNotStartLoading() throws InterruptedException {
         final TestConfigBuilder.WaitingDataLoader loader = spy(
                 new TestConfigBuilder.WaitingDataLoader(true /*success*/));
@@ -795,14 +700,6 @@
     }
 
     @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testGetAssetSignature() {
-        final String signature = EmojiCompat.get().getAssetSignature();
-        assertTrue(signature.isEmpty());
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testGetAssetSignature_api19() {
         final String signature = EmojiCompat.get().getAssetSignature();
         assertNotNull(signature);
@@ -810,7 +707,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUpdateEditorInfoAttrs_setsKeysIfInitialized() {
         final EditorInfo editorInfo = new EditorInfo();
         editorInfo.extras = new Bundle();
@@ -833,7 +729,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUpdateEditorInfoAttrs_makesBundleIfNull() {
         final EditorInfo editorInfo = new EditorInfo();
         editorInfo.extras = null;
@@ -848,40 +743,6 @@
     }
 
     @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testHandleDeleteSurroundingText_pre19() {
-        final TestString testString = new TestString(EMOJI_SINGLE_CODEPOINT);
-        final InputConnection inputConnection = mock(InputConnection.class);
-        final Editable editable = spy(new SpannableStringBuilder(testString.toString()));
-
-        Selection.setSelection(editable, testString.emojiEndIndex());
-
-        reset(editable);
-        reset(inputConnection);
-        verifyNoMoreInteractions(editable);
-        verifyNoMoreInteractions(inputConnection);
-
-        // try backwards delete 1 character
-        assertFalse(EmojiCompat.handleDeleteSurroundingText(inputConnection, editable,
-                1 /*beforeLength*/, 0 /*afterLength*/, false /*inCodePoints*/));
-    }
-
-    @Test
-    @SdkSuppress(maxSdkVersion = 18)
-    public void testOnKeyDown_pre19() {
-        final TestString testString = new TestString(EMOJI_SINGLE_CODEPOINT);
-        final Editable editable = spy(new SpannableStringBuilder(testString.toString()));
-        Selection.setSelection(editable, testString.emojiEndIndex());
-        final KeyEvent event = del();
-
-        reset(editable);
-        verifyNoMoreInteractions(editable);
-
-        assertFalse(EmojiCompat.handleOnKeyDown(editable, event.getKeyCode(), event));
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUseEmojiAsDefaultStyle_whenEmojiInTheMiddle() {
         final EmojiCompat.Config config = TestConfigBuilder.config().setReplaceAll(true);
         EmojiCompat.reset(config);
@@ -894,7 +755,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUseEmojiAsDefaultStyle_whenEmojiAtTheEnd() {
         final EmojiCompat.Config config = TestConfigBuilder.config().setReplaceAll(true);
         EmojiCompat.reset(config);
@@ -907,7 +767,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUseEmojiAsDefaultStyle_noEmojisAdded_whenMarkedAsException() {
         final String s = new TestString(CHAR_DEFAULT_TEXT_STYLE).toString();
         final List<Integer> exceptions =
@@ -920,7 +779,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUseEmojiAsDefaultStyle_emojisAdded_whenNotMarkedAsException() {
         final String s = new TestString(CHAR_DEFAULT_TEXT_STYLE).toString();
         final List<Integer> exceptions =
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanInstrumentationTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanInstrumentationTest.java
index 4cc43d8..3b5ae18 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanInstrumentationTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanInstrumentationTest.java
@@ -33,7 +33,6 @@
 import androidx.emoji.util.TestString;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -44,7 +43,6 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiSpanInstrumentationTest {
 
     @SuppressWarnings("deprecation")
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanTest.java
index 0b07a0f..3db5c29 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/EmojiSpanTest.java
@@ -31,7 +31,6 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -41,7 +40,6 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiSpanTest {
 
     @Before
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java
index 5a65bc1..3035cf6 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java
@@ -56,7 +56,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -99,7 +98,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_whenGetFontThrowsException() throws NameNotFoundException {
         final Exception exception = new RuntimeException();
         doThrow(exception).when(mFontProviderHelper).fetchFonts(
@@ -114,7 +112,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_providerNotFound() throws NameNotFoundException {
         doThrow(new NameNotFoundException()).when(mFontProviderHelper).fetchFonts(
                 any(Context.class), any(FontRequest.class));
@@ -131,14 +128,12 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_wrongCertificate() throws NameNotFoundException {
         verifyLoaderOnFailedCalled(STATUS_WRONG_CERTIFICATES, null /* fonts */,
                 "fetchFonts failed (" + STATUS_WRONG_CERTIFICATES + ")");
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_fontNotFound() throws NameNotFoundException {
         verifyLoaderOnFailedCalled(STATUS_OK,
                 getTestFontInfoWithInvalidPath(RESULT_CODE_FONT_NOT_FOUND),
@@ -146,7 +141,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_fontUnavailable() throws NameNotFoundException {
         verifyLoaderOnFailedCalled(STATUS_OK,
                 getTestFontInfoWithInvalidPath(RESULT_CODE_FONT_UNAVAILABLE),
@@ -154,7 +148,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_malformedQuery() throws NameNotFoundException {
         verifyLoaderOnFailedCalled(STATUS_OK,
                 getTestFontInfoWithInvalidPath(RESULT_CODE_MALFORMED_QUERY),
@@ -162,21 +155,18 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_resultNotFound() throws NameNotFoundException {
         verifyLoaderOnFailedCalled(STATUS_OK, new FontInfo[] {},
                 "fetchFonts failed (empty result)");
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_nullFontInfo() throws NameNotFoundException {
         verifyLoaderOnFailedCalled(STATUS_OK, null /* fonts */,
                 "fetchFonts failed (empty result)");
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_cannotLoadTypeface() throws NameNotFoundException {
         // getTestFontInfoWithInvalidPath returns FontInfo with invalid path to file.
         verifyLoaderOnFailedCalled(STATUS_OK,
@@ -185,7 +175,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_success() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final FontInfo[] fonts =  new FontInfo[] {
@@ -204,7 +193,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_retryPolicy() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final FontInfo[] fonts =  new FontInfo[] {
@@ -226,7 +214,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_keepRetryingAndGiveUp() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final FontInfo[] fonts =  new FontInfo[] {
@@ -252,7 +239,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_keepRetryingAndFail() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final Uri uri = Uri.fromFile(file);
@@ -309,7 +295,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_keepRetryingAndSuccess() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final Uri uri = Uri.fromFile(file);
@@ -366,7 +351,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_ObserverNotifyAndSuccess() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final Uri uri = Uri.fromFile(file);
@@ -422,7 +406,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testLoad_ObserverNotifyAndFail() throws IOException, NameNotFoundException {
         final File file = loadFont(mContext, "NotoColorEmojiCompat.ttf");
         final Uri uri = Uri.fromFile(file);
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/HardDeleteTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/HardDeleteTest.java
index 614c6a9..cd6c449 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/HardDeleteTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/HardDeleteTest.java
@@ -41,7 +41,6 @@
 
 import androidx.emoji.util.TestString;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -51,7 +50,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class HardDeleteTest {
 
     private TestString mTestString;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java
index 07d9d36..cc24436 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java
@@ -25,7 +25,6 @@
 import androidx.annotation.NonNull;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Test;
@@ -52,7 +51,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testRegisterInitCallback_callsFailCallback() {
         final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
         final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
@@ -72,7 +70,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testRegisterInitCallback_callsFailCallback_whenOnFailCalledByLoader() {
         final EmojiCompat.InitCallback initCallback = mock(EmojiCompat.InitCallback.class);
         final EmojiCompat.MetadataRepoLoader loader = new EmojiCompat.MetadataRepoLoader() {
@@ -91,7 +88,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testRegisterInitCallback_callsFailCallback_whenMetadataRepoIsNull() {
         final EmojiCompat.InitCallback initCallback = mock(EmojiCompat.InitCallback.class);
         final EmojiCompat.MetadataRepoLoader loader = new EmojiCompat.MetadataRepoLoader() {
@@ -110,7 +106,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testUnregisterInitCallback_doesNotInteractWithCallback()
             throws InterruptedException {
         // will be registered
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/MetadataRepoTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/MetadataRepoTest.java
index 4be9a03..e992452 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/MetadataRepoTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/MetadataRepoTest.java
@@ -19,7 +19,6 @@
 import static org.junit.Assert.assertSame;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -28,7 +27,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class MetadataRepoTest {
 
     MetadataRepo mMetadataRepo;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/SoftDeleteTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/SoftDeleteTest.java
index 9676fc8..8f57c55 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/SoftDeleteTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/SoftDeleteTest.java
@@ -36,7 +36,6 @@
 import androidx.emoji.util.Emoji;
 import androidx.emoji.util.TestString;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -46,7 +45,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class SoftDeleteTest {
     private InputConnection mInputConnection;
     private TestString mTestString;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/UninitializedStateTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/UninitializedStateTest.java
index 9a3d61f..31b9f6a 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/UninitializedStateTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/UninitializedStateTest.java
@@ -16,7 +16,6 @@
 package androidx.emoji.text;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -26,7 +25,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class UninitializedStateTest {
 
     private TestConfigBuilder.WaitingDataLoader mWaitingDataLoader;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperPre19Test.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperPre19Test.java
deleted file mode 100644
index 8f5dd1e..0000000
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperPre19Test.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2017 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.emoji.widget;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import android.text.TextWatcher;
-import android.text.method.KeyListener;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.EditText;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@SdkSuppress(maxSdkVersion = 18)
-public class EmojiEditTextHelperPre19Test {
-    EmojiEditTextHelper mEmojiEditTextHelper;
-
-    @Before
-    public void setup() {
-        final EditText editText = mock(EditText.class);
-        mEmojiEditTextHelper = new EmojiEditTextHelper(editText);
-        verifyNoMoreInteractions(editText);
-    }
-
-    @Test
-    public void testGetKeyListener_returnsSameKeyListener() {
-        final KeyListener param = mock(KeyListener.class);
-        final KeyListener keyListener = mEmojiEditTextHelper.getKeyListener(
-                param);
-
-        assertSame(param, keyListener);
-    }
-
-    @LargeTest
-    @Test
-    public void testGetOnCreateInputConnection_returnsSameInputConnection() {
-        final InputConnection param = mock(InputConnection.class);
-        final InputConnection inputConnection = mEmojiEditTextHelper.onCreateInputConnection(param,
-                new EditorInfo());
-
-        assertSame(param, inputConnection);
-    }
-
-    @Test
-    public void testGetOnCreateInputConnection_withNullAttrs_returnsSameInputConnection() {
-        final InputConnection param = mock(InputConnection.class);
-        final InputConnection inputConnection = mEmojiEditTextHelper.onCreateInputConnection(param,
-                null);
-
-        assertSame(param, inputConnection);
-    }
-
-    @Test
-    public void testGetOnCreateInputConnection_withNullInputConnection_returnsNull() {
-        final InputConnection inputConnection = mEmojiEditTextHelper.onCreateInputConnection(null,
-                new EditorInfo());
-        assertNull(inputConnection);
-    }
-
-    @Test
-    public void testDoesNotAttachTextWatcher() {
-        final EditText editText = mock(EditText.class);
-
-        mEmojiEditTextHelper = new EmojiEditTextHelper(editText);
-
-        verify(editText, times(0)).addTextChangedListener(any(TextWatcher.class));
-    }
-
-}
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperTest.java
index 4ff0979..f97415a 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextHelperTest.java
@@ -36,7 +36,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -45,7 +44,6 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiEditTextHelperTest {
     EmojiEditTextHelper mEmojiEditTextHelper;
     EditText mEditText;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextTest.java
index 0ef6166..d0fa116 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiEditTextTest.java
@@ -88,7 +88,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void testSetMaxCount() {
         final TestActivity activity = mActivityRule.getActivity();
         final EmojiEditText editText = activity.findViewById(R.id.editTextWithMaxCount);
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiExtractTextLayoutTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiExtractTextLayoutTest.java
index 9f9f404..8a06827 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiExtractTextLayoutTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiExtractTextLayoutTest.java
@@ -43,7 +43,6 @@
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -125,7 +124,6 @@
 
     @Test
     @UiThreadTest
-    @SdkSuppress(minSdkVersion = 19)
     public void testSetEmojiReplaceStrategyCallEmojiCompatWithCorrectStrategy() {
         final Context context = ApplicationProvider.getApplicationContext();
 
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputConnectionTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputConnectionTest.java
index 51ad68c..e80826c 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputConnectionTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputConnectionTest.java
@@ -54,7 +54,6 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiInputConnectionTest {
 
     private InputConnection mInputConnection;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java
index 5130a65..f31b043 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java
@@ -134,7 +134,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     public void initCallback_doesntCrashWhenNotAttached() {
         Context context = InstrumentationRegistry.getInstrumentation().getContext();
         EditText editText = new EditText(context);
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiKeyListenerTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiKeyListenerTest.java
index 817e524..e17215f 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiKeyListenerTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiKeyListenerTest.java
@@ -49,7 +49,6 @@
 import androidx.emoji.text.TestConfigBuilder;
 import androidx.emoji.util.TestString;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -59,7 +58,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiKeyListenerTest {
 
     private KeyListener mKeyListener;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperPre19Test.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperPre19Test.java
deleted file mode 100644
index a1ec7ec..0000000
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperPre19Test.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 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.emoji.widget;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.mockito.Mockito.mock;
-
-import android.text.InputFilter;
-import android.text.method.TransformationMethod;
-import android.widget.TextView;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@SdkSuppress(maxSdkVersion = 18)
-public class EmojiTextViewHelperPre19Test {
-    EmojiTextViewHelper mTextViewHelper;
-    TextView mTextView;
-
-    @Before
-    public void setup() {
-        mTextView = new TextView(ApplicationProvider.getApplicationContext());
-        mTextViewHelper = new EmojiTextViewHelper(mTextView);
-    }
-
-    @Test
-    public void testUpdateTransformationMethod_doesNotUpdateTransformationMethod() {
-        final TransformationMethod tm = mock(TransformationMethod.class);
-        mTextView.setTransformationMethod(tm);
-
-        mTextViewHelper.updateTransformationMethod();
-
-        assertSame(tm, mTextView.getTransformationMethod());
-    }
-
-    @Test
-    public void testGetFilters_returnsSameFilters() {
-        final InputFilter existingFilter = mock(InputFilter.class);
-        final InputFilter[] filters = new InputFilter[]{existingFilter};
-
-        final InputFilter[] newFilters = mTextViewHelper.getFilters(filters);
-
-        assertSame(filters, newFilters);
-    }
-
-    @Test
-    public void testGetTransformationMethod_returnSameTransformationMethod() {
-        assertNull(mTextViewHelper.wrapTransformationMethod(null));
-
-        final TransformationMethod tm = mock(TransformationMethod.class);
-        assertSame(tm, mTextViewHelper.wrapTransformationMethod(tm));
-    }
-
-    @Test
-    public void testSetAllCaps_doesNotUpdateTransformationMethod() {
-        final TransformationMethod tm = mock(TransformationMethod.class);
-        mTextView.setTransformationMethod(tm);
-        mTextViewHelper.setAllCaps(true);
-        assertSame(tm, mTextView.getTransformationMethod());
-
-        mTextViewHelper.setAllCaps(false);
-        assertSame(tm, mTextView.getTransformationMethod());
-    }
-}
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperTest.java
index 70b4c36..248343e 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextViewHelperTest.java
@@ -32,7 +32,6 @@
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -43,7 +42,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiTextViewHelperTest {
     EmojiTextViewHelper mTextViewHelper;
     TextView mTextView;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java
index 54d8ae1..d2dfcef 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java
@@ -47,7 +47,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class EmojiTextWatcherTest {
 
     private EmojiTextWatcher mTextWatcher;
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java
index da9477f..50a8a75 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java
@@ -19,7 +19,6 @@
 
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -281,8 +280,7 @@
         if (config.mInitCallbacks != null && !config.mInitCallbacks.isEmpty()) {
             mInitCallbacks.addAll(config.mInitCallbacks);
         }
-        mHelper = Build.VERSION.SDK_INT < 19 ? new CompatInternal(this) : new CompatInternal19(
-                this);
+        mHelper = new CompatInternal(this);
         loadMetadata();
     }
 
@@ -532,11 +530,7 @@
      */
     public static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
             final KeyEvent event) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
-        } else {
-            return false;
-        }
+        return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
     }
 
     /**
@@ -561,12 +555,8 @@
             @NonNull final InputConnection inputConnection, @NonNull final Editable editable,
             @IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength,
             final boolean inCodePoints) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable,
-                    beforeLength, afterLength, inCodePoints);
-        } else {
-            return false;
-        }
+        return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable,
+                beforeLength, afterLength, inCodePoints);
     }
 
     /**
@@ -1201,49 +1191,7 @@
         }
     }
 
-    /**
-     * Internal helper class to behave no-op for certain functions.
-     */
-    private static class CompatInternal {
-        final EmojiCompat mEmojiCompat;
-
-        CompatInternal(EmojiCompat emojiCompat) {
-            mEmojiCompat = emojiCompat;
-        }
-
-        void loadMetadata() {
-            // Moves into LOAD_STATE_SUCCESS state immediately.
-            mEmojiCompat.onMetadataLoadSuccess();
-        }
-
-        boolean hasEmojiGlyph(@NonNull final CharSequence sequence) {
-            // Since no metadata is loaded, EmojiCompat cannot detect or render any emojis.
-            return false;
-        }
-
-        boolean hasEmojiGlyph(@NonNull final CharSequence sequence, final int metadataVersion) {
-            // Since no metadata is loaded, EmojiCompat cannot detect or render any emojis.
-            return false;
-        }
-
-        CharSequence process(@NonNull final CharSequence charSequence,
-                @IntRange(from = 0) final int start, @IntRange(from = 0) final int end,
-                @IntRange(from = 0) final int maxEmojiCount, boolean replaceAll) {
-            // Returns the given charSequence as it is.
-            return charSequence;
-        }
-
-        void updateEditorInfoAttrs(@NonNull final EditorInfo outAttrs) {
-            // Does not add any EditorInfo attributes.
-        }
-
-        String getAssetSignature() {
-            return "";
-        }
-    }
-
-    @RequiresApi(19)
-    private static final class CompatInternal19 extends CompatInternal {
+    private static final class CompatInternal {
         /**
          * Responsible to process a CharSequence and add the spans. @{code Null} until the time the
          * metadata is loaded.
@@ -1254,13 +1202,13 @@
          * Keeps the information about emojis. Null until the time the data is loaded.
          */
         private volatile MetadataRepo mMetadataRepo;
+        final EmojiCompat mEmojiCompat;
 
 
-        CompatInternal19(EmojiCompat emojiCompat) {
-            super(emojiCompat);
+        CompatInternal(EmojiCompat emojiCompat) {
+            mEmojiCompat = emojiCompat;
         }
 
-        @Override
         void loadMetadata() {
             try {
                 final MetadataRepoLoaderCallback callback = new MetadataRepoLoaderCallback() {
@@ -1299,30 +1247,25 @@
             mEmojiCompat.onMetadataLoadSuccess();
         }
 
-        @Override
         boolean hasEmojiGlyph(@NonNull CharSequence sequence) {
             return mProcessor.getEmojiMetadata(sequence) != null;
         }
 
-        @Override
         boolean hasEmojiGlyph(@NonNull CharSequence sequence, int metadataVersion) {
             final EmojiMetadata emojiMetadata = mProcessor.getEmojiMetadata(sequence);
             return emojiMetadata != null && emojiMetadata.getCompatAdded() <= metadataVersion;
         }
 
-        @Override
         CharSequence process(@NonNull CharSequence charSequence, int start, int end,
                 int maxEmojiCount, boolean replaceAll) {
             return mProcessor.process(charSequence, start, end, maxEmojiCount, replaceAll);
         }
 
-        @Override
         void updateEditorInfoAttrs(@NonNull EditorInfo outAttrs) {
             outAttrs.extras.putInt(EDITOR_INFO_METAVERSION_KEY, mMetadataRepo.getMetadataVersion());
             outAttrs.extras.putBoolean(EDITOR_INFO_REPLACE_ALL_KEY, mEmojiCompat.mReplaceAll);
         }
 
-        @Override
         String getAssetSignature() {
             final String sha = mMetadataRepo.getMetadataList().sourceSha();
             return sha == null ? "" : sha;
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java
index 824c1c9..2f621ee 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java
@@ -17,7 +17,6 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
-import android.os.Build;
 import android.text.method.KeyListener;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
@@ -81,8 +80,7 @@
      */
     public EmojiEditTextHelper(@NonNull final EditText editText) {
         Preconditions.checkNotNull(editText, "editText cannot be null");
-        mHelper = Build.VERSION.SDK_INT >= 19 ? new HelperInternal19(editText)
-                : new HelperInternal();
+        mHelper = new HelperInternal19(editText);
     }
 
     /**
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java
index 40030f9..d061388 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java
@@ -15,7 +15,6 @@
  */
 package androidx.emoji.widget;
 
-import android.os.Build;
 import android.text.InputFilter;
 import android.text.method.PasswordTransformationMethod;
 import android.text.method.TransformationMethod;
@@ -23,7 +22,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.core.util.Preconditions;
 import androidx.emoji.text.EmojiCompat;
 
@@ -71,8 +69,7 @@
      */
     public EmojiTextViewHelper(@NonNull TextView textView) {
         Preconditions.checkNotNull(textView, "textView cannot be null");
-        mHelper = Build.VERSION.SDK_INT >= 19 ? new HelperInternal19(textView)
-                : new HelperInternal();
+        mHelper = new HelperInternal(textView);
     }
 
     /**
@@ -124,37 +121,15 @@
         mHelper.setAllCaps(allCaps);
     }
 
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    static class HelperInternal {
-
-        void updateTransformationMethod() {
-            // do nothing
-        }
-
-        InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
-            return filters;
-        }
-
-        TransformationMethod wrapTransformationMethod(TransformationMethod transformationMethod) {
-            return transformationMethod;
-        }
-
-        void setAllCaps(boolean allCaps) {
-            // do nothing
-        }
-    }
-
-    @RequiresApi(19)
-    private static class HelperInternal19 extends HelperInternal {
+    private static class HelperInternal {
         private final TextView mTextView;
         private final EmojiInputFilter mEmojiInputFilter;
 
-        HelperInternal19(TextView textView) {
+        HelperInternal(TextView textView) {
             mTextView = textView;
             mEmojiInputFilter = new EmojiInputFilter(textView);
         }
 
-        @Override
         void updateTransformationMethod() {
             final TransformationMethod tm = mTextView.getTransformationMethod();
             if (tm != null && !(tm instanceof PasswordTransformationMethod)) {
@@ -162,7 +137,6 @@
             }
         }
 
-        @Override
         InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
             final int count = filters.length;
             for (int i = 0; i < count; i++) {
@@ -176,7 +150,6 @@
             return newFilters;
         }
 
-        @Override
         TransformationMethod wrapTransformationMethod(TransformationMethod transformationMethod) {
             if (transformationMethod instanceof EmojiTransformationMethod) {
                 return transformationMethod;
@@ -184,7 +157,6 @@
             return new EmojiTransformationMethod(transformationMethod);
         }
 
-        @Override
         void setAllCaps(boolean allCaps) {
             // When allCaps is set to false TextView sets the transformation method to be null. We
             // are only interested when allCaps is set to true in order to wrap the original method.
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml
index 985e0cd..251972d 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml
@@ -21,7 +21,7 @@
     <string name="emoji_category_emotions" msgid="1570830970240985537">"EMOTICONES I EMOCIONS"</string>
     <string name="emoji_category_people" msgid="7968173366822927025">"PERSONES"</string>
     <string name="emoji_category_animals_nature" msgid="4640771324837307541">"ANIMALS I NATURALESA"</string>
-    <string name="emoji_category_food_drink" msgid="1189971856721244395">"MENJAR I BEGUDES"</string>
+    <string name="emoji_category_food_drink" msgid="1189971856721244395">"MENJAR I BEGUDA"</string>
     <string name="emoji_category_travel_places" msgid="8105712773237012672">"VIATGES I LLOCS"</string>
     <string name="emoji_category_activity" msgid="4381135114947330911">"ACTIVITATS I ESDEVENIMENTS"</string>
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTES"</string>
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiEditableFactoryTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiEditableFactoryTest.java
index ffa1803..df55f27 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiEditableFactoryTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiEditableFactoryTest.java
@@ -24,12 +24,10 @@
 import static org.mockito.Mockito.mock;
 
 import android.annotation.SuppressLint;
-import android.os.Build;
 import android.text.Editable;
 import android.text.SpannableString;
 import android.text.Spanned;
 
-import androidx.annotation.RequiresApi;
 import androidx.emoji2.text.EmojiSpan;
 import androidx.emoji2.text.SpannableBuilder;
 import androidx.emoji2.text.TypefaceEmojiRasterizer;
@@ -60,7 +58,6 @@
         assertThat(editable, instanceOf(Editable.class));
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     @Test
     public void testNewEditable_preservesCharSequenceData() {
         final String string = "abc";
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTransformationMethodTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTransformationMethodTest.java
index 71dfe18..b8e13b7 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTransformationMethodTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTransformationMethodTest.java
@@ -30,14 +30,12 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.os.Build;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.TextUtils;
 import android.text.method.TransformationMethod;
 import android.view.View;
 
-import androidx.annotation.RequiresApi;
 import androidx.emoji2.text.EmojiCompat;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -49,7 +47,6 @@
 import org.mockito.stubbing.Answer;
 
 @SmallTest
-@RequiresApi(api = Build.VERSION_CODES.KITKAT)
 @RunWith(AndroidJUnit4.class)
 public class EmojiTransformationMethodTest {
 
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiEditTextHelper.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiEditTextHelper.java
index de5847c..c41335f 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiEditTextHelper.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiEditTextHelper.java
@@ -15,7 +15,6 @@
  */
 package androidx.emoji2.viewsintegration;
 
-import android.os.Build;
 import android.text.method.KeyListener;
 import android.text.method.NumberKeyListener;
 import android.view.inputmethod.EditorInfo;
@@ -104,11 +103,7 @@
     public EmojiEditTextHelper(@NonNull EditText editText,
             boolean expectInitializedEmojiCompat) {
         Preconditions.checkNotNull(editText, "editText cannot be null");
-        if (Build.VERSION.SDK_INT < 19) {
-            mHelper = new HelperInternal();
-        } else {
-            mHelper = new HelperInternal19(editText, expectInitializedEmojiCompat);
-        }
+        mHelper = new HelperInternal19(editText, expectInitializedEmojiCompat);
     }
 
     /**
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextViewHelper.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextViewHelper.java
index 7748ba2..6ac961b 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextViewHelper.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextViewHelper.java
@@ -15,7 +15,6 @@
  */
 package androidx.emoji2.viewsintegration;
 
-import android.os.Build;
 import android.text.InputFilter;
 import android.text.method.PasswordTransformationMethod;
 import android.text.method.TransformationMethod;
@@ -95,9 +94,7 @@
      */
     public EmojiTextViewHelper(@NonNull TextView textView, boolean expectInitializedEmojiCompat) {
         Preconditions.checkNotNull(textView, "textView cannot be null");
-        if (Build.VERSION.SDK_INT < 19) {
-            mHelper = new HelperInternal();
-        } else if (!expectInitializedEmojiCompat) {
+        if (!expectInitializedEmojiCompat) {
             mHelper = new SkippingHelper19(textView);
         } else {
             mHelper = new HelperInternal19(textView);
diff --git a/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/DefaultEmojiCompatConfigTest.java b/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/DefaultEmojiCompatConfigTest.java
index eda1b9d..bb4ecd2 100644
--- a/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/DefaultEmojiCompatConfigTest.java
+++ b/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/DefaultEmojiCompatConfigTest.java
@@ -72,9 +72,6 @@
 
     @SuppressWarnings("deprecation")
     private boolean providerOnSystem() {
-        if (Build.VERSION.SDK_INT < 19) {
-            return false;
-        }
         List<ResolveInfo> result = ApplicationProvider.getApplicationContext()
                 .getPackageManager().queryIntentContentProviders(generateIntent(), 0);
         for (ResolveInfo resolveInfo : result) {
@@ -218,12 +215,9 @@
         Object result = reflectHelper.get(factory);
         int apiVersion = Build.VERSION.SDK_INT;
         Class<?> helperClass = Objects.requireNonNull(result).getClass();
-        if (apiVersion < 19) {
+        if (apiVersion < 28) {
             assertEquals(DefaultEmojiCompatConfig.DefaultEmojiCompatConfigHelper.class,
                     helperClass);
-        } else if (apiVersion < 28) {
-            assertEquals(DefaultEmojiCompatConfig.DefaultEmojiCompatConfigHelper_API19.class,
-                    helperClass);
         } else {
             assertEquals(DefaultEmojiCompatConfig.DefaultEmojiCompatConfigHelper_API28.class,
                     helperClass);
diff --git a/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/NoFontTestEmojiConfig.java b/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/NoFontTestEmojiConfig.java
index 648f1bd..812a223 100644
--- a/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/NoFontTestEmojiConfig.java
+++ b/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/NoFontTestEmojiConfig.java
@@ -19,12 +19,9 @@
 import static org.mockito.Mockito.mock;
 
 import android.graphics.Typeface;
-import android.os.Build;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 
-@RequiresApi(api = Build.VERSION_CODES.KITKAT)
 public class NoFontTestEmojiConfig extends EmojiCompat.Config {
 
     static EmojiCompat.Config emptyConfig() {
diff --git a/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/SpannableBuilderTest.java b/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/SpannableBuilderTest.java
index d0ba42d..3e7d8ca 100644
--- a/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/SpannableBuilderTest.java
+++ b/emoji2/emoji2/src/androidTest/java/androidx/emoji2/text/SpannableBuilderTest.java
@@ -35,7 +35,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.withSettings;
 
-import android.os.Build;
 import android.text.DynamicLayout;
 import android.text.Editable;
 import android.text.Layout;
@@ -46,7 +45,6 @@
 import android.text.style.QuoteSpan;
 import android.text.style.TypefaceSpan;
 
-import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SdkSuppress;
@@ -127,7 +125,6 @@
         assertEquals(1, start);
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     @Test
     public void testBlocksSpanCallbacks_forEmojiSpans() {
         final EmojiSpan span = mock(EmojiSpan.class);
@@ -189,7 +186,6 @@
         verify(mWatcher, times(1)).afterTextChanged(any(Editable.class));
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     @Test
     public void testDoesNotBlockSpanCallbacksForOtherWatchers() {
         final TextWatcher textWatcher = mock(TextWatcher.class);
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/DefaultEmojiCompatConfig.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/DefaultEmojiCompatConfig.java
index f9ca103..c0bb50e 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/DefaultEmojiCompatConfig.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/DefaultEmojiCompatConfig.java
@@ -241,8 +241,6 @@
         private static DefaultEmojiCompatConfigHelper getHelperForApi() {
             if (Build.VERSION.SDK_INT >= 28) {
                 return new DefaultEmojiCompatConfigHelper_API28();
-            } else if (Build.VERSION.SDK_INT >= 19) {
-                return new DefaultEmojiCompatConfigHelper_API19();
             } else {
                 return new DefaultEmojiCompatConfigHelper();
             }
@@ -250,30 +248,17 @@
     }
 
     /**
-     * Helper to lookup signatures in package manager.
-     *
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     public static class DefaultEmojiCompatConfigHelper {
         /**
-         * Get the signing signatures for a package in package manager.
-         */
-        @SuppressWarnings("deprecation") // replaced in API 28
-        @NonNull
-        public Signature[] getSigningSignatures(@NonNull PackageManager packageManager,
-                @NonNull String providerPackage) throws PackageManager.NameNotFoundException {
-            PackageInfo packageInfoForSignatures = packageManager.getPackageInfo(providerPackage,
-                    PackageManager.GET_SIGNATURES);
-            return packageInfoForSignatures.signatures;
-        }
-
-        /**
          * Get the content provider by intent.
          */
         @NonNull
+        @SuppressWarnings("deprecation")
         public List<ResolveInfo> queryIntentContentProviders(@NonNull PackageManager packageManager,
                 @NonNull Intent intent, int flags) {
-            return Collections.emptyList();
+            return packageManager.queryIntentContentProviders(intent, flags);
         }
 
         /**
@@ -283,31 +268,20 @@
          */
         @Nullable
         public ProviderInfo getProviderInfo(@NonNull ResolveInfo resolveInfo) {
-            throw new IllegalStateException("Unable to get provider info prior to API 19");
-        }
-    }
-
-    /**
-     * Actually do lookups > API 19
-     *
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    @RequiresApi(19)
-    public static class DefaultEmojiCompatConfigHelper_API19
-            extends DefaultEmojiCompatConfigHelper {
-        @NonNull
-        @Override
-        @SuppressWarnings("deprecation")
-        public List<ResolveInfo> queryIntentContentProviders(@NonNull PackageManager packageManager,
-                @NonNull Intent intent, int flags) {
-            return packageManager.queryIntentContentProviders(intent, flags);
-        }
-
-        @Nullable
-        @Override
-        public ProviderInfo getProviderInfo(@NonNull ResolveInfo resolveInfo) {
             return resolveInfo.providerInfo;
         }
+
+        /**
+         * Get the signing signatures for a package in package manager.
+         */
+        @SuppressWarnings("deprecation") // using deprecated API to match exact behavior in core
+        @NonNull
+        public Signature[] getSigningSignatures(@NonNull PackageManager packageManager,
+                @NonNull String providerPackage) throws PackageManager.NameNotFoundException {
+            PackageInfo packageInfoForSignatures = packageManager.getPackageInfo(providerPackage,
+                    PackageManager.GET_SIGNATURES);
+            return packageInfoForSignatures.signatures;
+        }
     }
 
     /**
@@ -316,7 +290,7 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @RequiresApi(28)
     public static class DefaultEmojiCompatConfigHelper_API28
-            extends DefaultEmojiCompatConfigHelper_API19 {
+            extends DefaultEmojiCompatConfigHelper {
         @SuppressWarnings("deprecation") // using deprecated API to match exact behavior in core
         @Override
         @NonNull
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java
index 3f6f2af..1755b2d 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompat.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.os.Build;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.method.KeyListener;
@@ -463,8 +462,7 @@
         if (config.mInitCallbacks != null && !config.mInitCallbacks.isEmpty()) {
             mInitCallbacks.addAll(config.mInitCallbacks);
         }
-        mHelper = Build.VERSION.SDK_INT < 19 ? new CompatInternal(this) : new CompatInternal19(
-                this);
+        mHelper = new CompatInternal(this);
         loadMetadata();
     }
 
@@ -889,11 +887,7 @@
      */
     public static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
             @NonNull final KeyEvent event) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
-        } else {
-            return false;
-        }
+        return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
     }
 
     /**
@@ -918,12 +912,8 @@
             @NonNull final InputConnection inputConnection, @NonNull final Editable editable,
             @IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength,
             final boolean inCodePoints) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable,
-                    beforeLength, afterLength, inCodePoints);
-        } else {
-            return false;
-        }
+        return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable,
+                beforeLength, afterLength, inCodePoints);
     }
 
     /**
@@ -1646,64 +1636,7 @@
         }
     }
 
-    /**
-     * Internal helper class to behave no-op for certain functions.
-     */
-    private static class CompatInternal {
-        final EmojiCompat mEmojiCompat;
-
-        CompatInternal(EmojiCompat emojiCompat) {
-            mEmojiCompat = emojiCompat;
-        }
-
-        void loadMetadata() {
-            // Moves into LOAD_STATE_SUCCESS state immediately.
-            mEmojiCompat.onMetadataLoadSuccess();
-        }
-
-        boolean hasEmojiGlyph(@NonNull final CharSequence sequence) {
-            // Since no metadata is loaded, EmojiCompat cannot detect or render any emojis.
-            return false;
-        }
-
-        boolean hasEmojiGlyph(@NonNull final CharSequence sequence, final int metadataVersion) {
-            // Since no metadata is loaded, EmojiCompat cannot detect or render any emojis.
-            return false;
-        }
-
-        int getEmojiStart(@NonNull final CharSequence cs, @IntRange(from = 0) final int offset) {
-            // Since no metadata is loaded, EmojiCompat cannot detect any emojis.
-            return -1;
-        }
-
-        int getEmojiEnd(@NonNull final CharSequence cs, @IntRange(from = 0) final int offset) {
-            // Since no metadata is loaded, EmojiCompat cannot detect any emojis.
-            return -1;
-        }
-
-        CharSequence process(@NonNull final CharSequence charSequence,
-                @IntRange(from = 0) final int start, @IntRange(from = 0) final int end,
-                @IntRange(from = 0) final int maxEmojiCount, boolean replaceAll) {
-            // Returns the given charSequence as it is.
-            return charSequence;
-        }
-
-        void updateEditorInfoAttrs(@NonNull final EditorInfo outAttrs) {
-            // Does not add any EditorInfo attributes.
-        }
-
-        String getAssetSignature() {
-            return "";
-        }
-
-        @CodepointSequenceMatchResult
-        public int getEmojiMatch(CharSequence sequence, int metadataVersion) {
-            return EMOJI_UNSUPPORTED;
-        }
-    }
-
-    @RequiresApi(19)
-    private static final class CompatInternal19 extends CompatInternal {
+    private static final class CompatInternal {
         /**
          * Responsible to process a CharSequence and add the spans. @{code Null} until the time the
          * metadata is loaded.
@@ -1714,13 +1647,12 @@
          * Keeps the information about emojis. Null until the time the data is loaded.
          */
         private volatile MetadataRepo mMetadataRepo;
+        private final EmojiCompat mEmojiCompat;
 
-
-        CompatInternal19(EmojiCompat emojiCompat) {
-            super(emojiCompat);
+        CompatInternal(EmojiCompat emojiCompat) {
+            mEmojiCompat = emojiCompat;
         }
 
-        @Override
         void loadMetadata() {
             try {
                 final MetadataRepoLoaderCallback callback = new MetadataRepoLoaderCallback() {
@@ -1761,45 +1693,37 @@
             mEmojiCompat.onMetadataLoadSuccess();
         }
 
-        @Override
         boolean hasEmojiGlyph(@NonNull CharSequence sequence) {
             return mProcessor.getEmojiMatch(sequence) == EMOJI_SUPPORTED;
         }
 
-        @Override
         boolean hasEmojiGlyph(@NonNull CharSequence sequence, int metadataVersion) {
             int emojiMatch = mProcessor.getEmojiMatch(sequence, metadataVersion);
             return emojiMatch == EMOJI_SUPPORTED;
         }
 
-        @Override
         public int getEmojiMatch(CharSequence sequence, int metadataVersion) {
             return mProcessor.getEmojiMatch(sequence, metadataVersion);
         }
 
-        @Override
         int getEmojiStart(@NonNull final CharSequence sequence, final int offset) {
             return mProcessor.getEmojiStart(sequence, offset);
         }
 
-        @Override
         int getEmojiEnd(@NonNull final CharSequence sequence, final int offset) {
             return mProcessor.getEmojiEnd(sequence, offset);
         }
 
-        @Override
         CharSequence process(@NonNull CharSequence charSequence, int start, int end,
                 int maxEmojiCount, boolean replaceAll) {
             return mProcessor.process(charSequence, start, end, maxEmojiCount, replaceAll);
         }
 
-        @Override
         void updateEditorInfoAttrs(@NonNull EditorInfo outAttrs) {
             outAttrs.extras.putInt(EDITOR_INFO_METAVERSION_KEY, mMetadataRepo.getMetadataVersion());
             outAttrs.extras.putBoolean(EDITOR_INFO_REPLACE_ALL_KEY, mEmojiCompat.mReplaceAll);
         }
 
-        @Override
         String getAssetSignature() {
             final String sha = mMetadataRepo.getMetadataList().sourceSha();
             return sha == null ? "" : sha;
diff --git a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java
index f4823bf..fb3f8f0 100644
--- a/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java
+++ b/emoji2/emoji2/src/main/java/androidx/emoji2/text/EmojiCompatInitializer.java
@@ -17,7 +17,6 @@
 package androidx.emoji2.text;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Handler;
 
 import androidx.annotation.NonNull;
@@ -84,12 +83,9 @@
     @NonNull
     @Override
     public Boolean create(@NonNull Context context) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            EmojiCompat.init(new BackgroundDefaultConfig(context));
-            delayUntilFirstResume(context);
-            return true;
-        }
-        return false;
+        EmojiCompat.init(new BackgroundDefaultConfig(context));
+        delayUntilFirstResume(context);
+        return true;
     }
 
     /**
diff --git a/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java b/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java
index ca2a19f..4381628 100644
--- a/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java
+++ b/exifinterface/exifinterface/src/androidTest/java/androidx/exifinterface/media/ExifInterfaceTest.java
@@ -50,7 +50,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -1443,10 +1442,6 @@
      * <p>This does not check the image itself for similarity/equality.
      */
     private void assertBitmapsEquivalent(File expectedImageFile, File actualImageFile) {
-        if (Build.VERSION.SDK_INT < 16 && expectedImageFile.getName().endsWith("webp")) {
-            // BitmapFactory can't parse WebP files on API levels before 16: b/254571189
-            return;
-        }
         if (Build.VERSION.SDK_INT < 26
                 && expectedImageFile.getName().equals(WEBP_WITHOUT_EXIF_WITH_ANIM_DATA)) {
             // BitmapFactory can't parse animated WebP files on API levels before 26: b/259964971
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
index 7ca4c07..61da32d 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
@@ -411,7 +411,6 @@
 
     // Ensure that removing and popping a Fragment uses the exit and popEnter animators,
     // but the animators are delayed when an entering Fragment is postponed.
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
     @Test
     fun postponedRemoveAnimators() {
         val fm = activityRule.activity.supportFragmentManager
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
index 3e65793..cb52138 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
@@ -103,7 +103,6 @@
         assertThat(childFrag).isNotNull()
     }
 
-    @SdkSuppress(minSdkVersion = 18) // androidx.transition needs setLayoutTransition for API < 18
     @Test
     fun setLayoutTransitionUnsupported() {
         val activity = activityRule.activity
@@ -122,20 +121,6 @@
         }
     }
 
-    @SdkSuppress(maxSdkVersion = 17) // androidx.transition needs setLayoutTransition for API < 18
-    @Test
-    fun setLayoutTransitionAllowed() {
-        val emptyLayoutTransition = LayoutTransition()
-        emptyLayoutTransition.setAnimator(LayoutTransition.APPEARING, null)
-        emptyLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, null)
-        emptyLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null)
-        emptyLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, null)
-        emptyLayoutTransition.setAnimator(4 /*LayoutTransition.Changing*/, null)
-
-        val containerView = FragmentContainerView(context)
-        containerView.layoutTransition = emptyLayoutTransition
-    }
-
     // If view sets animateLayoutChanges to true, throw UnsupportedOperationException
     @Test
     fun animateLayoutChangesTrueUnsupported() {
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTest.kt
index 2313a6f..7d34ca7 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTest.kt
@@ -26,7 +26,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.testutils.waitForExecution
@@ -101,7 +100,6 @@
 
     @LargeTest
     @Test
-    @SdkSuppress(minSdkVersion = 16) // waitForHalfFadeIn requires API 16
     fun testChildFragmentManagerGone() {
         val activity = activityRule.activity
         val fragmentA = FragmentA()
@@ -146,7 +144,6 @@
 
     @LargeTest
     @Test
-    @SdkSuppress(minSdkVersion = 16) // waitForHalfFadeIn requires API 16
     fun testRemoveUnrelatedDuringAnimation() {
         val activity = activityRule.activity
         val unrelatedFragment = StrictFragment()
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
index dad6a69..fa5874e 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
@@ -30,7 +30,6 @@
 import android.content.IntentSender;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -67,7 +66,6 @@
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.StringRes;
 import androidx.annotation.UiThread;
@@ -3083,19 +3081,17 @@
         mChildFragmentManager.noteStateNotSaved();
         mState = CREATED;
         mCalled = false;
-        if (Build.VERSION.SDK_INT >= 19) {
-            mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
-                @Override
-                public void onStateChanged(@NonNull LifecycleOwner source,
-                        @NonNull Lifecycle.Event event) {
-                    if (event == Lifecycle.Event.ON_STOP) {
-                        if (mView != null) {
-                            Api19Impl.cancelPendingInputEvents(mView);
-                        }
+        mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
+            @Override
+            public void onStateChanged(@NonNull LifecycleOwner source,
+                    @NonNull Lifecycle.Event event) {
+                if (event == Lifecycle.Event.ON_STOP) {
+                    if (mView != null) {
+                        mView.cancelPendingInputEvents();
                     }
                 }
-            });
-        }
+            }
+        });
         onCreate(savedInstanceState);
         mIsCreated = true;
         if (!mCalled) {
@@ -3713,13 +3709,4 @@
         // hasn't been called yet.
         boolean mEnterTransitionPostponed;
     }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() { }
-
-        static void cancelPendingInputEvents(@NonNull View view) {
-            view.cancelPendingInputEvents();
-        }
-    }
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
index 43f6429..e9dd1a8 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
@@ -18,7 +18,6 @@
 import android.animation.LayoutTransition
 import android.content.Context
 import android.graphics.Canvas
-import android.os.Build
 import android.util.AttributeSet
 import android.view.View
 import android.view.ViewGroup
@@ -178,13 +177,6 @@
      * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges
      */
     public override fun setLayoutTransition(transition: LayoutTransition?) {
-        if (Build.VERSION.SDK_INT < 18) {
-            // Transitions on APIs below 18 are using an empty LayoutTransition as a replacement
-            // for suppressLayout(true) and null LayoutTransition to then unsuppress it. If the
-            // API is below 18, we should allow FrameLayout to handle this call.
-            super.setLayoutTransition(transition)
-            return
-        }
         throw UnsupportedOperationException(
             "FragmentContainerView does not support Layout Transitions or " +
                 "animateLayoutChanges=\"true\"."
diff --git a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetManagerTest.kt b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetManagerTest.kt
index 1181f98..190983d 100644
--- a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetManagerTest.kt
+++ b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetManagerTest.kt
@@ -20,10 +20,8 @@
 import androidx.glance.text.Text
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
-import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
 import androidx.test.uiautomator.UiSelector
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -32,7 +30,6 @@
 import org.junit.Rule
 import org.junit.Test
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SdkSuppress(minSdkVersion = 29)
 @MediumTest
 class GlanceAppWidgetManagerTest {
@@ -47,45 +44,53 @@
 
     @After
     fun tearDown() {
-        getInstrumentation().context.startActivity(Intent(Intent.ACTION_MAIN).apply {
+        context.startActivity(Intent(Intent.ACTION_MAIN).apply {
             addCategory(Intent.CATEGORY_HOME)
             flags = Intent.FLAG_ACTIVITY_NEW_TASK
         })
     }
 
     @Test
-    fun noAppWidget() {
-        mHostRule.onHostActivity { activity ->
-            val manager = GlanceAppWidgetManager(activity)
-            runBlocking {
-                assertThat(manager.getGlanceIds(TestGlanceAppWidget::class.java)).isEmpty()
-            }
-        }
+    fun noAppWidget() = runBlocking {
+        val manager = GlanceAppWidgetManager(context)
+
+        assertThat(manager.getGlanceIds(TestGlanceAppWidget::class.java)).isEmpty()
     }
 
     @Test
-    fun withAppWidget() {
+    fun withAppWidget() = runBlocking {
         TestGlanceAppWidget.uiDefinition = {
             Text("Something")
         }
+        val manager = GlanceAppWidgetManager(context)
+
+        suspend fun verifyGlanceIdsAndSizes() {
+            val glanceIds = manager.getGlanceIds(TestGlanceAppWidget::class.java)
+            assertThat(glanceIds).hasSize(1)
+            assertThat(manager.listKnownReceivers()).containsExactly(
+                TestGlanceAppWidgetReceiver::class.java.canonicalName
+            )
+
+            val glanceId = manager.getGlanceIdBy((glanceIds[0] as AppWidgetId).appWidgetId)
+            assertThat(glanceId).isEqualTo(glanceIds[0])
+
+            val sizes = manager.getAppWidgetSizes(glanceIds[0])
+            assertThat(sizes).containsExactly(
+                mHostRule.portraitSize,
+                mHostRule.landscapeSize
+            )
+        }
 
         mHostRule.startHost()
 
-        mHostRule.onHostActivity { activity ->
-            val manager = GlanceAppWidgetManager(activity)
+        verifyGlanceIdsAndSizes()
 
-            runBlocking {
-                val glanceIds = manager.getGlanceIds(TestGlanceAppWidget::class.java)
-                assertThat(glanceIds).hasSize(1)
-                val glanceId = manager.getGlanceIdBy((glanceIds[0] as AppWidgetId).appWidgetId)
-                assertThat(glanceId).isEqualTo(glanceIds[0])
-                val sizes = manager.getAppWidgetSizes(glanceIds[0])
-                assertThat(sizes).containsExactly(
-                    mHostRule.portraitSize,
-                    mHostRule.landscapeSize
-                )
-            }
-        }
+        // using "pm clear <package>" is not suitable here - it will crash process.
+        // See https://github.com/android/testing-samples/issues/98
+        // So, we clear datastore to mimic clearing appData.
+        manager.clearDataStore()
+
+        verifyGlanceIdsAndSizes()
     }
 
     @Test
@@ -99,6 +104,7 @@
             TestGlanceAppWidgetReceiver::class.java,
             preview = TestGlanceAppWidget
         )
+
         assertThat(result).isTrue()
         mHostRule.onHostActivity {
             assertThat(mHostRule.device.findObject(UiSelector().text(text)).exists())
@@ -110,28 +116,27 @@
         val result = GlanceAppWidgetManager(context).requestPinGlanceAppWidget(
             DummyGlanceAppWidgetReceiver::class.java,
         )
+
         assertThat(result).isFalse()
     }
 
     @Ignore("b/285198114")
     @Test
-    fun cleanReceivers() {
-        mHostRule.onHostActivity { activity ->
-            val manager = GlanceAppWidgetManager(activity)
+    fun cleanReceivers() = runBlocking<Unit> {
+        val manager = GlanceAppWidgetManager(context)
 
-            runBlocking {
-                manager.updateReceiver(DummyGlanceAppWidgetReceiver(), TestGlanceAppWidget)
-                assertThat(manager.listKnownReceivers()).containsExactly(
-                    DummyGlanceAppWidgetReceiver::class.java.canonicalName,
-                    TestGlanceAppWidgetReceiver::class.java.canonicalName
-                )
+        manager.updateReceiver(DummyGlanceAppWidgetReceiver(), TestGlanceAppWidget)
 
-                manager.cleanReceivers()
-                assertThat(manager.listKnownReceivers()).containsExactly(
-                    TestGlanceAppWidgetReceiver::class.java.canonicalName
-                )
-            }
-        }
+        assertThat(manager.listKnownReceivers()).containsExactly(
+            DummyGlanceAppWidgetReceiver::class.java.canonicalName,
+            TestGlanceAppWidgetReceiver::class.java.canonicalName
+        )
+
+        manager.cleanReceivers()
+
+        assertThat(manager.listKnownReceivers()).containsExactly(
+            TestGlanceAppWidgetReceiver::class.java.canonicalName
+        )
     }
 }
 
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/AppWidgetSession.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/AppWidgetSession.kt
index fdc700d..09be273 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/AppWidgetSession.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/AppWidgetSession.kt
@@ -45,7 +45,8 @@
 import androidx.glance.state.GlanceState
 import androidx.glance.state.GlanceStateDefinition
 import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.CompletableJob
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
 
 /**
@@ -100,6 +101,7 @@
     private var glanceState by mutableStateOf(initialGlanceState, neverEqualPolicy())
     private var options by mutableStateOf(initialOptions, neverEqualPolicy())
     private var lambdas = mapOf<String, List<LambdaAction>>()
+    private val parentJob = Job()
 
     internal val lastRemoteViews = MutableStateFlow<RemoteViews?>(null)
 
@@ -226,7 +228,9 @@
                     lambdas[event.key]?.forEach { it.block() }
                 } ?: Log.w(TAG, "Triggering Action(${event.key}) for session($key) failed")
             }
-            is WaitForReady -> event.resume.send(Unit)
+            is WaitForReady -> {
+                event.job.apply { if (isActive) complete() }
+            }
             else -> {
                 throw IllegalArgumentException(
                     "Sent unrecognized event type ${event.javaClass} to AppWidgetSession"
@@ -235,6 +239,16 @@
         }
     }
 
+    override fun onClosed() {
+        // Normally when we are closed, any pending events are processed before the channel is
+        // shutdown. However, it is possible that the Worker for this session will die before
+        // processing the remaining events. So when this session is closed, we will immediately
+        // resume all waiters without waiting for their events to be processed. If the Worker lives
+        // long enough to process their events, it will have no effect because their Jobs are no
+        // longer active.
+        parentJob.cancel()
+    }
+
     suspend fun updateGlance() {
         sendEvent(UpdateGlanceState)
     }
@@ -247,11 +261,17 @@
         sendEvent(RunLambda(key))
     }
 
-    suspend fun waitForReady() {
-        WaitForReady().let {
-            sendEvent(it)
-            it.resume.receive()
-        }
+    /**
+     * Returns a Job that can be used to wait until the session is ready (i.e. has finished
+     * processEmittableTree for the first time and is now receiving events). You can wait on the
+     * session to be ready by calling [Job.join] on the returned [Job]. When the session is ready,
+     * join will resume successfully (Job is completed). If the session is closed before it is
+     * ready, we call [Job.cancel] and the call to join resumes with [CancellationException].
+     */
+    suspend fun waitForReady(): Job {
+        val event = WaitForReady(Job(parentJob))
+        sendEvent(event)
+        return event.job
     }
 
     private fun notifyWidgetOfError(context: Context, throwable: Throwable) {
@@ -276,7 +296,5 @@
     @VisibleForTesting
     internal class RunLambda(val key: String)
     @VisibleForTesting
-    internal class WaitForReady(
-        val resume: Channel<Unit> = Channel(Channel.CONFLATED)
-    )
+    internal class WaitForReady(val job: CompletableJob)
 }
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt
index d344989..934465e 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/CheckBox.kt
@@ -54,6 +54,9 @@
  * checked is provided to this action in its ActionParameters, and can be retrieved using the
  * [ToggleableStateKey]. If this action launches an activity, the current value of checked will be
  * passed as an intent extra with the name [RemoteViews.EXTRA_CHECKED].
+ * In order to allow the Launcher to provide this extra on Android version S and later, we use a
+ * mutable PendingIntent ([android.app.PendingIntent.FLAG_MUTABLE]) when this action is not a
+ * lambda. Before S, and for lambda actions, this will be an immutable PendingIntent.
  * @param modifier the modifier to apply to the check box
  * @param text the text to display to the end of the check box
  * @param style the style to apply to [text]
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidget.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidget.kt
index dac5826..1ce033a 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidget.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidget.kt
@@ -31,6 +31,7 @@
 import androidx.glance.appwidget.state.getAppWidgetState
 import androidx.glance.session.GlanceSessionManager
 import androidx.glance.session.SessionManager
+import androidx.glance.session.SessionManagerScope
 import androidx.glance.state.GlanceState
 import androidx.glance.state.GlanceStateDefinition
 import androidx.glance.state.PreferencesGlanceStateDefinition
@@ -120,7 +121,9 @@
      */
     internal suspend fun deleted(context: Context, appWidgetId: Int) {
         val glanceId = AppWidgetId(appWidgetId)
-        sessionManager.closeSession(glanceId.toSessionKey())
+        sessionManager.runWithLock {
+            closeSession(glanceId.toSessionKey())
+        }
         try {
             onDelete(context, glanceId)
         } catch (cancelled: CancellationException) {
@@ -144,10 +147,12 @@
     ) {
         Tracing.beginGlanceAppWidgetUpdate()
         val glanceId = AppWidgetId(appWidgetId)
-        if (!sessionManager.isSessionRunning(context, glanceId.toSessionKey())) {
-            sessionManager.startSession(context, AppWidgetSession(this, glanceId, options))
-        } else {
-            val session = sessionManager.getSession(glanceId.toSessionKey()) as AppWidgetSession
+        sessionManager.runWithLock {
+            if (!isSessionRunning(context, glanceId.toSessionKey())) {
+                startSession(context, AppWidgetSession(this@GlanceAppWidget, glanceId, options))
+                return@runWithLock
+            }
+            val session = getSession(glanceId.toSessionKey()) as AppWidgetSession
             session.updateGlance()
         }
     }
@@ -163,14 +168,9 @@
         options: Bundle? = null,
     ) {
         val glanceId = AppWidgetId(appWidgetId)
-        val session = if (!sessionManager.isSessionRunning(context, glanceId.toSessionKey())) {
-            AppWidgetSession(this, glanceId, options).also { session ->
-                sessionManager.startSession(context, session)
-            }
-        } else {
-            sessionManager.getSession(glanceId.toSessionKey()) as AppWidgetSession
+        sessionManager.getOrCreateAppWidgetSession(context, glanceId, options) { session ->
+            session.runLambda(actionKey)
         }
-        session.runLambda(actionKey)
     }
 
     /**
@@ -189,10 +189,7 @@
             return
         }
         val glanceId = AppWidgetId(appWidgetId)
-        if (!sessionManager.isSessionRunning(context, glanceId.toSessionKey())) {
-            sessionManager.startSession(context, AppWidgetSession(this, glanceId, options))
-        } else {
-            val session = sessionManager.getSession(glanceId.toSessionKey()) as AppWidgetSession
+        sessionManager.getOrCreateAppWidgetSession(context, glanceId, options) { session ->
             session.updateAppWidgetOptions(options)
         }
     }
@@ -230,6 +227,19 @@
             AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, rv)
         }
     }
+
+    private suspend fun SessionManager.getOrCreateAppWidgetSession(
+        context: Context,
+        glanceId: AppWidgetId,
+        options: Bundle? = null,
+        block: suspend SessionManagerScope.(AppWidgetSession) -> Unit
+    ) = runWithLock {
+        if (!isSessionRunning(context, glanceId.toSessionKey())) {
+            startSession(context, AppWidgetSession(this@GlanceAppWidget, glanceId, options))
+        }
+        val session = getSession(glanceId.toSessionKey()) as AppWidgetSession
+        block(session)
+    }
 }
 
 @RestrictTo(Scope.LIBRARY_GROUP)
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidgetManager.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidgetManager.kt
index 41c7633..9f86183 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidgetManager.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceAppWidgetManager.kt
@@ -18,6 +18,7 @@
 
 import android.app.PendingIntent
 import android.appwidget.AppWidgetManager
+import android.appwidget.AppWidgetProviderInfo
 import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
@@ -29,10 +30,12 @@
 import androidx.compose.ui.unit.DpSize
 import androidx.datastore.core.DataStore
 import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
 import androidx.datastore.preferences.core.stringPreferencesKey
 import androidx.datastore.preferences.core.stringSetPreferencesKey
 import androidx.datastore.preferences.preferencesDataStore
 import androidx.glance.GlanceId
+import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.firstOrNull
 
 /**
@@ -70,8 +73,8 @@
         receiver: R,
         provider: P,
     ) {
-        val receiverName = requireNotNull(receiver.javaClass.canonicalName) { "no receiver name" }
-        val providerName = requireNotNull(provider.javaClass.canonicalName) { "no provider name" }
+        val receiverName = receiver.canonicalName()
+        val providerName = provider.canonicalName()
         dataStore.updateData { pref ->
             pref.toMutablePreferences().also { builder ->
                 builder[providersKey] = (pref[providersKey] ?: emptySet()) + receiverName
@@ -92,8 +95,20 @@
         )
     }
 
-    private suspend fun getState() =
-        dataStore.data.firstOrNull()?.let { createState(it) } ?: State()
+    private suspend fun getState(): State {
+        // Preferences won't contain value for providersKey when either -
+        // 1. App doesn't have any widget placed, but app requested for glanceIds for a widget class
+        // 2. User cleared app data, so, the provider to receivers mapping is lost (even if widgets
+        // are still pinned).
+        // In case of #2, we want to return an appropriate list of glance ids, so, we back-fill the
+        // datastore with all known glance receivers and providers.
+        // #1 isn't something that an app would commonly do, and even if it does, it would get empty
+        // IDs as expected.
+        return createState(
+            prefs = dataStore.data.first().takeIf { it[providersKey] != null }
+                ?: addAllReceiversAndProvidersToPreferences()
+        )
+    }
 
     /**
      * Returns the [GlanceId] of the App Widgets installed for a particular provider.
@@ -237,10 +252,53 @@
         }
     }
 
+    /**
+     * Identifies [GlanceAppWidget] (provider) for each [GlanceAppWidgetReceiver] in the app and
+     * saves the mapping in the preferences datastore. Also stores the set of glance-based
+     * receiver class names.
+     *
+     * [getGlanceIds] looks up the set of associated receivers for the given [GlanceAppWidget]
+     * (provider) from the datastore to be able to get the appwidget ids from [AppWidgetManager].
+     *
+     * Typically, the information is stored / overwritten by [updateReceiver] during widget
+     * lifecycle, however, when app data is cleared by the user, it is lost. So, we reconstruct it
+     * (for all known glance-based receivers).
+     *
+     * Follow b/305232907 to know the recommendation from appWidgets on handling cleared app data
+     * scenarios for widgets.
+     */
+    @Suppress("ListIterator")
+    private suspend fun addAllReceiversAndProvidersToPreferences(): Preferences {
+        val installedGlanceAppWidgetReceivers = appWidgetManager.installedProviders
+            .filter { it.provider.packageName == context.packageName }
+            .mapNotNull { it.maybeGlanceAppWidgetReceiver() }
+
+        return dataStore.updateData { prefs ->
+            prefs.toMutablePreferences().apply {
+                this[providersKey] =
+                    installedGlanceAppWidgetReceivers.map { it.javaClass.name }.toSet()
+                installedGlanceAppWidgetReceivers.forEach {
+                    this[providerKey(it.canonicalName())] = it.glanceAppWidget.canonicalName()
+                }
+            }.toPreferences()
+        }
+    }
+
     @VisibleForTesting
     internal suspend fun listKnownReceivers(): Collection<String>? =
         dataStore.data.firstOrNull()?.let { it[providersKey] }
 
+    /**
+     * Clears the datastore that holds information about glance app widgets (providers) and
+     * receivers.
+     *
+     * Useful for tests that wish to mimic clearing app data.
+     */
+    @VisibleForTesting
+    internal suspend fun clearDataStore() {
+        dataStore.edit { it.clear() }
+    }
+
     private companion object {
         private val Context.appManagerDataStore
             by preferencesDataStore(name = "GlanceAppWidgetManager")
@@ -248,6 +306,20 @@
         private val providersKey = stringSetPreferencesKey("list::Providers")
 
         private fun providerKey(provider: String) = stringPreferencesKey("provider:$provider")
+
+        private fun GlanceAppWidgetReceiver.canonicalName() =
+            requireNotNull(this.javaClass.canonicalName) { "no receiver name" }
+
+        private fun GlanceAppWidget.canonicalName() =
+            requireNotNull(this.javaClass.canonicalName) { "no provider name" }
+
+        private fun AppWidgetProviderInfo.maybeGlanceAppWidgetReceiver(): GlanceAppWidgetReceiver? {
+            val receiver = Class.forName(provider.className).getDeclaredConstructor().newInstance()
+            if (receiver is GlanceAppWidgetReceiver) {
+                return receiver
+            }
+            return null
+        }
     }
 
     @RequiresApi(Build.VERSION_CODES.O)
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceRemoteViewsService.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceRemoteViewsService.kt
index 1e91d1c..52058e4 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceRemoteViewsService.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/GlanceRemoteViewsService.kt
@@ -21,12 +21,14 @@
 import android.content.Intent
 import android.net.Uri
 import android.os.Build
+import android.util.Log
 import android.widget.RemoteViews
 import android.widget.RemoteViewsService
 import androidx.annotation.DoNotInline
 import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
 import androidx.glance.session.GlanceSessionManager
+import kotlinx.coroutines.channels.ClosedSendChannelException
 import kotlinx.coroutines.runBlocking
 
 /**
@@ -51,6 +53,7 @@
     companion object {
         const val EXTRA_VIEW_ID = "androidx.glance.widget.extra.view_id"
         const val EXTRA_SIZE_INFO = "androidx.glance.widget.extra.size_info"
+        const val TAG = "GlanceRemoteViewService"
 
         // An in-memory store containing items to be returned via the adapter when requested.
         private val InMemoryStore = RemoteCollectionItemsInMemoryStore()
@@ -107,26 +110,49 @@
         private fun loadData() {
             runBlocking {
                 val glanceId = AppWidgetId(appWidgetId)
-                // If session is already running, data must have already been loaded into the store
-                // during composition.
-                if (!GlanceSessionManager.isSessionRunning(context, glanceId.toSessionKey())) {
-                    startSessionAndWaitUntilReady(glanceId)
+                try {
+                    startSessionIfNeededAndWaitUntilReady(glanceId)
+                } catch (e: ClosedSendChannelException) {
+                    // This catch should no longer be necessary.
+                    // Because we use SessionManager.runWithLock, we are guaranteed that the session
+                    // we create won't be closed by concurrent calls to SessionManager. Currently,
+                    // the only way a session would be closed is if there is an error in the
+                    // composition that happens between the call to `startSession` and
+                    // `waitForReady()` In that case, the composition error will be logged by
+                    // GlanceAppWidget.onCompositionError, but could still cause
+                    // ClosedSendChannelException. This is pretty unlikely, however keeping this
+                    // here to avoid crashes in that scenario.
+                    Log.e(TAG, "Error when trying to start session for list items", e)
                 }
             }
         }
 
-        private suspend fun startSessionAndWaitUntilReady(glanceId: AppWidgetId) {
+        private suspend fun startSessionIfNeededAndWaitUntilReady(glanceId: AppWidgetId) {
+            val job = getGlanceAppWidget()?.let { widget ->
+                GlanceSessionManager.runWithLock {
+                    if (isSessionRunning(context, glanceId.toSessionKey())) {
+                        // If session is already running, data must have already been loaded into
+                        // the store during composition.
+                        return@runWithLock null
+                    }
+                    startSession(context, AppWidgetSession(widget, glanceId))
+                    val session = getSession(glanceId.toSessionKey()) as AppWidgetSession
+                    session.waitForReady()
+                }
+            } ?: UnmanagedSessionReceiver.getSession(appWidgetId)?.waitForReady()
+            // The following join() may throw CancellationException if the session is closed before
+            // it is ready. This will have the effect of cancelling the runBlocking scope.
+            job?.join()
+        }
+
+        private fun getGlanceAppWidget(): GlanceAppWidget? {
             val appWidgetManager = AppWidgetManager.getInstance(context)
             val providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId)
-            providerInfo?.provider?.className?.let { className ->
+            return providerInfo?.provider?.className?.let { className ->
                 val receiverClass = Class.forName(className)
-                val glanceAppWidget =
-                    (receiverClass.getDeclaredConstructor()
-                        .newInstance() as GlanceAppWidgetReceiver).glanceAppWidget
-                AppWidgetSession(glanceAppWidget, glanceId)
-                    .also { GlanceSessionManager.startSession(context, it) }
-                    .waitForReady()
-            } ?: UnmanagedSessionReceiver.getSession(appWidgetId)?.waitForReady()
+                (receiverClass.getDeclaredConstructor()
+                    .newInstance() as GlanceAppWidgetReceiver).glanceAppWidget
+            }
         }
 
         override fun onDestroy() {
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt
index 44f7f99..2e43830 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/Switch.kt
@@ -54,6 +54,9 @@
  * checked is provided to this action in its ActionParameters, and can be retrieved using the
  * [ToggleableStateKey]. If this action launches an activity, the current value of checked will be
  * passed as an intent extra with the name [RemoteViews.EXTRA_CHECKED].
+ * In order to allow the Launcher to provide this extra on Android version S and later, we use a
+ * mutable PendingIntent ([android.app.PendingIntent.FLAG_MUTABLE]) when this action is not a
+ * lambda. Before S, and for lambda actions, this will be an immutable PendingIntent.
  * @param modifier the modifier to apply to the switch
  * @param text the text to display to the end of the switch
  * @param style the style to apply to [text]
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/action/ApplyAction.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/action/ApplyAction.kt
index 6e2a201..7a94b75 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/action/ApplyAction.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/action/ApplyAction.kt
@@ -75,6 +75,7 @@
     translationContext: TranslationContext,
     @IdRes viewId: Int,
     editParams: (ActionParameters) -> ActionParameters = { it },
+    mutability: Int = PendingIntent.FLAG_IMMUTABLE,
 ): PendingIntent {
     when (action) {
         is StartActivityAction -> {
@@ -93,7 +94,7 @@
                         )
                     }
                 },
-                PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
+                mutability or PendingIntent.FLAG_UPDATE_CURRENT,
                 action.activityOptions,
             )
         }
@@ -119,7 +120,7 @@
                     translationContext.context,
                     0,
                     intent,
-                    PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
+                    mutability or PendingIntent.FLAG_UPDATE_CURRENT,
                 )
             }
         }
@@ -136,7 +137,7 @@
                         )
                     }
                 },
-                PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
+                mutability or PendingIntent.FLAG_UPDATE_CURRENT,
             )
         }
         is RunCallbackAction -> {
@@ -156,7 +157,7 @@
                             ActionTrampolineType.CALLBACK,
                         )
                 },
-                PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
+                mutability or PendingIntent.FLAG_UPDATE_CURRENT,
             )
         }
         is LambdaAction -> {
@@ -179,7 +180,7 @@
                             action.key,
                         )
                 },
-                PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
+                mutability or PendingIntent.FLAG_UPDATE_CURRENT,
             )
         }
         is CompoundButtonAction -> {
@@ -188,6 +189,15 @@
                 translationContext,
                 viewId,
                 action.getActionParameters(),
+                mutability = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
+                    action.innerAction !is LambdaAction) {
+                    // RemoteViews.setOnCheckedChangedResponse (API 31+) requires a mutable
+                    // PendingIntent in order to set the EXTRA_CHECKED extra with the current state
+                    // of the button. Lambda actions do not use this extra so they can be immutable.
+                    PendingIntent.FLAG_MUTABLE
+                } else {
+                    mutability
+                }
             )
         }
         else -> error("Cannot create PendingIntent for action type: $action")
@@ -370,7 +380,7 @@
             context,
             0,
             intent,
-            PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
+            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
         )
     }
 }
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/AppWidgetSessionTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/AppWidgetSessionTest.kt
index 6eaa1a5..4c62efd 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/AppWidgetSessionTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/AppWidgetSessionTest.kt
@@ -219,6 +219,25 @@
         assertThat(caught).isEqualTo(null)
     }
 
+    @Test
+    fun waitForReadyResumesWhenEventIsReceived() = runTest {
+        launch {
+            session.waitForReady().join()
+            session.close()
+        }
+        session.receiveEvents(context) {}
+    }
+
+    @Test
+    fun waitForReadyResumesWhenSessionIsClosed() = runTest {
+        launch {
+            session.waitForReady().join()
+        }
+        // Advance until waitForReady suspends.
+        this.testScheduler.advanceUntilIdle()
+        session.close()
+    }
+
     private class TestGlanceState : ConfigManager {
 
         val getValueCalls = mutableListOf<String>()
diff --git a/glance/glance-material3/api/current.txt b/glance/glance-material3/api/current.txt
index 016b53c..20f8436 100644
--- a/glance/glance-material3/api/current.txt
+++ b/glance/glance-material3/api/current.txt
@@ -18,7 +18,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold(kotlin.jvm.functions.Function0<kotlin.Unit> titleBar, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider backgroundColor);
+    method @androidx.compose.runtime.Composable public static void Scaffold(kotlin.jvm.functions.Function0<kotlin.Unit> titleBar, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider backgroundColor, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
   }
 
   public final class TitleBarKt {
diff --git a/glance/glance-material3/api/restricted_current.txt b/glance/glance-material3/api/restricted_current.txt
index 016b53c..20f8436 100644
--- a/glance/glance-material3/api/restricted_current.txt
+++ b/glance/glance-material3/api/restricted_current.txt
@@ -18,7 +18,7 @@
   }
 
   public final class ScaffoldKt {
-    method @androidx.compose.runtime.Composable public static void Scaffold(kotlin.jvm.functions.Function0<kotlin.Unit> titleBar, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider backgroundColor);
+    method @androidx.compose.runtime.Composable public static void Scaffold(kotlin.jvm.functions.Function0<kotlin.Unit> titleBar, optional androidx.glance.GlanceModifier modifier, optional androidx.glance.unit.ColorProvider backgroundColor, kotlin.jvm.functions.Function1<? super androidx.glance.layout.ColumnScope,kotlin.Unit> content);
   }
 
   public final class TitleBarKt {
diff --git a/glance/glance-material3/src/main/java/androidx/glance/material3/Scaffold.kt b/glance/glance-material3/src/main/java/androidx/glance/material3/Scaffold.kt
index 39e8207..2ddbedb 100644
--- a/glance/glance-material3/src/main/java/androidx/glance/material3/Scaffold.kt
+++ b/glance/glance-material3/src/main/java/androidx/glance/material3/Scaffold.kt
@@ -35,17 +35,17 @@
  * component.
  *
  * @param titleBar A composable that creates the [TitleBar]
- * @param content The main content of the widget.
  * @param modifier a modifier
  * @param backgroundColor the background color for the layout.
+ * @param content The main content of the widget.
  */
 @Composable
 fun Scaffold(
     titleBar: @Composable () -> Unit,
-    content: @Composable ColumnScope.() -> Unit,
     modifier: GlanceModifier = GlanceModifier,
-    backgroundColor: ColorProvider = GlanceTheme.colors.surface
-) {
+    backgroundColor: ColorProvider = GlanceTheme.colors.surface,
+    content: @Composable ColumnScope.() -> Unit,
+    ) {
     Box(modifier
         .fillMaxSize()
         .background(backgroundColor)
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt
index 6b9a108..ce75bbc 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt
@@ -66,7 +66,8 @@
         fun tintColor() = ColorProvider(Color.Magenta)
 
         val modifier = GlanceModifier.background(
-            ImageProvider(R.drawable.oval), ColorFilter.tint(
+            ImageProvider(R.drawable.oval),
+            colorFilter = ColorFilter.tint(
                 tintColor()
             )
         )
diff --git a/glance/glance/api/current.txt b/glance/glance/api/current.txt
index 4389b13..12a1867 100644
--- a/glance/glance/api/current.txt
+++ b/glance/glance/api/current.txt
@@ -2,8 +2,8 @@
 package androidx.glance {
 
   public final class BackgroundKt {
-    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, androidx.glance.ColorFilter? colorFilter, optional int contentScale);
-    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale);
+    method @Deprecated public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale, optional androidx.glance.ColorFilter? colorFilter);
     method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.unit.ColorProvider colorProvider);
     method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, @ColorRes int color);
     method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, long color);
diff --git a/glance/glance/api/restricted_current.txt b/glance/glance/api/restricted_current.txt
index 4389b13..12a1867 100644
--- a/glance/glance/api/restricted_current.txt
+++ b/glance/glance/api/restricted_current.txt
@@ -2,8 +2,8 @@
 package androidx.glance {
 
   public final class BackgroundKt {
-    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, androidx.glance.ColorFilter? colorFilter, optional int contentScale);
-    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale);
+    method @Deprecated public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale);
+    method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.ImageProvider imageProvider, optional int contentScale, optional androidx.glance.ColorFilter? colorFilter);
     method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, androidx.glance.unit.ColorProvider colorProvider);
     method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, @ColorRes int color);
     method public static androidx.glance.GlanceModifier background(androidx.glance.GlanceModifier, long color);
diff --git a/glance/glance/src/androidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt b/glance/glance/src/androidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
index 3f4fa05..474e759 100644
--- a/glance/glance/src/androidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
+++ b/glance/glance/src/androidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
@@ -127,7 +127,9 @@
         val text = assertIs<EmittableText>(testSession.uiTree.receive().children.single())
         assertThat(text.text).isEqualTo("Hello World")
 
-        assertNotNull(GlanceSessionManager.getSession(testSession.key)).close()
+        GlanceSessionManager.runWithLock {
+            assertNotNull(getSession(testSession.key)).close()
+        }
         waitForWorkerSuccess()
     }
 
@@ -150,7 +152,9 @@
         // The session is not subject to a timeout before the composition has been processed
         // successfully for the first time.
         delay(initialTimeout * 5)
-        assertThat(GlanceSessionManager.isSessionRunning(context, testSession.key)).isTrue()
+        GlanceSessionManager.runWithLock {
+            assertThat(isSessionRunning(context, testSession.key)).isTrue()
+        }
 
         testSession.uiTree.receive()
         val timeout = testTimeSource.measureTime {
@@ -189,9 +193,11 @@
     }
 
     private suspend fun startSession() {
-        GlanceSessionManager.startSession(context, testSession)
-        waitForWorkerStart()
-        assertThat(GlanceSessionManager.isSessionRunning(context, testSession.key)).isTrue()
+        GlanceSessionManager.runWithLock {
+            startSession(context, testSession)
+            waitForWorkerStart()
+            assertThat(isSessionRunning(context, testSession.key)).isTrue()
+        }
     }
 
     private suspend fun waitForWorkerState(vararg state: State) = workerState.first {
diff --git a/glance/glance/src/main/java/androidx/glance/Background.kt b/glance/glance/src/main/java/androidx/glance/Background.kt
index 9ea97b3..1d095cd 100644
--- a/glance/glance/src/main/java/androidx/glance/Background.kt
+++ b/glance/glance/src/main/java/androidx/glance/Background.kt
@@ -78,6 +78,10 @@
  * @param contentScale scaling to apply to the imageProvider.
  *
  */
+@Deprecated(
+    "This method has been deprecated in favor of the one that accepts a colorFilter.",
+    level = DeprecationLevel.HIDDEN
+)
 fun GlanceModifier.background(
     imageProvider: ImageProvider,
     contentScale: ContentScale = ContentScale.FillBounds
@@ -93,9 +97,9 @@
  */
 fun GlanceModifier.background(
     imageProvider: ImageProvider,
-    colorFilter: ColorFilter?,
     contentScale: ContentScale = ContentScale.FillBounds,
-    ): GlanceModifier =
+    colorFilter: ColorFilter? = null,
+): GlanceModifier =
     this.then(
         BackgroundModifier.Image(
             imageProvider = imageProvider,
diff --git a/glance/glance/src/main/java/androidx/glance/session/Session.kt b/glance/glance/src/main/java/androidx/glance/session/Session.kt
index c7aec1e..614aff6 100644
--- a/glance/glance/src/main/java/androidx/glance/session/Session.kt
+++ b/glance/glance/src/main/java/androidx/glance/session/Session.kt
@@ -22,6 +22,7 @@
 import androidx.compose.runtime.Composable
 import androidx.glance.EmittableWithChildren
 import androidx.glance.GlanceComposable
+import java.util.concurrent.atomic.AtomicBoolean
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.channels.ClosedReceiveChannelException
 
@@ -32,6 +33,12 @@
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 abstract class Session(val key: String) {
+    // _isOpen/isOpen is used to check whether this Session's event channel is still open and
+    // accepting events (close has not been called). It may be checked or set from different
+    // threads, so we use an AtomicBoolean so that the value is updated atomically.
+    private val _isOpen = AtomicBoolean(true)
+    internal val isOpen: Boolean
+        get() = _isOpen.get()
     private val eventChannel = Channel<Any>(Channel.UNLIMITED)
 
     /**
@@ -85,11 +92,22 @@
         }
     }
 
+    /**
+     * Close the session. Any events sent before [close] will be processed unless the Worker for
+     * this session is cancelled.
+     */
     fun close() {
         eventChannel.close()
+        _isOpen.set(false)
+        onClosed()
     }
 
     /**
+     * Called after the session is closed. Can be used by implementers to clean up any resources.
+     */
+    open fun onClosed() {}
+
+    /**
      * Called when there is an error in the composition. The session will be closed immediately
      * after this.
      */
diff --git a/glance/glance/src/main/java/androidx/glance/session/SessionManager.kt b/glance/glance/src/main/java/androidx/glance/session/SessionManager.kt
index 5b83da2..4099d5e 100644
--- a/glance/glance/src/main/java/androidx/glance/session/SessionManager.kt
+++ b/glance/glance/src/main/java/androidx/glance/session/SessionManager.kt
@@ -16,6 +16,7 @@
 
 package androidx.glance.session
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.util.Log
 import androidx.annotation.RestrictTo
@@ -28,6 +29,8 @@
 import androidx.work.await
 import androidx.work.workDataOf
 import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 
 @JvmDefaultWithCompatibility
 /**
@@ -38,6 +41,27 @@
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 interface SessionManager {
     /**
+     * [runWithLock] provides a scope in which to run operations on SessionManager.
+     *
+     * The implementation must ensure that concurrent calls to [runWithLock] are mutually exclusive.
+     * Because this function holds a lock while running [block], clients should not run any
+     * long-running operations in [block]. The client should not maintain a reference to the
+     * [SessionManagerScope] after [block] returns.
+     */
+    suspend fun <T> runWithLock(block: suspend SessionManagerScope.() -> T): T
+
+    /**
+     * The name of the session key parameter, which is used to set the session key in the Worker's
+     * input data.
+     * TODO: consider using a typealias instead
+     */
+    val keyParam: String
+        get() = "KEY"
+}
+
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+interface SessionManagerScope {
+    /**
      * Start a session for the Glance in [session].
      */
     suspend fun startSession(context: Context, session: Session)
@@ -56,9 +80,6 @@
      * Gets the session corresponding to [key] if it exists
      */
     fun getSession(key: String): Session?
-
-    val keyParam: String
-        get() = "KEY"
 }
 
 @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -67,49 +88,65 @@
 internal class SessionManagerImpl(
     private val workerClass: Class<out ListenableWorker>
 ) : SessionManager {
-    private val sessions = mutableMapOf<String, Session>()
-    companion object {
-        private const val TAG = "GlanceSessionManager"
-        private const val DEBUG = false
+    private companion object {
+        const val TAG = "GlanceSessionManager"
+        const val DEBUG = false
     }
 
-    override suspend fun startSession(context: Context, session: Session) {
-        if (DEBUG) Log.d(TAG, "startSession(${session.key})")
-        synchronized(sessions) {
-            sessions.put(session.key, session)
-        }?.close()
-        val workRequest = OneTimeWorkRequest.Builder(workerClass)
-            .setInputData(
-                workDataOf(
-                    keyParam to session.key
+    // This mutex guards access to the SessionManagerScope, to prevent multiple clients from
+    // performing SessionManagerScope operations at the same time.
+    private val mutex = Mutex()
+
+    // All external access to this object is protected with a mutex, so there is no need for any
+    // internal synchronization.
+    private val scope = object : SessionManagerScope {
+        private val sessions = mutableMapOf<String, Session>()
+
+        override suspend fun startSession(context: Context, session: Session) {
+            if (DEBUG) Log.d(TAG, "startSession(${session.key})")
+            sessions.put(session.key, session)?.let { previousSession ->
+                previousSession.close()
+            }
+            val workRequest = OneTimeWorkRequest.Builder(workerClass)
+                .setInputData(
+                    workDataOf(
+                        keyParam to session.key
+                    )
                 )
-            )
-            .build()
-        WorkManager.getInstance(context)
-            .enqueueUniqueWork(session.key, ExistingWorkPolicy.REPLACE, workRequest)
-            .result.await()
-        enqueueDelayedWorker(context)
-    }
-
-    override fun getSession(key: String): Session? = synchronized(sessions) {
-        sessions[key]
-    }
-
-    override suspend fun isSessionRunning(context: Context, key: String) =
-        (WorkManager.getInstance(context).getWorkInfosForUniqueWork(key).await()
-            .any { it.state == WorkInfo.State.RUNNING } && synchronized(sessions) {
-            sessions.containsKey(key)
-        }).also {
-            if (DEBUG) Log.d(TAG, "isSessionRunning($key) == $it")
+                .build()
+            WorkManager.getInstance(context)
+                .enqueueUniqueWork(session.key, ExistingWorkPolicy.REPLACE, workRequest)
+                .result.await()
+            enqueueDelayedWorker(context)
         }
 
-    override suspend fun closeSession(key: String) {
-        if (DEBUG) Log.d(TAG, "closeSession($key)")
-        synchronized(sessions) {
-            sessions.remove(key)
-        }?.close()
+        override fun getSession(key: String): Session? = sessions[key]
+
+        @SuppressLint("ListIterator")
+        override suspend fun isSessionRunning(
+            context: Context,
+            key: String
+        ): Boolean {
+            val workerIsRunningOrEnqueued = WorkManager.getInstance(context)
+                .getWorkInfosForUniqueWork(key)
+                .await()
+                .any { it.state in listOf(WorkInfo.State.RUNNING, WorkInfo.State.ENQUEUED) }
+            val hasOpenSession = sessions[key]?.isOpen ?: false
+            val isRunning = hasOpenSession && workerIsRunningOrEnqueued
+            if (DEBUG) Log.d(TAG, "isSessionRunning($key) == $isRunning")
+            return isRunning
+        }
+
+        override suspend fun closeSession(key: String) {
+            if (DEBUG) Log.d(TAG, "closeSession($key)")
+            sessions.remove(key)?.close()
+        }
     }
 
+    override suspend fun <T> runWithLock(
+        block: suspend SessionManagerScope.() -> T
+    ): T = mutex.withLock { scope.block() }
+
     /**
      * Workaround worker to fix b/119920965
      */
diff --git a/glance/glance/src/main/java/androidx/glance/session/SessionWorker.kt b/glance/glance/src/main/java/androidx/glance/session/SessionWorker.kt
index 2cff47b..544dd2d 100644
--- a/glance/glance/src/main/java/androidx/glance/session/SessionWorker.kt
+++ b/glance/glance/src/main/java/androidx/glance/session/SessionWorker.kt
@@ -101,12 +101,14 @@
                     if (DEBUG) Log.d(TAG, "Received idle event, session timeout $timeLeft")
                 }
             ) {
-                val session = sessionManager.getSession(key) ?: if (params.runAttemptCount == 0) {
+                val session = sessionManager.runWithLock {
+                    getSession(key)
+                } ?: if (params.runAttemptCount == 0) {
                     error("No session available for key $key")
                 } else {
-                    // If this is a retry because the process was restarted (e.g. on app upgrade or
-                    // reinstall), the Session object won't be available because it's not persistable
-                    // at the moment.
+                    // If this is a retry because the process was restarted (e.g. on app upgrade
+                    // or reinstall), the Session object won't be available because it's not
+                    // persistable.
                     Log.w(
                         TAG,
                         "SessionWorker attempted restart but Session is not available for $key"
@@ -114,14 +116,18 @@
                     return@observeIdleEvents Result.success()
                 }
 
-                runSession(
-                    applicationContext,
-                    session,
-                    timeouts,
-                    effectJobFactory = {
-                        Job().also { effectJob = it }
-                    }
-                )
+                try {
+                    runSession(
+                        applicationContext,
+                        session,
+                        timeouts,
+                        effectJobFactory = {
+                            Job().also { effectJob = it }
+                        }
+                    )
+                } finally {
+                    session.close()
+                }
                 Result.success()
             }
         } ?: Result.success(Data.Builder().putBoolean(TimeoutExitReason, true).build())
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/SessionManagerImplTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/SessionManagerImplTest.kt
index 9a05800..b47fa4f 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/session/SessionManagerImplTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/SessionManagerImplTest.kt
@@ -29,9 +29,12 @@
 import androidx.work.impl.WorkManagerImpl
 import androidx.work.testing.WorkManagerTestInitHelper
 import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicBoolean
 import kotlin.coroutines.suspendCoroutine
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.yield
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
@@ -84,19 +87,55 @@
 
     @Test
     fun startSession() = runTest {
-        assertThat(sessionManager.isSessionRunning(context, key)).isFalse()
-        sessionManager.startSession(context, session)
-        assertThat(sessionManager.isSessionRunning(context, key)).isTrue()
-        assertThat(sessionManager.getSession(key)).isSameInstanceAs(session)
+        sessionManager.runWithLock {
+            assertThat(isSessionRunning(context, key)).isFalse()
+            startSession(context, session)
+            assertThat(isSessionRunning(context, key)).isTrue()
+            assertThat(getSession(key)).isSameInstanceAs(session)
+        }
     }
 
     @Test
     fun closeSession() = runTest {
-        sessionManager.startSession(context, session)
-        assertThat(sessionManager.isSessionRunning(context, key)).isTrue()
-        sessionManager.closeSession(key)
-        assertThat(sessionManager.isSessionRunning(context, key)).isFalse()
-        assertThat(sessionManager.getSession(key)).isNull()
+        sessionManager.runWithLock {
+            startSession(context, session)
+            assertThat(isSessionRunning(context, key)).isTrue()
+            closeSession(key)
+            assertThat(isSessionRunning(context, key)).isFalse()
+            assertThat(getSession(key)).isNull()
+        }
+    }
+
+    @Test
+    fun closedSessionIsNotRunning() = runTest {
+        sessionManager.runWithLock {
+            assertThat(isSessionRunning(context, key)).isFalse()
+            startSession(context, session)
+            assertThat(isSessionRunning(context, key)).isTrue()
+            session.close()
+            assertThat(isSessionRunning(context, key)).isFalse()
+        }
+    }
+
+    @Test
+    fun runWithLockIsMutuallyExclusive() = runTest {
+        val firstRan = AtomicBoolean(false)
+        launch {
+            sessionManager.runWithLock {
+                yield()
+                firstRan.set(true)
+            }
+        }
+        // Because test dispatchers are single threaded and do not run background `launch`es until
+        // we suspend, we yield here to allow the first transaction to run. This resumes after the
+        // yield above, while the first transaction still has the lock but is suspended.
+        yield()
+        // This call to runWithLock should suspend until the first transaction finishes, then run
+        // the block. If it is not mutually exclusive, it will run right away and firstRan will not
+        // be true.
+        sessionManager.runWithLock {
+            assertThat(firstRan.get()).isTrue()
+        }
     }
 }
 
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
index d5dfc4a..693218f 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
@@ -29,11 +29,11 @@
 import androidx.glance.text.EmittableText
 import androidx.glance.text.Text
 import androidx.test.core.app.ApplicationProvider
-import androidx.work.Data
 import androidx.work.ListenableWorker.Result
 import androidx.work.WorkerFactory
 import androidx.work.WorkerParameters
 import androidx.work.testing.TestListenableWorkerBuilder
+import androidx.work.workDataOf
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.assertIs
 import kotlin.time.Duration
@@ -58,7 +58,7 @@
     fun setUp() {
         context = ApplicationProvider.getApplicationContext()
         worker = TestListenableWorkerBuilder<SessionWorker>(context)
-            .setInputData(Data(mapOf(sessionManager.keyParam to SESSION_KEY)))
+            .setInputData(workDataOf(sessionManager.keyParam to SESSION_KEY))
             .setWorkerFactory(object : WorkerFactory() {
                 override fun createWorker(
                     appContext: Context,
@@ -75,8 +75,8 @@
             val result = worker.doWork()
             assertThat(result).isEqualTo(Result.success())
         }
-        sessionManager.startSession(context)
-        sessionManager.closeSession()
+        sessionManager.scope.startSession(context)
+        sessionManager.scope.closeSession()
     }
 
     @Test
@@ -86,7 +86,7 @@
             assertThat(result).isEqualTo(Result.success())
         }
 
-        val root = sessionManager.startSession(context) {
+        val root = sessionManager.scope.startSession(context) {
             Box {
                 Text("Hello World")
             }
@@ -94,7 +94,7 @@
         val box = assertIs<EmittableBox>(root.children.single())
         val text = assertIs<EmittableText>(box.children.single())
         assertThat(text.text).isEqualTo("Hello World")
-        sessionManager.closeSession()
+        sessionManager.scope.closeSession()
     }
 
     @Test
@@ -103,10 +103,10 @@
             val result = worker.doWork()
             assertThat(result).isEqualTo(Result.success())
         }
-        sessionManager.startSession(context).first()
-        val session = assertIs<TestSession>(sessionManager.getSession(SESSION_KEY))
+        sessionManager.scope.startSession(context).first()
+        val session = assertIs<TestSession>(sessionManager.scope.getSession(SESSION_KEY))
         assertThat(session.provideGlanceCalled).isEqualTo(1)
-        sessionManager.closeSession()
+        sessionManager.scope.closeSession()
     }
 
     @Test
@@ -117,7 +117,7 @@
         }
 
         val state = mutableStateOf("Hello World")
-        val uiFlow = sessionManager.startSession(context) {
+        val uiFlow = sessionManager.scope.startSession(context) {
                 Text(state.value)
         }
         uiFlow.first().getOrThrow().let { root ->
@@ -130,7 +130,7 @@
             val text = assertIs<EmittableText>(root.children.single())
             assertThat(text.text).isEqualTo("Hello Earth")
         }
-        sessionManager.closeSession()
+        sessionManager.scope.closeSession()
     }
 
     @Test
@@ -141,14 +141,14 @@
         }
 
         val state = mutableStateOf("Hello World")
-        val uiFlow = sessionManager.startSession(context) {
+        val uiFlow = sessionManager.scope.startSession(context) {
             Text(state.value)
         }
         uiFlow.first().getOrThrow().let { root ->
             val text = assertIs<EmittableText>(root.children.single())
             assertThat(text.text).isEqualTo("Hello World")
         }
-        val session = assertIs<TestSession>(sessionManager.getSession(SESSION_KEY))
+        val session = assertIs<TestSession>(sessionManager.scope.getSession(SESSION_KEY))
         session.sendEvent {
             state.value = "Hello Earth"
         }
@@ -156,7 +156,7 @@
             val text = assertIs<EmittableText>(root.children.single())
             assertThat(text.text).isEqualTo("Hello Earth")
         }
-        sessionManager.closeSession()
+        sessionManager.scope.closeSession()
     }
 
     @Test
@@ -167,7 +167,7 @@
         }
 
         val state = mutableStateOf("Hello World")
-        val uiFlow = sessionManager.startDelayedProcessingSession(context) {
+        val uiFlow = sessionManager.scope.startDelayedProcessingSession(context) {
             Text(state.value)
         }
         uiFlow.first().getOrThrow().let { root ->
@@ -183,9 +183,9 @@
             assertThat(text.text).isEqualTo("Hello Earth")
         }
 
-        val session = assertIs<TestSession>(sessionManager.getSession(SESSION_KEY))
+        val session = assertIs<TestSession>(sessionManager.scope.getSession(SESSION_KEY))
         assertThat(session.processEmittableTreeCancelCount).isEqualTo(1)
-        sessionManager.closeSession()
+        sessionManager.scope.closeSession()
     }
 
     @Test
@@ -197,7 +197,7 @@
 
         val cause = Throwable()
         val exception = Exception("message", cause)
-        val result = sessionManager.startSession(context) {
+        val result = sessionManager.scope.startSession(context) {
             throw exception
         }.first().exceptionOrNull()
         assertThat(result).hasCauseThat().isEqualTo(cause)
@@ -214,7 +214,7 @@
         val runError = mutableStateOf(false)
         val cause = Throwable()
         val exception = Exception("message", cause)
-        val resultFlow = sessionManager.startSession(context) {
+        val resultFlow = sessionManager.scope.startSession(context) {
             if (runError.value) {
                 throw exception
             } else {
@@ -245,7 +245,7 @@
 
         val cause = Throwable()
         val exception = Exception("message", cause)
-        val result = sessionManager.startSession(context) {
+        val result = sessionManager.scope.startSession(context) {
             SideEffect { throw exception }
         }.first().exceptionOrNull()
         assertThat(result).hasCauseThat().isEqualTo(cause)
@@ -261,7 +261,7 @@
 
         val cause = Throwable()
         val exception = Exception("message", cause)
-        val result = sessionManager.startSession(context) {
+        val result = sessionManager.scope.startSession(context) {
             LaunchedEffect(true) { throw exception }
         }.first().exceptionOrNull()
         assertThat(result).hasCauseThat().isEqualTo(cause)
@@ -282,7 +282,7 @@
             }
         }
 
-        sessionManager.startSession(context).first()
+        sessionManager.scope.startSession(context).first()
         workerJob.cancel()
     }
 
@@ -294,54 +294,60 @@
             assertThat(worker.effectJob?.isCancelled).isTrue()
         }
 
-        sessionManager.startSession(context).first()
-        sessionManager.closeSession()
+        sessionManager.scope.startSession(context).first()
+        sessionManager.scope.closeSession()
     }
 }
 
 private const val SESSION_KEY = "123"
 
 class TestSessionManager : SessionManager {
-    private val sessions = mutableMapOf<String, Session>()
+    val scope = TestSessionManagerScope()
+    // No locking needed, tests are run on single threaded environment and is only user of this
+    // SessionManager.
+    override suspend fun <T> runWithLock(block: suspend SessionManagerScope.() -> T): T =
+        scope.block()
 
-    suspend fun startSession(
-        context: Context,
-        content: @GlanceComposable @Composable () -> Unit = {}
-    ) = MutableSharedFlow<kotlin.Result<EmittableWithChildren>>().also { flow ->
-        startSession(context, TestSession(resultFlow = flow, content = content))
-    }
+    class TestSessionManagerScope : SessionManagerScope {
+        private val sessions = mutableMapOf<String, Session>()
+        suspend fun startSession(
+            context: Context,
+            content: @GlanceComposable @Composable () -> Unit = {}
+        ) = MutableSharedFlow<kotlin.Result<EmittableWithChildren>>().also { flow ->
+            startSession(context, TestSession(resultFlow = flow, content = content))
+        }
 
-    suspend fun startDelayedProcessingSession(
-        context: Context,
-        content: @GlanceComposable @Composable () -> Unit = {}
-    ) = MutableSharedFlow<kotlin.Result<EmittableWithChildren>>().also { flow ->
-        startSession(
-            context,
-            TestSession(
-                resultFlow = flow,
-                content = content,
-                processEmittableTreeHasInfiniteDelay = true,
+        suspend fun startDelayedProcessingSession(
+            context: Context,
+            content: @GlanceComposable @Composable () -> Unit = {}
+        ) = MutableSharedFlow<kotlin.Result<EmittableWithChildren>>().also { flow ->
+            startSession(
+                context,
+                TestSession(
+                    resultFlow = flow,
+                    content = content,
+                    processEmittableTreeHasInfiniteDelay = true,
+                )
             )
-        )
-    }
+        }
 
-    suspend fun closeSession() {
-        closeSession(SESSION_KEY)
-    }
+        suspend fun closeSession() {
+            closeSession(SESSION_KEY)
+        }
 
-    override suspend fun startSession(context: Context, session: Session) {
-        sessions[session.key] = session
-    }
+        override suspend fun startSession(context: Context, session: Session) {
+            sessions[session.key] = session
+        }
 
-    override suspend fun closeSession(key: String) {
-        sessions[key]?.close()
-    }
+        override suspend fun closeSession(key: String) {
+            sessions[key]?.close()
+        }
 
-    override suspend fun isSessionRunning(context: Context, key: String): Boolean {
-        TODO("Not yet implemented")
+        override suspend fun isSessionRunning(context: Context, key: String): Boolean {
+            TODO("Not yet implemented")
+        }
+        override fun getSession(key: String): Session? = sessions[key]
     }
-
-    override fun getSession(key: String): Session? = sessions[key]
 }
 
 class TestSession(
diff --git a/gradle.properties b/gradle.properties
index b30720c..470ef1a3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -27,8 +27,6 @@
 android.enableAdditionalTestOutput=true
 android.useAndroidX=true
 android.nonTransitiveRClass=true
-# Pending cleanup to support non-constant R class IDs b/260409846
-android.nonFinalResIds=false
 android.experimental.lint.missingBaselineIsEmptyBaseline=true
 android.experimental.lint.reservedMemoryPerTask=1g
 
@@ -82,3 +80,6 @@
 
 # Properties we often want to toggle
 ksp.version.check=false
+
+# Annotation processors discovery from compile classpath is deprecated
+kapt.include.compile.classpath=false
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index dc73106..073053b 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -27,22 +27,22 @@
 byteBuddy = "1.12.10"
 asm = "9.3"
 cmake = "3.22.1"
-dagger = "2.48"
+dagger = "2.49"
 dexmaker = "2.28.3"
 dokka = "1.8.20-dev-214"
 espresso = "3.6.0-alpha01"
 espressoDevice = "1.0.0-alpha05"
 grpc = "1.52.0"
 guavaJre = "31.1-jre"
-hilt = "2.48"
+hilt = "2.49"
 incap = "0.2"
 jcodec = "0.2.5"
 kotlin17 = "1.7.10"
 kotlin18 = "1.8.22"
-kotlin19 = "1.9.20"
-kotlin = "1.9.20"
+kotlin19 = "1.9.21"
+kotlin = "1.9.21"
 kotlinBenchmark = "0.4.8"
-kotlinNative = "1.9.20"
+kotlinNative = "1.9.21"
 kotlinCompileTesting = "1.4.9"
 kotlinCoroutines = "1.7.3"
 kotlinSerialization = "1.3.3"
@@ -85,7 +85,7 @@
 androidToolsAnalyticsProtos = { module = "com.android.tools.analytics-library:protos", version.ref = "androidLint" }
 androidKotlinMultiplatform = { module = "com.android.kotlin.multiplatform.library:com.android.kotlin.multiplatform.library.gradle.plugin", version.ref = "androidGradlePlugin" }
 androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "annotationVersion" }
-autoCommon = { module = "com.google.auto:auto-common", version = "0.11" }
+autoCommon = { module = "com.google.auto:auto-common", version = "1.2.1" }
 atomicFu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicFu" }
 atomicFuPluginz = { module = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version.ref = "atomicFu" }
 autoServiceAnnotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoService" }
@@ -106,7 +106,7 @@
 checkerframework = { module = "org.checkerframework:checker-qual", version = "2.5.3" }
 checkmark = { module = "net.saff.checkmark:checkmark", version = "0.1.6" }
 constraintLayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.0.1"}
-dackka = { module = "com.google.devsite:dackka", version = "1.4.0" }
+dackka = { module = "com.google.devsite:dackka", version = "1.4.1" }
 dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
 daggerCompiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
 desugarJdkLibs = { module = "com.android.tools:desugar_jdk_libs", version = "2.0.3" }
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index e0c828e..e5f9139 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- To regenerate this file, run development/update-verification-metadata.sh -->
-<verification-metadata xmlns="https://schema.gradle.org/dependency-verification" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.2.xsd">
+<verification-metadata xmlns="https://schema.gradle.org/dependency-verification" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.3.xsd">
    <configuration>
       <verify-metadata>true</verify-metadata>
       <verify-signatures>true</verify-signatures>
+      <keyring-format>armored</keyring-format>
       <key-servers enabled="false">
          <key-server uri="https://keyserver.ubuntu.com"/>
          <key-server uri="https://keys.openpgp.org"/>
@@ -477,19 +478,19 @@
       </trusted-keys>
    </configuration>
    <components>
-      <component group="" name="kotlin-native-prebuilt-linux-x86_64" version="1.9.20">
-         <artifact name="kotlin-native-prebuilt-linux-x86_64-1.9.20.tar.gz">
-            <sha256 value="21899334495a5340c5504b1f7698db425b94ffeb633d809668c308e1f15bf585" origin="Hand-built using sha256sum kotlin-native-prebuilt-linux-x86_64-1.9.20.tar.gz" reason="Artifact is not signed"/>
+      <component group="" name="kotlin-native-prebuilt-linux-x86_64" version="1.9.21">
+         <artifact name="kotlin-native-prebuilt-linux-x86_64-1.9.21.tar.gz">
+            <sha256 value="8fbabb93092de6047345f1a9134e41e778828d51e70a44a7a50044b8471ce900" origin="Hand-built using sha256sum kotlin-native-prebuilt-linux-x86_64-1.9.21.tar.gz" reason="Artifact is not signed"/>
          </artifact>
       </component>
-      <component group="" name="kotlin-native-prebuilt-macos-aarch64" version="1.9.20">
-         <artifact name="kotlin-native-prebuilt-macos-aarch64-1.9.20.tar.gz">
-            <sha256 value="1c6a149c98d7c2f557b638465b415152d30b80746a3582235b1cd0484d320da8" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-aarch64-1.9.20.tar.gz"/>
+      <component group="" name="kotlin-native-prebuilt-macos-aarch64" version="1.9.21">
+         <artifact name="kotlin-native-prebuilt-macos-aarch64-1.9.21.tar.gz">
+            <sha256 value="8a05fb4645f5252143e6262e9207f60902ab4641ae08bc7cb40f93b47771358f" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-aarch64-1.9.21.tar.gz"/>
          </artifact>
       </component>
-      <component group="" name="kotlin-native-prebuilt-macos-x86_64" version="1.9.20">
-         <artifact name="kotlin-native-prebuilt-macos-x86_64-1.9.20.tar.gz">
-            <sha256 value="3e39493d86f8175a34698a5c884e127dde04390629942f3c52eeca5bdc1ccf56" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-x86_64-1.9.20.tar.gz"/>
+      <component group="" name="kotlin-native-prebuilt-macos-x86_64" version="1.9.21">
+         <artifact name="kotlin-native-prebuilt-macos-x86_64-1.9.21.tar.gz">
+            <sha256 value="11c8e5764f05541d23c09db75d1f975930cfe38962bb264ad0719e45fb0e6f9c" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-x86_64-1.9.21.tar.gz"/>
          </artifact>
       </component>
       <component group="aopalliance" name="aopalliance" version="1.0">
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 48a5558..570dfce 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=../../../../tools/external/gradle/gradle-8.4-bin.zip
-distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
+distributionUrl=../../../../tools/external/gradle/gradle-8.5-bin.zip
+distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 45c5536..11901b7e 100755
--- a/gradlew
+++ b/gradlew
@@ -43,12 +43,6 @@
 
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 
-if [[ " ${@} " =~ " -PupdateLintBaseline " ]]; then
-  # remove when b/188666845 is complete
-  # Inform lint to not fail even when creating a baseline file
-  JAVA_OPTS="$JAVA_OPTS -Dlint.baselines.continue=true"
-fi
-
 APP_NAME="Gradle"
 APP_BASE_NAME=`basename "$0"`
 
diff --git a/graphics/graphics-core/api/1.0.0-beta01.txt b/graphics/graphics-core/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..bcf0955
--- /dev/null
+++ b/graphics/graphics-core/api/1.0.0-beta01.txt
@@ -0,0 +1,561 @@
+// Signature format: 4.0
+package androidx.graphics {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class CanvasBufferedRenderer implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getBufferFormat();
+    method public int getMaxBuffers();
+    method public long getUsageFlags();
+    method public boolean isClosed();
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest obtainRenderRequest();
+    method public void releaseBuffer(android.hardware.HardwareBuffer hardwareBuffer, androidx.hardware.SyncFenceCompat? fence);
+    method public void setContentRoot(android.graphics.RenderNode renderNode);
+    method public void setLightSourceAlpha(float ambientShadowAlpha, float spotShadowAlpha);
+    method public void setLightSourceGeometry(float lightX, float lightY, float lightZ, float lightRadius);
+    property public final int bufferFormat;
+    property public final boolean isClosed;
+    property public final int maxBuffers;
+    property public final long usageFlags;
+  }
+
+  public static final class CanvasBufferedRenderer.Builder {
+    ctor public CanvasBufferedRenderer.Builder(int width, int height);
+    method public androidx.graphics.CanvasBufferedRenderer build();
+    method public androidx.graphics.CanvasBufferedRenderer.Builder setBufferFormat(int format);
+    method public androidx.graphics.CanvasBufferedRenderer.Builder setMaxBuffers(@IntRange(from=1L, to=64L) int numBuffers);
+    method public androidx.graphics.CanvasBufferedRenderer.Builder setUsageFlags(long usageFlags);
+  }
+
+  public final class CanvasBufferedRenderer.RenderRequest {
+    method public suspend Object? draw(optional boolean waitForFence, kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>);
+    method public void drawAsync(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult> callback);
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest preserveContents(boolean preserve);
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setBufferTransform(int bufferTransform);
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setColorSpace(android.graphics.ColorSpace? colorSpace);
+  }
+
+  public static final class CanvasBufferedRenderer.RenderResult {
+    ctor public CanvasBufferedRenderer.RenderResult(android.hardware.HardwareBuffer buffer, androidx.hardware.SyncFenceCompat? mFence, int mStatus);
+    method public androidx.hardware.SyncFenceCompat? getFence();
+    method public android.hardware.HardwareBuffer getHardwareBuffer();
+    method public int getStatus();
+    property public final androidx.hardware.SyncFenceCompat? fence;
+    property public final android.hardware.HardwareBuffer hardwareBuffer;
+    property public final int status;
+    field public static final androidx.graphics.CanvasBufferedRenderer.RenderResult.Companion Companion;
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static final class CanvasBufferedRenderer.RenderResult.Companion {
+  }
+
+}
+
+package androidx.graphics.lowlatency {
+
+  public final class BufferInfo {
+    method public int getFrameBufferId();
+    method public int getHeight();
+    method public int getWidth();
+    property public final int frameBufferId;
+    property public final int height;
+    property public final int width;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class CanvasFrontBufferedRenderer<T> {
+    ctor public CanvasFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.CanvasFrontBufferedRenderer.Callback<T> callback);
+    ctor public CanvasFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.CanvasFrontBufferedRenderer.Callback<T> callback, optional int bufferFormat);
+    method public void cancel();
+    method public void clear();
+    method public void commit();
+    method public int getBufferFormat();
+    method public android.graphics.ColorSpace getColorSpace();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
+    method public void renderFrontBufferedLayer(T param);
+    method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
+    method public void setColorSpace(android.graphics.ColorSpace);
+    property public final int bufferFormat;
+    property public final android.graphics.ColorSpace colorSpace;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
+    method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
+    method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+    method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat multiBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+  }
+
+  public final class FrontBufferSyncStrategy implements androidx.graphics.opengl.SyncStrategy {
+    ctor public FrontBufferSyncStrategy(long usageFlags);
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public boolean isVisible();
+    method public void setVisible(boolean);
+    property public final boolean isVisible;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class GLFrontBufferedRenderer<T> {
+    ctor public GLFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.GLFrontBufferedRenderer.Callback<T> callback);
+    ctor public GLFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.GLFrontBufferedRenderer.Callback<T> callback, optional androidx.graphics.opengl.GLRenderer? glRenderer);
+    ctor public GLFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.GLFrontBufferedRenderer.Callback<T> callback, optional androidx.graphics.opengl.GLRenderer? glRenderer, optional int bufferFormat);
+    method public void cancel();
+    method public void clear();
+    method public void commit();
+    method public void execute(Runnable runnable);
+    method public int getBufferFormat();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
+    method public void renderFrontBufferedLayer(T param);
+    method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
+    property public final int bufferFormat;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
+    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, int width, int height, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
+    method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, int width, int height, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
+    method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+    method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat multiBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class LowLatencyCanvasView extends android.view.ViewGroup {
+    ctor public LowLatencyCanvasView(android.content.Context context);
+    ctor public LowLatencyCanvasView(android.content.Context context, optional android.util.AttributeSet? attrs);
+    ctor public LowLatencyCanvasView(android.content.Context context, optional android.util.AttributeSet? attrs, optional int defStyle);
+    method public void cancel();
+    method public void clear();
+    method public void commit();
+    method public void execute(Runnable runnable);
+    method public void renderFrontBufferedLayer();
+    method public void setRenderCallback(androidx.graphics.lowlatency.LowLatencyCanvasView.Callback? callback);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface LowLatencyCanvasView.Callback {
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int width, int height);
+    method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+    method @WorkerThread public void onRedrawRequested(android.graphics.Canvas canvas, int width, int height);
+  }
+
+}
+
+package androidx.graphics.opengl {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class FrameBuffer implements java.lang.AutoCloseable {
+    ctor public FrameBuffer(androidx.graphics.opengl.egl.EGLSpec egl, android.hardware.HardwareBuffer hardwareBuffer);
+    method public void close();
+    method public android.hardware.HardwareBuffer getHardwareBuffer();
+    method public boolean isClosed();
+    method public void makeCurrent();
+    property public final android.hardware.HardwareBuffer hardwareBuffer;
+    property public final boolean isClosed;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class FrameBufferRenderer implements androidx.graphics.opengl.GLRenderer.RenderCallback {
+    ctor public FrameBufferRenderer(androidx.graphics.opengl.FrameBufferRenderer.RenderCallback frameBufferRendererCallbacks, optional androidx.graphics.opengl.SyncStrategy syncStrategy);
+    method public void clear();
+    method public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager);
+  }
+
+  public static interface FrameBufferRenderer.RenderCallback {
+    method public androidx.graphics.opengl.FrameBuffer obtainFrameBuffer(androidx.graphics.opengl.egl.EGLSpec egl);
+    method public void onDraw(androidx.graphics.opengl.egl.EGLManager eglManager);
+    method public void onDrawComplete(androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFenceCompat);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class GLFrameBufferRenderer {
+    method public void execute(Runnable runnable);
+    method public int getBufferFormat();
+    method public androidx.graphics.opengl.GLRenderer getGLRenderer();
+    method public int getMaxBuffers();
+    method public androidx.graphics.opengl.SyncStrategy getSyncStrategy();
+    method public long getUsageFlags();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseCallback);
+    method public void render();
+    property public final int bufferFormat;
+    property public final androidx.graphics.opengl.GLRenderer glRenderer;
+    property public final int maxBuffers;
+    property public final androidx.graphics.opengl.SyncStrategy syncStrategy;
+    property public final long usageFlags;
+  }
+
+  public static final class GLFrameBufferRenderer.Builder {
+    ctor public GLFrameBufferRenderer.Builder(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLFrameBufferRenderer.Callback callback);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer build();
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setBufferFormat(int format);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setGLRenderer(androidx.graphics.opengl.GLRenderer? glRenderer);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setMaxBuffers(@IntRange(from=1L, to=64L) int numBuffers);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setSyncStrategy(androidx.graphics.opengl.SyncStrategy syncStrategy);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setUsageFlags(long usageFlags);
+  }
+
+  public static interface GLFrameBufferRenderer.Callback {
+    method @WorkerThread public default void onBufferReleased(androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? releaseFence);
+    method @WorkerThread public default void onDrawComplete(androidx.graphics.surface.SurfaceControlCompat targetSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction, androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFence);
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager, int width, int height, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform);
+  }
+
+  public final class GLRenderer {
+    ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EGLSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EGLManager,? extends android.opengl.EGLConfig> eglConfigFactory);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.TextureView textureView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget createRenderTarget(int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void execute(Runnable runnable);
+    method public boolean isRunning();
+    method public void registerEGLContextCallback(androidx.graphics.opengl.GLRenderer.EGLContextCallback callback);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void start();
+    method public void start(optional String name);
+    method public void stop(boolean cancelPending);
+    method public void stop(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer,kotlin.Unit>? onStop);
+    method public void unregisterEGLContextCallback(androidx.graphics.opengl.GLRenderer.EGLContextCallback callback);
+    field public static final androidx.graphics.opengl.GLRenderer.Companion Companion;
+  }
+
+  public static final class GLRenderer.Companion {
+  }
+
+  public static interface GLRenderer.EGLContextCallback {
+    method @WorkerThread public void onEGLContextCreated(androidx.graphics.opengl.egl.EGLManager eglManager);
+    method @WorkerThread public void onEGLContextDestroyed(androidx.graphics.opengl.egl.EGLManager eglManager);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLRenderer.RenderCallback {
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager);
+    method @WorkerThread public default android.opengl.EGLSurface? onSurfaceCreated(androidx.graphics.opengl.egl.EGLSpec spec, android.opengl.EGLConfig config, android.view.Surface surface, int width, int height);
+  }
+
+  public static final class GLRenderer.RenderTarget {
+    method public void detach(boolean cancelPending);
+    method public void detach(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public boolean isAttached();
+    method public void requestRender();
+    method public void requestRender(optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void resize(int width, int height);
+    method public void resize(int width, int height, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+  }
+
+  public interface SyncStrategy {
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    field public static final androidx.graphics.opengl.SyncStrategy ALWAYS;
+    field public static final androidx.graphics.opengl.SyncStrategy.Companion Companion;
+  }
+
+  public static final class SyncStrategy.Companion {
+  }
+
+}
+
+package androidx.graphics.opengl.egl {
+
+  public final class EGLConfigAttributes {
+    method public int[] toArray();
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes.Companion Companion;
+    field public static final int EGL_COLOR_COMPONENT_TYPE_EXT = 13113; // 0x3339
+    field public static final int EGL_COLOR_COMPONENT_TYPE_FIXED_EXT = 13114; // 0x333a
+    field public static final int EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT = 13115; // 0x333b
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes RGBA_1010102;
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes RGBA_8888;
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes RGBA_F16;
+  }
+
+  public static final class EGLConfigAttributes.Builder {
+    method public androidx.graphics.opengl.egl.EGLConfigAttributes build();
+    method public void include(androidx.graphics.opengl.egl.EGLConfigAttributes attributes);
+    method public androidx.graphics.opengl.egl.EGLConfigAttributes.Builder setAttribute(int attribute, int value);
+    method @kotlin.jvm.JvmSynthetic public infix void to(int, int that);
+  }
+
+  public static final class EGLConfigAttributes.Companion {
+  }
+
+  public final class EGLConfigAttributesKt {
+    method @kotlin.jvm.JvmSynthetic public static inline androidx.graphics.opengl.egl.EGLConfigAttributes EGLConfigAttributes(kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EGLConfigAttributes.Builder,kotlin.Unit> block);
+  }
+
+  public final class EGLException extends java.lang.RuntimeException {
+    ctor public EGLException(int error, optional String msg);
+    method public int getError();
+    method public String getMsg();
+    property public final int error;
+    property public String message;
+    property public final String msg;
+  }
+
+  public final class EGLManager {
+    ctor public EGLManager(optional androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public android.opengl.EGLContext createContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface getCurrentDrawSurface();
+    method public android.opengl.EGLSurface getCurrentReadSurface();
+    method public android.opengl.EGLSurface getDefaultSurface();
+    method public android.opengl.EGLConfig? getEGLConfig();
+    method public android.opengl.EGLContext? getEGLContext();
+    method public androidx.graphics.opengl.egl.EGLSpec getEGLSpec();
+    method public androidx.graphics.opengl.egl.EGLVersion getEGLVersion();
+    method public void initialize();
+    method public boolean isExtensionSupported(String extensionName);
+    method public android.opengl.EGLConfig? loadConfig(androidx.graphics.opengl.egl.EGLConfigAttributes configAttributes);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface, optional android.opengl.EGLSurface readSurface);
+    method public void release();
+    method public void swapAndFlushBuffers();
+    property public final android.opengl.EGLSurface currentDrawSurface;
+    property public final android.opengl.EGLSurface currentReadSurface;
+    property public final android.opengl.EGLSurface defaultSurface;
+    property public final android.opengl.EGLConfig? eglConfig;
+    property public final android.opengl.EGLContext? eglContext;
+    property public final androidx.graphics.opengl.egl.EGLSpec eglSpec;
+    property public final androidx.graphics.opengl.egl.EGLVersion eglVersion;
+    field public static final androidx.graphics.opengl.egl.EGLManager.Companion Companion;
+  }
+
+  public static final class EGLManager.Companion {
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface EGLSpec {
+    method public int eglClientWaitSyncKHR(androidx.opengl.EGLSyncKHR sync, int flags, long timeoutNanos);
+    method public android.opengl.EGLContext eglCreateContext(android.opengl.EGLConfig config);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.opengl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.hardware.HardwareBuffer hardwareBuffer);
+    method public android.opengl.EGLSurface eglCreatePBufferSurface(android.opengl.EGLConfig config, androidx.graphics.opengl.egl.EGLConfigAttributes? configAttributes);
+    method public androidx.opengl.EGLSyncKHR? eglCreateSyncKHR(int type, androidx.graphics.opengl.egl.EGLConfigAttributes? attributes);
+    method public android.opengl.EGLSurface eglCreateWindowSurface(android.opengl.EGLConfig config, android.view.Surface surface, androidx.graphics.opengl.egl.EGLConfigAttributes? configAttributes);
+    method public void eglDestroyContext(android.opengl.EGLContext eglContext);
+    method public boolean eglDestroyImageKHR(androidx.opengl.EGLImageKHR image);
+    method public boolean eglDestroySurface(android.opengl.EGLSurface surface);
+    method public boolean eglDestroySyncKHR(androidx.opengl.EGLSyncKHR sync);
+    method public android.opengl.EGLSurface eglGetCurrentDrawSurface();
+    method public android.opengl.EGLSurface eglGetCurrentReadSurface();
+    method public int eglGetError();
+    method public boolean eglGetSyncAttribKHR(androidx.opengl.EGLSyncKHR sync, int attribute, int[] value, int offset);
+    method public androidx.graphics.opengl.egl.EGLVersion eglInitialize();
+    method public boolean eglMakeCurrent(android.opengl.EGLContext context, android.opengl.EGLSurface drawSurface, android.opengl.EGLSurface readSurface);
+    method public String eglQueryString(int nameId);
+    method public boolean eglQuerySurface(android.opengl.EGLSurface surface, int attribute, int[] result, int offset);
+    method public boolean eglSwapBuffers(android.opengl.EGLSurface surface);
+    method public default String getErrorMessage();
+    method public static String getStatusString(int error);
+    method public android.opengl.EGLConfig? loadConfig(androidx.graphics.opengl.egl.EGLConfigAttributes configAttributes);
+    field public static final androidx.graphics.opengl.egl.EGLSpec.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EGLSpec V14;
+  }
+
+  public static final class EGLSpec.Companion {
+    method public String getStatusString(int error);
+  }
+
+  public final class EGLVersion {
+    ctor public EGLVersion(int major, int minor);
+    method public int component1();
+    method public int component2();
+    method public androidx.graphics.opengl.egl.EGLVersion copy(int major, int minor);
+    method public int getMajor();
+    method public int getMinor();
+    property public final int major;
+    property public final int minor;
+    field public static final androidx.graphics.opengl.egl.EGLVersion.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EGLVersion Unknown;
+    field public static final androidx.graphics.opengl.egl.EGLVersion V14;
+    field public static final androidx.graphics.opengl.egl.EGLVersion V15;
+  }
+
+  public static final class EGLVersion.Companion {
+  }
+
+}
+
+package androidx.graphics.surface {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class SurfaceControlCompat {
+    method public boolean isValid();
+    method public void release();
+    field public static final int BUFFER_TRANSFORM_IDENTITY = 0; // 0x0
+    field public static final int BUFFER_TRANSFORM_MIRROR_HORIZONTAL = 1; // 0x1
+    field public static final int BUFFER_TRANSFORM_MIRROR_VERTICAL = 2; // 0x2
+    field public static final int BUFFER_TRANSFORM_ROTATE_180 = 3; // 0x3
+    field public static final int BUFFER_TRANSFORM_ROTATE_270 = 7; // 0x7
+    field public static final int BUFFER_TRANSFORM_ROTATE_90 = 4; // 0x4
+    field public static final int CHANGE_FRAME_RATE_ALWAYS = 1; // 0x1
+    field public static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0; // 0x0
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Companion Companion;
+    field public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0; // 0x0
+    field public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1; // 0x1
+  }
+
+  public static final class SurfaceControlCompat.Builder {
+    ctor public SurfaceControlCompat.Builder();
+    method public androidx.graphics.surface.SurfaceControlCompat build();
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setName(String name);
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setParent(android.view.SurfaceView surfaceView);
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setParent(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+  }
+
+  public static final class SurfaceControlCompat.Companion {
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final class SurfaceControlCompat.Transaction implements java.lang.AutoCloseable {
+    ctor public SurfaceControlCompat.Transaction();
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public androidx.graphics.surface.SurfaceControlCompat.Transaction addTransactionCommittedListener(java.util.concurrent.Executor executor, androidx.graphics.surface.SurfaceControlCompat.TransactionCommittedListener listener);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction clearFrameRate(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+    method public void close();
+    method public void commit();
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void commitTransactionOnDraw(android.view.AttachedSurfaceControl attachedSurfaceControl);
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public androidx.graphics.surface.SurfaceControlCompat.Transaction reparent(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.view.AttachedSurfaceControl attachedSurfaceControl);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction reparent(androidx.graphics.surface.SurfaceControlCompat surfaceControl, androidx.graphics.surface.SurfaceControlCompat? newParent);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setAlpha(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float alpha);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBuffer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.hardware.HardwareBuffer? buffer);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBuffer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.hardware.HardwareBuffer? buffer, optional androidx.hardware.SyncFenceCompat? fence);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBuffer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.hardware.HardwareBuffer? buffer, optional androidx.hardware.SyncFenceCompat? fence, optional kotlin.jvm.functions.Function1<? super androidx.hardware.SyncFenceCompat,kotlin.Unit>? releaseCallback);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBufferTransform(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int transformation);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setCrop(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Rect? crop);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setDamageRegion(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Region? region);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setDataSpace(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int dataSpace);
+    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public androidx.graphics.surface.SurfaceControlCompat.Transaction setExtendedRangeBrightness(androidx.graphics.surface.SurfaceControlCompat surfaceControl, @FloatRange(from=1.0, fromInclusive=true) float currentBufferRatio, @FloatRange(from=1.0, fromInclusive=true) float desiredRatio);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setFrameRate(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float frameRate, int compatibility, int changeFrameRateStrategy);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setLayer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int z);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setOpaque(androidx.graphics.surface.SurfaceControlCompat surfaceControl, boolean isOpaque);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setPosition(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float x, float y);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setScale(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float scaleX, float scaleY);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setVisibility(androidx.graphics.surface.SurfaceControlCompat surfaceControl, boolean visible);
+  }
+
+  public static interface SurfaceControlCompat.TransactionCommittedListener {
+    method public void onTransactionCommitted();
+  }
+
+}
+
+package androidx.hardware {
+
+  public final class DataSpace {
+    field public static final androidx.hardware.DataSpace.Companion Companion;
+    field public static final int DATASPACE_ADOBE_RGB = 151715840; // 0x90b0000
+    field public static final int DATASPACE_BT2020 = 147193856; // 0x8c60000
+    field public static final int DATASPACE_BT2020_HLG = 168165376; // 0xa060000
+    field public static final int DATASPACE_BT2020_PQ = 163971072; // 0x9c60000
+    field public static final int DATASPACE_BT601_525 = 281280512; // 0x10c40000
+    field public static final int DATASPACE_BT601_625 = 281149440; // 0x10c20000
+    field public static final int DATASPACE_BT709 = 281083904; // 0x10c10000
+    field public static final int DATASPACE_DCI_P3 = 155844608; // 0x94a0000
+    field public static final int DATASPACE_DEPTH = 4096; // 0x1000
+    field public static final int DATASPACE_DISPLAY_P3 = 143261696; // 0x88a0000
+    field public static final int DATASPACE_DYNAMIC_DEPTH = 4098; // 0x1002
+    field public static final int DATASPACE_HEIF = 4100; // 0x1004
+    field public static final int DATASPACE_JFIF = 146931712; // 0x8c20000
+    field public static final int DATASPACE_JPEG_R = 4101; // 0x1005
+    field public static final int DATASPACE_SCRGB = 411107328; // 0x18810000
+    field public static final int DATASPACE_SCRGB_LINEAR = 406913024; // 0x18410000
+    field public static final int DATASPACE_SRGB = 142671872; // 0x8810000
+    field public static final int DATASPACE_SRGB_LINEAR = 138477568; // 0x8410000
+    field public static final int DATASPACE_UNKNOWN = 0; // 0x0
+    field public static final int RANGE_EXTENDED = 402653184; // 0x18000000
+    field public static final int RANGE_FULL = 134217728; // 0x8000000
+    field public static final int RANGE_LIMITED = 268435456; // 0x10000000
+    field public static final int RANGE_UNSPECIFIED = 0; // 0x0
+  }
+
+  public static final class DataSpace.Companion {
+  }
+
+  public final class SyncFenceCompat implements java.lang.AutoCloseable {
+    method public boolean await(long timeoutNanos);
+    method public boolean awaitForever();
+    method public void close();
+    method public static androidx.hardware.SyncFenceCompat createNativeSyncFence();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public long getSignalTimeNanos();
+    method public boolean isValid();
+    field public static final androidx.hardware.SyncFenceCompat.Companion Companion;
+    field public static final long SIGNAL_TIME_INVALID = -1L; // 0xffffffffffffffffL
+    field public static final long SIGNAL_TIME_PENDING = 9223372036854775807L; // 0x7fffffffffffffffL
+  }
+
+  public static final class SyncFenceCompat.Companion {
+    method public androidx.hardware.SyncFenceCompat createNativeSyncFence();
+  }
+
+}
+
+package androidx.opengl {
+
+  public final class EGLExt {
+    method public static int eglClientWaitSyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int flags, long timeoutNanos);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.opengl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public static androidx.opengl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, androidx.graphics.opengl.egl.EGLConfigAttributes? attributes);
+    method public static boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLImageKHR image);
+    method public static boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR eglSync);
+    method public static boolean eglGetSyncAttribKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int attribute, int[] value, int offset);
+    method public static void glEGLImageTargetTexture2DOES(int target, androidx.opengl.EGLImageKHR image);
+    method public static java.util.Set<java.lang.String> parseExtensions(String queryString);
+    field public static final androidx.opengl.EGLExt.Companion Companion;
+    field public static final String EGL_ANDROID_CLIENT_BUFFER = "EGL_ANDROID_get_native_client_buffer";
+    field public static final String EGL_ANDROID_IMAGE_NATIVE_BUFFER = "EGL_ANDROID_image_native_buffer";
+    field public static final String EGL_ANDROID_NATIVE_FENCE_SYNC = "EGL_ANDROID_native_fence_sync";
+    field public static final int EGL_CONDITION_SATISFIED_KHR = 12534; // 0x30f6
+    field public static final String EGL_EXT_BUFFER_AGE = "EGL_EXT_buffer_age";
+    field public static final String EGL_EXT_GL_COLORSPACE_BT2020_PQ = "EGL_EXT_gl_colorspace_bt2020_pq";
+    field public static final String EGL_EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+    field public static final String EGL_EXT_GL_COLORSPACE_SCRGB = "EGL_EXT_gl_colorspace_scrgb";
+    field public static final String EGL_EXT_PIXEL_FORMAT_FLOAT = "EGL_EXT_pixel_format_float";
+    field public static final int EGL_FALSE = 0; // 0x0
+    field public static final long EGL_FOREVER_KHR = -1L; // 0xffffffffffffffffL
+    field public static final String EGL_IMG_CONTEXT_PRIORITY = "EGL_IMG_context_priority";
+    field public static final String EGL_KHR_FENCE_SYNC = "EGL_KHR_fence_sync";
+    field public static final String EGL_KHR_GL_COLORSPACE = "EGL_KHR_gl_colorspace";
+    field public static final String EGL_KHR_IMAGE = "EGL_KHR_image";
+    field public static final String EGL_KHR_IMAGE_BASE = "EGL_KHR_image_base";
+    field public static final String EGL_KHR_NO_CONFIG_CONTEXT = "EGL_KHR_no_config_context";
+    field public static final String EGL_KHR_PARTIAL_UPDATE = "EGL_KHR_partial_update";
+    field public static final String EGL_KHR_SURFACELESS_CONTEXT = "EGL_KHR_surfaceless_context";
+    field public static final String EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE = "EGL_KHR_swap_buffers_with_damage";
+    field public static final String EGL_KHR_WAIT_SYNC = "EGL_KHR_wait_sync";
+    field public static final int EGL_SIGNALED_KHR = 12530; // 0x30f2
+    field public static final int EGL_SYNC_CONDITION_KHR = 12536; // 0x30f8
+    field public static final int EGL_SYNC_FENCE_KHR = 12537; // 0x30f9
+    field public static final int EGL_SYNC_FLUSH_COMMANDS_BIT_KHR = 1; // 0x1
+    field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144
+    field public static final int EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR = 12528; // 0x30f0
+    field public static final int EGL_SYNC_STATUS_KHR = 12529; // 0x30f1
+    field public static final int EGL_SYNC_TYPE_KHR = 12535; // 0x30f7
+    field public static final int EGL_TIMEOUT_EXPIRED_KHR = 12533; // 0x30f5
+    field public static final int EGL_TRUE = 1; // 0x1
+    field public static final int EGL_UNSIGNALED_KHR = 12531; // 0x30f3
+  }
+
+  public static final class EGLExt.Companion {
+    method public int eglClientWaitSyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int flags, long timeoutNanos);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.opengl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public androidx.opengl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, androidx.graphics.opengl.egl.EGLConfigAttributes? attributes);
+    method public boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLImageKHR image);
+    method public boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR eglSync);
+    method public boolean eglGetSyncAttribKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int attribute, int[] value, int offset);
+    method public void glEGLImageTargetTexture2DOES(int target, androidx.opengl.EGLImageKHR image);
+    method public java.util.Set<java.lang.String> parseExtensions(String queryString);
+  }
+
+  public interface EGLHandle {
+    method public long getNativeHandle();
+    property public abstract long nativeHandle;
+  }
+
+  public final class EGLImageKHR implements androidx.opengl.EGLHandle {
+    ctor public EGLImageKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLSyncKHR implements androidx.opengl.EGLHandle {
+    ctor public EGLSyncKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+}
+
diff --git a/graphics/graphics-core/api/current.ignore b/graphics/graphics-core/api/current.ignore
new file mode 100644
index 0000000..af77f0d
--- /dev/null
+++ b/graphics/graphics-core/api/current.ignore
@@ -0,0 +1,11 @@
+// Baseline format: 1.0
+AddedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#draw(boolean, kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>):
+    Added method androidx.graphics.CanvasBufferedRenderer.RenderRequest.draw(boolean,kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>)
+AddedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#drawAsync(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>):
+    Added method androidx.graphics.CanvasBufferedRenderer.RenderRequest.drawAsync(java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>)
+
+
+RemovedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#draw(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>):
+    Removed method androidx.graphics.CanvasBufferedRenderer.RenderRequest.draw(java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>)
+RemovedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#drawSync(boolean):
+    Removed method androidx.graphics.CanvasBufferedRenderer.RenderRequest.drawSync(boolean)
diff --git a/graphics/graphics-core/api/current.txt b/graphics/graphics-core/api/current.txt
index e1b45be..bcf0955 100644
--- a/graphics/graphics-core/api/current.txt
+++ b/graphics/graphics-core/api/current.txt
@@ -13,6 +13,7 @@
     method public void setLightSourceAlpha(float ambientShadowAlpha, float spotShadowAlpha);
     method public void setLightSourceGeometry(float lightX, float lightY, float lightZ, float lightRadius);
     property public final int bufferFormat;
+    property public final boolean isClosed;
     property public final int maxBuffers;
     property public final long usageFlags;
   }
@@ -26,7 +27,8 @@
   }
 
   public final class CanvasBufferedRenderer.RenderRequest {
-    method public void draw(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult> callback);
+    method public suspend Object? draw(optional boolean waitForFence, kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>);
+    method public void drawAsync(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult> callback);
     method public androidx.graphics.CanvasBufferedRenderer.RenderRequest preserveContents(boolean preserve);
     method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setBufferTransform(int bufferTransform);
     method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setColorSpace(android.graphics.ColorSpace? colorSpace);
@@ -88,7 +90,7 @@
 
   public final class FrontBufferSyncStrategy implements androidx.graphics.opengl.SyncStrategy {
     ctor public FrontBufferSyncStrategy(long usageFlags);
-    method @RequiresApi(android.os.Build.VERSION_CODES.KITKAT) public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
     method public boolean isVisible();
     method public void setVisible(boolean);
     property public final boolean isVisible;
@@ -243,7 +245,7 @@
   }
 
   public interface SyncStrategy {
-    method @RequiresApi(android.os.Build.VERSION_CODES.KITKAT) public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
     field public static final androidx.graphics.opengl.SyncStrategy ALWAYS;
     field public static final androidx.graphics.opengl.SyncStrategy.Companion Companion;
   }
@@ -463,7 +465,7 @@
   public static final class DataSpace.Companion {
   }
 
-  @RequiresApi(android.os.Build.VERSION_CODES.KITKAT) public final class SyncFenceCompat implements java.lang.AutoCloseable {
+  public final class SyncFenceCompat implements java.lang.AutoCloseable {
     method public boolean await(long timeoutNanos);
     method public boolean awaitForever();
     method public void close();
diff --git a/graphics/graphics-core/api/res-1.0.0-beta01.txt b/graphics/graphics-core/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/graphics/graphics-core/api/res-1.0.0-beta01.txt
diff --git a/graphics/graphics-core/api/restricted_1.0.0-beta01.txt b/graphics/graphics-core/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..0c3a248
--- /dev/null
+++ b/graphics/graphics-core/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,562 @@
+// Signature format: 4.0
+package androidx.graphics {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class CanvasBufferedRenderer implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getBufferFormat();
+    method public int getMaxBuffers();
+    method public long getUsageFlags();
+    method public boolean isClosed();
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest obtainRenderRequest();
+    method public void releaseBuffer(android.hardware.HardwareBuffer hardwareBuffer, androidx.hardware.SyncFenceCompat? fence);
+    method public void setContentRoot(android.graphics.RenderNode renderNode);
+    method public void setLightSourceAlpha(float ambientShadowAlpha, float spotShadowAlpha);
+    method public void setLightSourceGeometry(float lightX, float lightY, float lightZ, float lightRadius);
+    property public final int bufferFormat;
+    property public final boolean isClosed;
+    property public final int maxBuffers;
+    property public final long usageFlags;
+  }
+
+  public static final class CanvasBufferedRenderer.Builder {
+    ctor public CanvasBufferedRenderer.Builder(int width, int height);
+    method public androidx.graphics.CanvasBufferedRenderer build();
+    method public androidx.graphics.CanvasBufferedRenderer.Builder setBufferFormat(int format);
+    method public androidx.graphics.CanvasBufferedRenderer.Builder setMaxBuffers(@IntRange(from=1L, to=64L) int numBuffers);
+    method public androidx.graphics.CanvasBufferedRenderer.Builder setUsageFlags(long usageFlags);
+  }
+
+  public final class CanvasBufferedRenderer.RenderRequest {
+    method public suspend Object? draw(optional boolean waitForFence, kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>);
+    method public void drawAsync(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult> callback);
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest preserveContents(boolean preserve);
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setBufferTransform(int bufferTransform);
+    method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setColorSpace(android.graphics.ColorSpace? colorSpace);
+  }
+
+  public static final class CanvasBufferedRenderer.RenderResult {
+    ctor public CanvasBufferedRenderer.RenderResult(android.hardware.HardwareBuffer buffer, androidx.hardware.SyncFenceCompat? mFence, int mStatus);
+    method public androidx.hardware.SyncFenceCompat? getFence();
+    method public android.hardware.HardwareBuffer getHardwareBuffer();
+    method public int getStatus();
+    property public final androidx.hardware.SyncFenceCompat? fence;
+    property public final android.hardware.HardwareBuffer hardwareBuffer;
+    property public final int status;
+    field public static final androidx.graphics.CanvasBufferedRenderer.RenderResult.Companion Companion;
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static final class CanvasBufferedRenderer.RenderResult.Companion {
+  }
+
+}
+
+package androidx.graphics.lowlatency {
+
+  public final class BufferInfo {
+    method public int getFrameBufferId();
+    method public int getHeight();
+    method public int getWidth();
+    property public final int frameBufferId;
+    property public final int height;
+    property public final int width;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class CanvasFrontBufferedRenderer<T> {
+    ctor public CanvasFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.CanvasFrontBufferedRenderer.Callback<T> callback);
+    ctor public CanvasFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.CanvasFrontBufferedRenderer.Callback<T> callback, optional int bufferFormat);
+    method public void cancel();
+    method public void clear();
+    method public void commit();
+    method public int getBufferFormat();
+    method public android.graphics.ColorSpace getColorSpace();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
+    method public void renderFrontBufferedLayer(T param);
+    method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
+    method public void setColorSpace(android.graphics.ColorSpace);
+    property public final int bufferFormat;
+    property public final android.graphics.ColorSpace colorSpace;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
+    method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
+    method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+    method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat multiBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+  }
+
+  public final class FrontBufferSyncStrategy implements androidx.graphics.opengl.SyncStrategy {
+    ctor public FrontBufferSyncStrategy(long usageFlags);
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public boolean isVisible();
+    method public void setVisible(boolean);
+    property public final boolean isVisible;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class GLFrontBufferedRenderer<T> {
+    ctor public GLFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.GLFrontBufferedRenderer.Callback<T> callback);
+    ctor public GLFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.GLFrontBufferedRenderer.Callback<T> callback, optional androidx.graphics.opengl.GLRenderer? glRenderer);
+    ctor public GLFrontBufferedRenderer(android.view.SurfaceView surfaceView, androidx.graphics.lowlatency.GLFrontBufferedRenderer.Callback<T> callback, optional androidx.graphics.opengl.GLRenderer? glRenderer, optional int bufferFormat);
+    method public void cancel();
+    method public void clear();
+    method public void commit();
+    method public void execute(Runnable runnable);
+    method public int getBufferFormat();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
+    method public void renderFrontBufferedLayer(T param);
+    method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
+    property public final int bufferFormat;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
+    method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, int width, int height, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
+    method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, int width, int height, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
+    method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+    method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat multiBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class LowLatencyCanvasView extends android.view.ViewGroup {
+    ctor public LowLatencyCanvasView(android.content.Context context);
+    ctor public LowLatencyCanvasView(android.content.Context context, optional android.util.AttributeSet? attrs);
+    ctor public LowLatencyCanvasView(android.content.Context context, optional android.util.AttributeSet? attrs, optional int defStyle);
+    method public void cancel();
+    method public void clear();
+    method public void commit();
+    method public void execute(Runnable runnable);
+    method public void renderFrontBufferedLayer();
+    method public void setRenderCallback(androidx.graphics.lowlatency.LowLatencyCanvasView.Callback? callback);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface LowLatencyCanvasView.Callback {
+    method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int width, int height);
+    method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
+    method @WorkerThread public void onRedrawRequested(android.graphics.Canvas canvas, int width, int height);
+  }
+
+}
+
+package androidx.graphics.opengl {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class FrameBuffer implements java.lang.AutoCloseable {
+    ctor public FrameBuffer(androidx.graphics.opengl.egl.EGLSpec egl, android.hardware.HardwareBuffer hardwareBuffer);
+    method public void close();
+    method public android.hardware.HardwareBuffer getHardwareBuffer();
+    method public boolean isClosed();
+    method public void makeCurrent();
+    property public final android.hardware.HardwareBuffer hardwareBuffer;
+    property public final boolean isClosed;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class FrameBufferRenderer implements androidx.graphics.opengl.GLRenderer.RenderCallback {
+    ctor public FrameBufferRenderer(androidx.graphics.opengl.FrameBufferRenderer.RenderCallback frameBufferRendererCallbacks, optional androidx.graphics.opengl.SyncStrategy syncStrategy);
+    method public void clear();
+    method public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager);
+  }
+
+  public static interface FrameBufferRenderer.RenderCallback {
+    method public androidx.graphics.opengl.FrameBuffer obtainFrameBuffer(androidx.graphics.opengl.egl.EGLSpec egl);
+    method public void onDraw(androidx.graphics.opengl.egl.EGLManager eglManager);
+    method public void onDrawComplete(androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFenceCompat);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class GLFrameBufferRenderer {
+    method public void execute(Runnable runnable);
+    method public int getBufferFormat();
+    method public androidx.graphics.opengl.GLRenderer getGLRenderer();
+    method public int getMaxBuffers();
+    method public androidx.graphics.opengl.SyncStrategy getSyncStrategy();
+    method public long getUsageFlags();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseCallback);
+    method public void render();
+    property public final int bufferFormat;
+    property public final androidx.graphics.opengl.GLRenderer glRenderer;
+    property public final int maxBuffers;
+    property public final androidx.graphics.opengl.SyncStrategy syncStrategy;
+    property public final long usageFlags;
+  }
+
+  public static final class GLFrameBufferRenderer.Builder {
+    ctor public GLFrameBufferRenderer.Builder(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLFrameBufferRenderer.Callback callback);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer build();
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setBufferFormat(int format);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setGLRenderer(androidx.graphics.opengl.GLRenderer? glRenderer);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setMaxBuffers(@IntRange(from=1L, to=64L) int numBuffers);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setSyncStrategy(androidx.graphics.opengl.SyncStrategy syncStrategy);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setUsageFlags(long usageFlags);
+  }
+
+  public static interface GLFrameBufferRenderer.Callback {
+    method @WorkerThread public default void onBufferReleased(androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? releaseFence);
+    method @WorkerThread public default void onDrawComplete(androidx.graphics.surface.SurfaceControlCompat targetSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction, androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFence);
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager, int width, int height, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform);
+  }
+
+  public final class GLRenderer {
+    ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EGLSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EGLManager,? extends android.opengl.EGLConfig> eglConfigFactory);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.TextureView textureView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget createRenderTarget(int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void execute(Runnable runnable);
+    method public boolean isRunning();
+    method public void registerEGLContextCallback(androidx.graphics.opengl.GLRenderer.EGLContextCallback callback);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void start();
+    method public void start(optional String name);
+    method public void stop(boolean cancelPending);
+    method public void stop(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer,kotlin.Unit>? onStop);
+    method public void unregisterEGLContextCallback(androidx.graphics.opengl.GLRenderer.EGLContextCallback callback);
+    field public static final androidx.graphics.opengl.GLRenderer.Companion Companion;
+  }
+
+  public static final class GLRenderer.Companion {
+  }
+
+  public static interface GLRenderer.EGLContextCallback {
+    method @WorkerThread public void onEGLContextCreated(androidx.graphics.opengl.egl.EGLManager eglManager);
+    method @WorkerThread public void onEGLContextDestroyed(androidx.graphics.opengl.egl.EGLManager eglManager);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface GLRenderer.RenderCallback {
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager);
+    method @WorkerThread public default android.opengl.EGLSurface? onSurfaceCreated(androidx.graphics.opengl.egl.EGLSpec spec, android.opengl.EGLConfig config, android.view.Surface surface, int width, int height);
+  }
+
+  public static final class GLRenderer.RenderTarget {
+    method public void detach(boolean cancelPending);
+    method public void detach(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public boolean isAttached();
+    method public void requestRender();
+    method public void requestRender(optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void resize(int width, int height);
+    method public void resize(int width, int height, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+  }
+
+  public interface SyncStrategy {
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    field public static final androidx.graphics.opengl.SyncStrategy ALWAYS;
+    field public static final androidx.graphics.opengl.SyncStrategy.Companion Companion;
+  }
+
+  public static final class SyncStrategy.Companion {
+  }
+
+}
+
+package androidx.graphics.opengl.egl {
+
+  public final class EGLConfigAttributes {
+    method public int[] toArray();
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes.Companion Companion;
+    field public static final int EGL_COLOR_COMPONENT_TYPE_EXT = 13113; // 0x3339
+    field public static final int EGL_COLOR_COMPONENT_TYPE_FIXED_EXT = 13114; // 0x333a
+    field public static final int EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT = 13115; // 0x333b
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes RGBA_1010102;
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes RGBA_8888;
+    field public static final androidx.graphics.opengl.egl.EGLConfigAttributes RGBA_F16;
+  }
+
+  public static final class EGLConfigAttributes.Builder {
+    ctor @kotlin.PublishedApi internal EGLConfigAttributes.Builder();
+    method public androidx.graphics.opengl.egl.EGLConfigAttributes build();
+    method public void include(androidx.graphics.opengl.egl.EGLConfigAttributes attributes);
+    method public androidx.graphics.opengl.egl.EGLConfigAttributes.Builder setAttribute(int attribute, int value);
+    method @kotlin.jvm.JvmSynthetic public infix void to(int, int that);
+  }
+
+  public static final class EGLConfigAttributes.Companion {
+  }
+
+  public final class EGLConfigAttributesKt {
+    method @kotlin.jvm.JvmSynthetic public static inline androidx.graphics.opengl.egl.EGLConfigAttributes EGLConfigAttributes(kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EGLConfigAttributes.Builder,kotlin.Unit> block);
+  }
+
+  public final class EGLException extends java.lang.RuntimeException {
+    ctor public EGLException(int error, optional String msg);
+    method public int getError();
+    method public String getMsg();
+    property public final int error;
+    property public String message;
+    property public final String msg;
+  }
+
+  public final class EGLManager {
+    ctor public EGLManager(optional androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public android.opengl.EGLContext createContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface getCurrentDrawSurface();
+    method public android.opengl.EGLSurface getCurrentReadSurface();
+    method public android.opengl.EGLSurface getDefaultSurface();
+    method public android.opengl.EGLConfig? getEGLConfig();
+    method public android.opengl.EGLContext? getEGLContext();
+    method public androidx.graphics.opengl.egl.EGLSpec getEGLSpec();
+    method public androidx.graphics.opengl.egl.EGLVersion getEGLVersion();
+    method public void initialize();
+    method public boolean isExtensionSupported(String extensionName);
+    method public android.opengl.EGLConfig? loadConfig(androidx.graphics.opengl.egl.EGLConfigAttributes configAttributes);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface, optional android.opengl.EGLSurface readSurface);
+    method public void release();
+    method public void swapAndFlushBuffers();
+    property public final android.opengl.EGLSurface currentDrawSurface;
+    property public final android.opengl.EGLSurface currentReadSurface;
+    property public final android.opengl.EGLSurface defaultSurface;
+    property public final android.opengl.EGLConfig? eglConfig;
+    property public final android.opengl.EGLContext? eglContext;
+    property public final androidx.graphics.opengl.egl.EGLSpec eglSpec;
+    property public final androidx.graphics.opengl.egl.EGLVersion eglVersion;
+    field public static final androidx.graphics.opengl.egl.EGLManager.Companion Companion;
+  }
+
+  public static final class EGLManager.Companion {
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface EGLSpec {
+    method public int eglClientWaitSyncKHR(androidx.opengl.EGLSyncKHR sync, int flags, long timeoutNanos);
+    method public android.opengl.EGLContext eglCreateContext(android.opengl.EGLConfig config);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.opengl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.hardware.HardwareBuffer hardwareBuffer);
+    method public android.opengl.EGLSurface eglCreatePBufferSurface(android.opengl.EGLConfig config, androidx.graphics.opengl.egl.EGLConfigAttributes? configAttributes);
+    method public androidx.opengl.EGLSyncKHR? eglCreateSyncKHR(int type, androidx.graphics.opengl.egl.EGLConfigAttributes? attributes);
+    method public android.opengl.EGLSurface eglCreateWindowSurface(android.opengl.EGLConfig config, android.view.Surface surface, androidx.graphics.opengl.egl.EGLConfigAttributes? configAttributes);
+    method public void eglDestroyContext(android.opengl.EGLContext eglContext);
+    method public boolean eglDestroyImageKHR(androidx.opengl.EGLImageKHR image);
+    method public boolean eglDestroySurface(android.opengl.EGLSurface surface);
+    method public boolean eglDestroySyncKHR(androidx.opengl.EGLSyncKHR sync);
+    method public android.opengl.EGLSurface eglGetCurrentDrawSurface();
+    method public android.opengl.EGLSurface eglGetCurrentReadSurface();
+    method public int eglGetError();
+    method public boolean eglGetSyncAttribKHR(androidx.opengl.EGLSyncKHR sync, int attribute, int[] value, int offset);
+    method public androidx.graphics.opengl.egl.EGLVersion eglInitialize();
+    method public boolean eglMakeCurrent(android.opengl.EGLContext context, android.opengl.EGLSurface drawSurface, android.opengl.EGLSurface readSurface);
+    method public String eglQueryString(int nameId);
+    method public boolean eglQuerySurface(android.opengl.EGLSurface surface, int attribute, int[] result, int offset);
+    method public boolean eglSwapBuffers(android.opengl.EGLSurface surface);
+    method public default String getErrorMessage();
+    method public static String getStatusString(int error);
+    method public android.opengl.EGLConfig? loadConfig(androidx.graphics.opengl.egl.EGLConfigAttributes configAttributes);
+    field public static final androidx.graphics.opengl.egl.EGLSpec.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EGLSpec V14;
+  }
+
+  public static final class EGLSpec.Companion {
+    method public String getStatusString(int error);
+  }
+
+  public final class EGLVersion {
+    ctor public EGLVersion(int major, int minor);
+    method public int component1();
+    method public int component2();
+    method public androidx.graphics.opengl.egl.EGLVersion copy(int major, int minor);
+    method public int getMajor();
+    method public int getMinor();
+    property public final int major;
+    property public final int minor;
+    field public static final androidx.graphics.opengl.egl.EGLVersion.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EGLVersion Unknown;
+    field public static final androidx.graphics.opengl.egl.EGLVersion V14;
+    field public static final androidx.graphics.opengl.egl.EGLVersion V15;
+  }
+
+  public static final class EGLVersion.Companion {
+  }
+
+}
+
+package androidx.graphics.surface {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class SurfaceControlCompat {
+    method public boolean isValid();
+    method public void release();
+    field public static final int BUFFER_TRANSFORM_IDENTITY = 0; // 0x0
+    field public static final int BUFFER_TRANSFORM_MIRROR_HORIZONTAL = 1; // 0x1
+    field public static final int BUFFER_TRANSFORM_MIRROR_VERTICAL = 2; // 0x2
+    field public static final int BUFFER_TRANSFORM_ROTATE_180 = 3; // 0x3
+    field public static final int BUFFER_TRANSFORM_ROTATE_270 = 7; // 0x7
+    field public static final int BUFFER_TRANSFORM_ROTATE_90 = 4; // 0x4
+    field public static final int CHANGE_FRAME_RATE_ALWAYS = 1; // 0x1
+    field public static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0; // 0x0
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Companion Companion;
+    field public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0; // 0x0
+    field public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1; // 0x1
+  }
+
+  public static final class SurfaceControlCompat.Builder {
+    ctor public SurfaceControlCompat.Builder();
+    method public androidx.graphics.surface.SurfaceControlCompat build();
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setName(String name);
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setParent(android.view.SurfaceView surfaceView);
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setParent(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+  }
+
+  public static final class SurfaceControlCompat.Companion {
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final class SurfaceControlCompat.Transaction implements java.lang.AutoCloseable {
+    ctor public SurfaceControlCompat.Transaction();
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public androidx.graphics.surface.SurfaceControlCompat.Transaction addTransactionCommittedListener(java.util.concurrent.Executor executor, androidx.graphics.surface.SurfaceControlCompat.TransactionCommittedListener listener);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction clearFrameRate(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+    method public void close();
+    method public void commit();
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void commitTransactionOnDraw(android.view.AttachedSurfaceControl attachedSurfaceControl);
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public androidx.graphics.surface.SurfaceControlCompat.Transaction reparent(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.view.AttachedSurfaceControl attachedSurfaceControl);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction reparent(androidx.graphics.surface.SurfaceControlCompat surfaceControl, androidx.graphics.surface.SurfaceControlCompat? newParent);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setAlpha(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float alpha);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBuffer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.hardware.HardwareBuffer? buffer);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBuffer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.hardware.HardwareBuffer? buffer, optional androidx.hardware.SyncFenceCompat? fence);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBuffer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.hardware.HardwareBuffer? buffer, optional androidx.hardware.SyncFenceCompat? fence, optional kotlin.jvm.functions.Function1<? super androidx.hardware.SyncFenceCompat,kotlin.Unit>? releaseCallback);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBufferTransform(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int transformation);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setCrop(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Rect? crop);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setDamageRegion(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Region? region);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setDataSpace(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int dataSpace);
+    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public androidx.graphics.surface.SurfaceControlCompat.Transaction setExtendedRangeBrightness(androidx.graphics.surface.SurfaceControlCompat surfaceControl, @FloatRange(from=1.0, fromInclusive=true) float currentBufferRatio, @FloatRange(from=1.0, fromInclusive=true) float desiredRatio);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setFrameRate(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float frameRate, int compatibility, int changeFrameRateStrategy);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setLayer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int z);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setOpaque(androidx.graphics.surface.SurfaceControlCompat surfaceControl, boolean isOpaque);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setPosition(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float x, float y);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setScale(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float scaleX, float scaleY);
+    method public androidx.graphics.surface.SurfaceControlCompat.Transaction setVisibility(androidx.graphics.surface.SurfaceControlCompat surfaceControl, boolean visible);
+  }
+
+  public static interface SurfaceControlCompat.TransactionCommittedListener {
+    method public void onTransactionCommitted();
+  }
+
+}
+
+package androidx.hardware {
+
+  public final class DataSpace {
+    field public static final androidx.hardware.DataSpace.Companion Companion;
+    field public static final int DATASPACE_ADOBE_RGB = 151715840; // 0x90b0000
+    field public static final int DATASPACE_BT2020 = 147193856; // 0x8c60000
+    field public static final int DATASPACE_BT2020_HLG = 168165376; // 0xa060000
+    field public static final int DATASPACE_BT2020_PQ = 163971072; // 0x9c60000
+    field public static final int DATASPACE_BT601_525 = 281280512; // 0x10c40000
+    field public static final int DATASPACE_BT601_625 = 281149440; // 0x10c20000
+    field public static final int DATASPACE_BT709 = 281083904; // 0x10c10000
+    field public static final int DATASPACE_DCI_P3 = 155844608; // 0x94a0000
+    field public static final int DATASPACE_DEPTH = 4096; // 0x1000
+    field public static final int DATASPACE_DISPLAY_P3 = 143261696; // 0x88a0000
+    field public static final int DATASPACE_DYNAMIC_DEPTH = 4098; // 0x1002
+    field public static final int DATASPACE_HEIF = 4100; // 0x1004
+    field public static final int DATASPACE_JFIF = 146931712; // 0x8c20000
+    field public static final int DATASPACE_JPEG_R = 4101; // 0x1005
+    field public static final int DATASPACE_SCRGB = 411107328; // 0x18810000
+    field public static final int DATASPACE_SCRGB_LINEAR = 406913024; // 0x18410000
+    field public static final int DATASPACE_SRGB = 142671872; // 0x8810000
+    field public static final int DATASPACE_SRGB_LINEAR = 138477568; // 0x8410000
+    field public static final int DATASPACE_UNKNOWN = 0; // 0x0
+    field public static final int RANGE_EXTENDED = 402653184; // 0x18000000
+    field public static final int RANGE_FULL = 134217728; // 0x8000000
+    field public static final int RANGE_LIMITED = 268435456; // 0x10000000
+    field public static final int RANGE_UNSPECIFIED = 0; // 0x0
+  }
+
+  public static final class DataSpace.Companion {
+  }
+
+  public final class SyncFenceCompat implements java.lang.AutoCloseable {
+    method public boolean await(long timeoutNanos);
+    method public boolean awaitForever();
+    method public void close();
+    method public static androidx.hardware.SyncFenceCompat createNativeSyncFence();
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public long getSignalTimeNanos();
+    method public boolean isValid();
+    field public static final androidx.hardware.SyncFenceCompat.Companion Companion;
+    field public static final long SIGNAL_TIME_INVALID = -1L; // 0xffffffffffffffffL
+    field public static final long SIGNAL_TIME_PENDING = 9223372036854775807L; // 0x7fffffffffffffffL
+  }
+
+  public static final class SyncFenceCompat.Companion {
+    method public androidx.hardware.SyncFenceCompat createNativeSyncFence();
+  }
+
+}
+
+package androidx.opengl {
+
+  public final class EGLExt {
+    method public static int eglClientWaitSyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int flags, long timeoutNanos);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.opengl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public static androidx.opengl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, androidx.graphics.opengl.egl.EGLConfigAttributes? attributes);
+    method public static boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLImageKHR image);
+    method public static boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR eglSync);
+    method public static boolean eglGetSyncAttribKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int attribute, int[] value, int offset);
+    method public static void glEGLImageTargetTexture2DOES(int target, androidx.opengl.EGLImageKHR image);
+    method public static java.util.Set<java.lang.String> parseExtensions(String queryString);
+    field public static final androidx.opengl.EGLExt.Companion Companion;
+    field public static final String EGL_ANDROID_CLIENT_BUFFER = "EGL_ANDROID_get_native_client_buffer";
+    field public static final String EGL_ANDROID_IMAGE_NATIVE_BUFFER = "EGL_ANDROID_image_native_buffer";
+    field public static final String EGL_ANDROID_NATIVE_FENCE_SYNC = "EGL_ANDROID_native_fence_sync";
+    field public static final int EGL_CONDITION_SATISFIED_KHR = 12534; // 0x30f6
+    field public static final String EGL_EXT_BUFFER_AGE = "EGL_EXT_buffer_age";
+    field public static final String EGL_EXT_GL_COLORSPACE_BT2020_PQ = "EGL_EXT_gl_colorspace_bt2020_pq";
+    field public static final String EGL_EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+    field public static final String EGL_EXT_GL_COLORSPACE_SCRGB = "EGL_EXT_gl_colorspace_scrgb";
+    field public static final String EGL_EXT_PIXEL_FORMAT_FLOAT = "EGL_EXT_pixel_format_float";
+    field public static final int EGL_FALSE = 0; // 0x0
+    field public static final long EGL_FOREVER_KHR = -1L; // 0xffffffffffffffffL
+    field public static final String EGL_IMG_CONTEXT_PRIORITY = "EGL_IMG_context_priority";
+    field public static final String EGL_KHR_FENCE_SYNC = "EGL_KHR_fence_sync";
+    field public static final String EGL_KHR_GL_COLORSPACE = "EGL_KHR_gl_colorspace";
+    field public static final String EGL_KHR_IMAGE = "EGL_KHR_image";
+    field public static final String EGL_KHR_IMAGE_BASE = "EGL_KHR_image_base";
+    field public static final String EGL_KHR_NO_CONFIG_CONTEXT = "EGL_KHR_no_config_context";
+    field public static final String EGL_KHR_PARTIAL_UPDATE = "EGL_KHR_partial_update";
+    field public static final String EGL_KHR_SURFACELESS_CONTEXT = "EGL_KHR_surfaceless_context";
+    field public static final String EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE = "EGL_KHR_swap_buffers_with_damage";
+    field public static final String EGL_KHR_WAIT_SYNC = "EGL_KHR_wait_sync";
+    field public static final int EGL_SIGNALED_KHR = 12530; // 0x30f2
+    field public static final int EGL_SYNC_CONDITION_KHR = 12536; // 0x30f8
+    field public static final int EGL_SYNC_FENCE_KHR = 12537; // 0x30f9
+    field public static final int EGL_SYNC_FLUSH_COMMANDS_BIT_KHR = 1; // 0x1
+    field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144
+    field public static final int EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR = 12528; // 0x30f0
+    field public static final int EGL_SYNC_STATUS_KHR = 12529; // 0x30f1
+    field public static final int EGL_SYNC_TYPE_KHR = 12535; // 0x30f7
+    field public static final int EGL_TIMEOUT_EXPIRED_KHR = 12533; // 0x30f5
+    field public static final int EGL_TRUE = 1; // 0x1
+    field public static final int EGL_UNSIGNALED_KHR = 12531; // 0x30f3
+  }
+
+  public static final class EGLExt.Companion {
+    method public int eglClientWaitSyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int flags, long timeoutNanos);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.opengl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public androidx.opengl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, androidx.graphics.opengl.egl.EGLConfigAttributes? attributes);
+    method public boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLImageKHR image);
+    method public boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR eglSync);
+    method public boolean eglGetSyncAttribKHR(android.opengl.EGLDisplay eglDisplay, androidx.opengl.EGLSyncKHR sync, int attribute, int[] value, int offset);
+    method public void glEGLImageTargetTexture2DOES(int target, androidx.opengl.EGLImageKHR image);
+    method public java.util.Set<java.lang.String> parseExtensions(String queryString);
+  }
+
+  public interface EGLHandle {
+    method public long getNativeHandle();
+    property public abstract long nativeHandle;
+  }
+
+  public final class EGLImageKHR implements androidx.opengl.EGLHandle {
+    ctor public EGLImageKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLSyncKHR implements androidx.opengl.EGLHandle {
+    ctor public EGLSyncKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+}
+
diff --git a/graphics/graphics-core/api/restricted_current.ignore b/graphics/graphics-core/api/restricted_current.ignore
new file mode 100644
index 0000000..af77f0d
--- /dev/null
+++ b/graphics/graphics-core/api/restricted_current.ignore
@@ -0,0 +1,11 @@
+// Baseline format: 1.0
+AddedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#draw(boolean, kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>):
+    Added method androidx.graphics.CanvasBufferedRenderer.RenderRequest.draw(boolean,kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>)
+AddedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#drawAsync(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>):
+    Added method androidx.graphics.CanvasBufferedRenderer.RenderRequest.drawAsync(java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>)
+
+
+RemovedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#draw(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>):
+    Removed method androidx.graphics.CanvasBufferedRenderer.RenderRequest.draw(java.util.concurrent.Executor,androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult>)
+RemovedMethod: androidx.graphics.CanvasBufferedRenderer.RenderRequest#drawSync(boolean):
+    Removed method androidx.graphics.CanvasBufferedRenderer.RenderRequest.drawSync(boolean)
diff --git a/graphics/graphics-core/api/restricted_current.txt b/graphics/graphics-core/api/restricted_current.txt
index 74ac194..0c3a248 100644
--- a/graphics/graphics-core/api/restricted_current.txt
+++ b/graphics/graphics-core/api/restricted_current.txt
@@ -13,6 +13,7 @@
     method public void setLightSourceAlpha(float ambientShadowAlpha, float spotShadowAlpha);
     method public void setLightSourceGeometry(float lightX, float lightY, float lightZ, float lightRadius);
     property public final int bufferFormat;
+    property public final boolean isClosed;
     property public final int maxBuffers;
     property public final long usageFlags;
   }
@@ -26,7 +27,8 @@
   }
 
   public final class CanvasBufferedRenderer.RenderRequest {
-    method public void draw(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult> callback);
+    method public suspend Object? draw(optional boolean waitForFence, kotlin.coroutines.Continuation<? super androidx.graphics.CanvasBufferedRenderer.RenderResult>);
+    method public void drawAsync(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.graphics.CanvasBufferedRenderer.RenderResult> callback);
     method public androidx.graphics.CanvasBufferedRenderer.RenderRequest preserveContents(boolean preserve);
     method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setBufferTransform(int bufferTransform);
     method public androidx.graphics.CanvasBufferedRenderer.RenderRequest setColorSpace(android.graphics.ColorSpace? colorSpace);
@@ -88,7 +90,7 @@
 
   public final class FrontBufferSyncStrategy implements androidx.graphics.opengl.SyncStrategy {
     ctor public FrontBufferSyncStrategy(long usageFlags);
-    method @RequiresApi(android.os.Build.VERSION_CODES.KITKAT) public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
     method public boolean isVisible();
     method public void setVisible(boolean);
     property public final boolean isVisible;
@@ -243,7 +245,7 @@
   }
 
   public interface SyncStrategy {
-    method @RequiresApi(android.os.Build.VERSION_CODES.KITKAT) public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
+    method public androidx.hardware.SyncFenceCompat? createSyncFence(androidx.graphics.opengl.egl.EGLSpec eglSpec);
     field public static final androidx.graphics.opengl.SyncStrategy ALWAYS;
     field public static final androidx.graphics.opengl.SyncStrategy.Companion Companion;
   }
@@ -464,7 +466,7 @@
   public static final class DataSpace.Companion {
   }
 
-  @RequiresApi(android.os.Build.VERSION_CODES.KITKAT) public final class SyncFenceCompat implements java.lang.AutoCloseable {
+  public final class SyncFenceCompat implements java.lang.AutoCloseable {
     method public boolean await(long timeoutNanos);
     method public boolean awaitForever();
     method public void close();
diff --git a/graphics/graphics-core/build.gradle b/graphics/graphics-core/build.gradle
index f5a4f87..9dfe084 100644
--- a/graphics/graphics-core/build.gradle
+++ b/graphics/graphics-core/build.gradle
@@ -25,6 +25,7 @@
 
 dependencies {
     api(libs.kotlinStdlib)
+    implementation(libs.kotlinCoroutinesAndroid)
     implementation("androidx.annotation:annotation-experimental:1.1.0-rc01")
     implementation("androidx.core:core:1.8.0")
     androidTestImplementation(libs.testExtJunit)
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt
index c606168..9420dab 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt
@@ -53,6 +53,7 @@
 import java.util.concurrent.Executors
 import java.util.concurrent.TimeUnit
 import kotlin.math.abs
+import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
@@ -72,16 +73,16 @@
     fun testRenderAfterCloseReturnsError() = hardwareBufferRendererTest { renderer ->
         renderer.close()
         assertThrows(IllegalStateException::class.java) {
-            renderer.obtainRenderRequest().draw(mExecutor) { _ -> /* NO-OP */ }
+            renderer.obtainRenderRequest().drawAsync(mExecutor) { _ -> /* NO-OP */ }
         }
     }
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     @Test
     fun testIsClosed() = hardwareBufferRendererTest { renderer ->
-        assertFalse(renderer.isClosed())
+        assertFalse(renderer.isClosed)
         renderer.close()
-        assertTrue(renderer.isClosed())
+        assertTrue(renderer.isClosed)
     }
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
@@ -106,7 +107,7 @@
         var bitmap: Bitmap? = null
         renderer.obtainRenderRequest()
             .preserveContents(true)
-            .draw(mExecutor) { result ->
+            .drawAsync(mExecutor) { result ->
                 assertEquals(SUCCESS, result.status)
                 result.fence?.awaitForever()
                 bitmap = Bitmap.wrapHardwareBuffer(result.hardwareBuffer, null)
@@ -122,7 +123,7 @@
         latch = CountDownLatch(1)
         renderer.obtainRenderRequest()
             .preserveContents(false)
-            .draw(mExecutor) { result ->
+            .drawAsync(mExecutor) { result ->
                 assertEquals(SUCCESS, result.status)
                 result.fence?.awaitForever()
                 bitmap = Bitmap.wrapHardwareBuffer(result.hardwareBuffer, null)
@@ -138,12 +139,16 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     @Test
     fun testPreservationEnabledPreservesContents() =
-        verifyPreservedBuffer(CanvasBufferedRenderer.DEFAULT_IMPL)
+        repeat(20) {
+            verifyPreservedBuffer(CanvasBufferedRenderer.DEFAULT_IMPL)
+        }
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     @Test
     fun testPreservationEnabledPreservesContentsWithRedrawStrategy() =
-        verifyPreservedBuffer(CanvasBufferedRenderer.USE_V29_IMPL_WITH_REDRAW)
+        repeat(20) {
+            verifyPreservedBuffer(CanvasBufferedRenderer.USE_V29_IMPL_WITH_REDRAW)
+        }
 
     @RequiresApi(Build.VERSION_CODES.Q)
     private fun verifyPreservedBuffer(
@@ -208,7 +213,7 @@
             var bitmap: Bitmap? = null
             renderer.obtainRenderRequest()
                 .preserveContents(true)
-                .draw(executor) { result ->
+                .drawAsync(executor) { result ->
                     assertEquals(SUCCESS, result.status)
                     result.fence?.awaitForever()
                     bitmap = Bitmap.wrapHardwareBuffer(result.hardwareBuffer, null)
@@ -224,7 +229,7 @@
             val secondRenderLatch = CountDownLatch(1)
             renderer.obtainRenderRequest()
                 .preserveContents(true)
-                .draw(executor) { result ->
+                .drawAsync(executor) { result ->
                     assertEquals(SUCCESS, result.status)
                     result.fence?.awaitForever()
                     bitmap = Bitmap.wrapHardwareBuffer(result.hardwareBuffer, null)
@@ -250,11 +255,13 @@
         val colorSpace = ColorSpace.get(ColorSpace.Named.SRGB)
         val latch = CountDownLatch(1)
         var hardwareBuffer: HardwareBuffer? = null
-        renderer.obtainRenderRequest().setColorSpace(colorSpace).draw(mExecutor) { renderResult ->
-            renderResult.fence?.awaitForever()
-            hardwareBuffer = renderResult.hardwareBuffer
-            latch.countDown()
-        }
+        renderer.obtainRenderRequest()
+            .setColorSpace(colorSpace)
+            .drawAsync(mExecutor) { renderResult ->
+                renderResult.fence?.awaitForever()
+                hardwareBuffer = renderResult.hardwareBuffer
+                latch.countDown()
+            }
 
         assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
 
@@ -268,6 +275,73 @@
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     @Test
+    fun testDrawSync() = hardwareBufferRendererTest { renderer ->
+        val contentRoot = RenderNode("content").apply {
+            setPosition(0, 0, TEST_WIDTH, TEST_HEIGHT)
+            record { canvas -> canvas.drawColor(Color.BLUE) }
+        }
+        renderer.setContentRoot(contentRoot)
+
+        val colorSpace = ColorSpace.get(ColorSpace.Named.SRGB)
+
+        var renderResult: CanvasBufferedRenderer.RenderResult?
+        runBlocking {
+            renderResult = renderer.obtainRenderRequest().setColorSpace(colorSpace).draw()
+        }
+        assertNotNull(renderResult)
+        assertEquals(SUCCESS, renderResult!!.status)
+        val fence = renderResult?.fence
+        if (fence != null) {
+            // by default drawSync will automatically wait on the fence and close it leaving
+            // it in the invalid state
+            assertFalse(fence.isValid())
+        }
+
+        val hardwareBuffer = renderResult!!.hardwareBuffer
+
+        val bitmap = Bitmap.wrapHardwareBuffer(hardwareBuffer, colorSpace)!!
+            .copy(Bitmap.Config.ARGB_8888, false)
+
+        assertEquals(TEST_WIDTH, bitmap.width)
+        assertEquals(TEST_HEIGHT, bitmap.height)
+        assertEquals(0xFF0000FF.toInt(), bitmap.getPixel(0, 0))
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testDrawSyncWithoutBlockingFence() = hardwareBufferRendererTest { renderer ->
+        val contentRoot = RenderNode("content").apply {
+            setPosition(0, 0, TEST_WIDTH, TEST_HEIGHT)
+            record { canvas -> canvas.drawColor(Color.BLUE) }
+        }
+        renderer.setContentRoot(contentRoot)
+
+        val colorSpace = ColorSpace.get(ColorSpace.Named.SRGB)
+
+        var renderResult: CanvasBufferedRenderer.RenderResult?
+        runBlocking {
+            renderResult = renderer.obtainRenderRequest().setColorSpace(colorSpace).draw(false)
+        }
+        assertNotNull(renderResult)
+        assertEquals(SUCCESS, renderResult!!.status)
+        val fence = renderResult?.fence
+        assertNotNull(fence)
+        assertTrue(fence!!.isValid())
+        fence.awaitForever()
+        fence.close()
+
+        val hardwareBuffer = renderResult!!.hardwareBuffer
+
+        val bitmap = Bitmap.wrapHardwareBuffer(hardwareBuffer, colorSpace)!!
+            .copy(Bitmap.Config.ARGB_8888, false)
+
+        assertEquals(TEST_WIDTH, bitmap.width)
+        assertEquals(TEST_HEIGHT, bitmap.height)
+        assertEquals(0xFF0000FF.toInt(), bitmap.getPixel(0, 0))
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
     fun testContentsPreservedSRGB() = preservedContentsTest { bitmap ->
         assertEquals(Color.RED, bitmap.getPixel(TEST_WIDTH / 2, TEST_HEIGHT / 4))
         assertEquals(Color.BLUE, bitmap.getPixel(TEST_WIDTH / 2, TEST_HEIGHT / 2 + TEST_HEIGHT / 4))
@@ -342,7 +416,7 @@
         renderer.obtainRenderRequest()
             .setColorSpace(colorSpace)
             .preserveContents(true)
-            .draw(mExecutor) { renderResult ->
+            .drawAsync(mExecutor) { renderResult ->
             renderResult.fence?.awaitForever()
             hardwareBuffer = renderResult.hardwareBuffer
             latch.countDown()
@@ -361,7 +435,7 @@
         renderer.obtainRenderRequest()
             .setColorSpace(colorSpace)
             .preserveContents(true)
-            .draw(mExecutor) { renderResult ->
+            .drawAsync(mExecutor) { renderResult ->
                 renderResult.fence?.awaitForever()
                 hardwareBuffer = renderResult.hardwareBuffer
                 latch2.countDown()
@@ -535,7 +609,7 @@
             renderer.obtainRenderRequest()
                 .setColorSpace(colorSpace)
                 .setBufferTransform(42)
-                .draw(mExecutor) { renderResult ->
+                .drawAsync(mExecutor) { renderResult ->
                     renderResult.fence?.awaitForever()
                     latch.countDown()
                 }
@@ -602,7 +676,7 @@
         renderer.obtainRenderRequest()
             .setColorSpace(colorSpace)
             .setBufferTransform(transform)
-            .draw(mExecutor) { renderResult ->
+            .drawAsync(mExecutor) { renderResult ->
                 renderStatus = renderResult.status
                 renderResult.fence?.awaitForever()
                 hardwareBuffer = renderResult.hardwareBuffer
@@ -704,7 +778,7 @@
             val latch2 = CountDownLatch(1)
             val latch3 = CountDownLatch(1)
             var hardwareBuffer: HardwareBuffer? = null
-            renderer.obtainRenderRequest().draw(executor) { result ->
+            renderer.obtainRenderRequest().drawAsync(executor) { result ->
                 result.fence?.awaitForever()
                 result.fence?.close()
                 hardwareBuffer = result.hardwareBuffer
@@ -717,7 +791,7 @@
             canvas.drawColor(Color.BLUE)
             renderNode.endRecording()
 
-            renderer.obtainRenderRequest().draw(executor) { _ ->
+            renderer.obtainRenderRequest().drawAsync(executor) { _ ->
                 latch2.countDown()
             }
 
@@ -727,7 +801,7 @@
             canvas.drawColor(Color.GREEN)
             renderNode.endRecording()
 
-            renderer.obtainRenderRequest().draw(executor) { _ ->
+            renderer.obtainRenderRequest().drawAsync(executor) { _ ->
                 latch3.countDown()
             }
 
@@ -845,7 +919,7 @@
                 renderNode.endRecording()
 
                 val latch = CountDownLatch(1)
-                hbr.obtainRenderRequest().draw(executor) { result ->
+                hbr.obtainRenderRequest().drawAsync(executor) { result ->
                     hbr.releaseBuffer(result.hardwareBuffer, result.fence)
                     latch.countDown()
                 }
@@ -920,7 +994,7 @@
                         .setColorSpace(colorSpace)
                         .preserveContents(true)
                         .setBufferTransform(transform)
-                        .draw(executor) { renderResult ->
+                        .drawAsync(executor) { renderResult ->
                             renderResult.fence?.awaitForever()
                             hardwareBuffer = renderResult.hardwareBuffer
                             latch.countDown()
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt
index 6a4cace..9fe0fb4 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.graphics.lowlatency
 
+import android.app.Activity
 import android.app.UiAutomation
 import android.graphics.Canvas
 import android.graphics.Color
@@ -981,18 +982,20 @@
         }
         try {
             var supportsWideColorGamut = false
+            val createLatch = CountDownLatch(1)
             val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
-                    supportsWideColorGamut = it.window.isWideColorGamut
+                    supportsWideColorGamut = supportsWideColorGamut(it)
                     surfaceView = it.getSurfaceView()
                     renderer = CanvasFrontBufferedRenderer(surfaceView!!, callbacks).apply {
                         configureRenderer.invoke(this)
                     }
+                    createLatch.countDown()
                 }
+            assertTrue(createLatch.await(3000, TimeUnit.MILLISECONDS))
             if (supportsWideColorGamut) {
                 scenario.moveToState(Lifecycle.State.RESUMED)
-
                 assertTrue(multiBufferLatch.await(3000, TimeUnit.MILLISECONDS))
 
                 renderer?.renderFrontBufferedLayer(Any())
@@ -1016,6 +1019,16 @@
         }
     }
 
+    @Suppress("DEPRECATION")
+    @RequiresApi(Build.VERSION_CODES.O)
+    private fun supportsWideColorGamut(activity: Activity): Boolean {
+        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            activity.display?.isWideColorGamut == true
+        } else {
+            activity.windowManager.defaultDisplay.isWideColorGamut
+        }
+    }
+
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     @Test
     fun testMultiBufferedLayerRenderWithDisplayP3() {
@@ -1087,15 +1100,18 @@
         }
         try {
             var supportsWideColorGamut = false
+            val createLatch = CountDownLatch(1)
             val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
-                    supportsWideColorGamut = it.window.isWideColorGamut
+                    supportsWideColorGamut = supportsWideColorGamut(it)
                     surfaceView = it.getSurfaceView()
                     renderer = CanvasFrontBufferedRenderer(surfaceView!!, callbacks).apply {
                         configureRenderer.invoke(this)
                     }
+                    createLatch.countDown()
                 }
+            assertTrue(createLatch.await(3000, TimeUnit.MILLISECONDS))
             if (supportsWideColorGamut) {
                 scenario.moveToState(Lifecycle.State.RESUMED)
 
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
index 7e7d5ef..d4d4753 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
@@ -103,7 +103,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     fun testRender() {
         val latch = CountDownLatch(1)
         val renderer = object : GLRenderer.RenderCallback {
@@ -129,7 +128,7 @@
         assertEquals(4, plane.pixelStride)
 
         val targetColor = Color.argb(255, 255, 0, 255)
-        Api19Helpers.verifyPlaneContent(width, height, plane, targetColor)
+        verifyPlaneContent(width, height, plane, targetColor)
 
         target.detach(true)
 
@@ -137,7 +136,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     fun testDetachExecutesPendingRequests() {
         val latch = CountDownLatch(1)
         val renderer = object : GLRenderer.RenderCallback {
@@ -164,13 +162,12 @@
         assertEquals(4, plane.pixelStride)
 
         val targetColor = Color.argb(255, 255, 0, 255)
-        Api19Helpers.verifyPlaneContent(width, height, plane, targetColor)
+        verifyPlaneContent(width, height, plane, targetColor)
 
         glRenderer.stop(true)
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     fun testStopExecutesPendingRequests() {
         val latch = CountDownLatch(1)
         val surfaceWidth = 5
@@ -200,11 +197,10 @@
         assertEquals(4, plane.pixelStride)
 
         val targetColor = Color.argb(255, 255, 0, 255)
-        Api19Helpers.verifyPlaneContent(surfaceWidth, surfaceHeight, plane, targetColor)
+        verifyPlaneContent(surfaceWidth, surfaceHeight, plane, targetColor)
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     fun testDetachExecutesMultiplePendingRequests() {
         val numRenders = 4
         val latch = CountDownLatch(numRenders)
@@ -254,13 +250,12 @@
         assertEquals(4, plane.pixelStride)
 
         val targetColor = Color.argb(255, 0, 0, 255)
-        Api19Helpers.verifyPlaneContent(width, height, plane, targetColor)
+        verifyPlaneContent(width, height, plane, targetColor)
 
         glRenderer.stop(true)
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     fun testDetachCancelsPendingRequests() {
         val latch = CountDownLatch(1)
         val renderer = object : GLRenderer.RenderCallback {
@@ -286,7 +281,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     fun testMultipleAttachedSurfaces() {
         val latch = CountDownLatch(2)
         val renderer1 = object : GLRenderer.RenderCallback {
@@ -329,8 +323,8 @@
         val plane1 = reader1.acquireLatestImage().planes[0]
         val plane2 = reader2.acquireLatestImage().planes[0]
 
-        Api19Helpers.verifyPlaneContent(width1, height1, plane1, Color.argb(255, 255, 0, 0))
-        Api19Helpers.verifyPlaneContent(width2, height2, plane2, Color.argb(255, 0, 0, 255))
+        verifyPlaneContent(width1, height1, plane1, Color.argb(255, 255, 0, 0))
+        verifyPlaneContent(width2, height2, plane2, Color.argb(255, 0, 0, 255))
 
         target1.detach(true)
         target2.detach(true)
@@ -351,25 +345,20 @@
      * there are corresponding @SdkSuppress and @RequiresApi
      * See https://b.corp.google.com/issues/221485597
      */
-    class Api19Helpers private constructor() {
-        companion object {
-            @RequiresApi(Build.VERSION_CODES.KITKAT)
-            fun verifyPlaneContent(width: Int, height: Int, plane: Image.Plane, targetColor: Int) {
-                val rowPadding = plane.rowStride - plane.pixelStride * width
-                var offset = 0
-                for (y in 0 until height) {
-                    for (x in 0 until width) {
-                        val red = plane.buffer[offset].toInt() and 0xff
-                        val green = plane.buffer[offset + 1].toInt() and 0xff
-                        val blue = plane.buffer[offset + 2].toInt() and 0xff
-                        val alpha = plane.buffer[offset + 3].toInt() and 0xff
-                        val packedColor = Color.argb(alpha, red, green, blue)
-                        assertEquals("Index: $x, $y", targetColor, packedColor)
-                        offset += plane.pixelStride
-                    }
-                    offset += rowPadding
-                }
+    private fun verifyPlaneContent(width: Int, height: Int, plane: Image.Plane, targetColor: Int) {
+        val rowPadding = plane.rowStride - plane.pixelStride * width
+        var offset = 0
+        for (y in 0 until height) {
+            for (x in 0 until width) {
+                val red = plane.buffer[offset].toInt() and 0xff
+                val green = plane.buffer[offset + 1].toInt() and 0xff
+                val blue = plane.buffer[offset + 2].toInt() and 0xff
+                val alpha = plane.buffer[offset + 3].toInt() and 0xff
+                val packedColor = Color.argb(alpha, red, green, blue)
+                assertEquals("Index: $x, $y", targetColor, packedColor)
+                offset += plane.pixelStride
             }
+            offset += rowPadding
         }
     }
 
@@ -661,9 +650,34 @@
                 assertNotNull(textureView)
 
                 glRenderer = GLRenderer().apply { start() }
-                target = glRenderer!!.attach(it.textureView, ColorRenderCallback(Color.BLUE) {
-                    renderLatch.get().countDown()
-                })
+                target = glRenderer!!.attach(it.textureView, ColorRenderCallback(Color.BLUE))
+                val listener = textureView!!.surfaceTextureListener
+                textureView!!.surfaceTextureListener = object : SurfaceTextureListener {
+                    override fun onSurfaceTextureAvailable(
+                        surface: SurfaceTexture,
+                        width: Int,
+                        height: Int
+                    ) {
+                        listener?.onSurfaceTextureAvailable(surface, width, height)
+                    }
+
+                    override fun onSurfaceTextureSizeChanged(
+                        surface: SurfaceTexture,
+                        width: Int,
+                        height: Int
+                    ) {
+                        listener?.onSurfaceTextureSizeChanged(surface, width, height)
+                    }
+
+                    override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
+                        return listener?.onSurfaceTextureDestroyed(surface) ?: true
+                    }
+
+                    override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
+                        listener?.onSurfaceTextureUpdated(surface)
+                        renderLatch.get().countDown()
+                    }
+                }
             }
 
         scenario.moveToState(State.RESUMED)
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
index b0ec6e1..0fd265f 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
@@ -27,7 +27,6 @@
 import android.opengl.GLES20
 import android.os.Build
 import android.view.Surface
-import androidx.annotation.RequiresApi
 import androidx.hardware.SyncFenceCompat
 import androidx.opengl.EGLBindings
 import androidx.opengl.EGLExt
@@ -290,19 +289,16 @@
         }
     }
 
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     fun testSurfaceContentsWithBackBuffer() {
         verifySurfaceContentsWithWindowConfig()
     }
 
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     fun testSurfaceContentsWithFrontBuffer() {
         verifySurfaceContentsWithWindowConfig(true)
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     private fun verifySurfaceContentsWithWindowConfig(
         singleBuffered: Boolean = false
     ) {
@@ -499,7 +495,6 @@
         }
     }
 
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     fun testEGLDupNativeFenceFDMethodLinked() {
         verifyMethodLinked {
@@ -688,7 +683,6 @@
         }
     }
 
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     fun testEglDupNativeFenceFDANDROID() {
         testEGLManager {
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
index a63e68b..81c25e2 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
@@ -1725,59 +1725,25 @@
         createTransaction: (SurfaceView) -> SurfaceControlCompat.Transaction,
         verifyOutput: (Bitmap, Rect) -> Boolean
     ) {
-        val transactionLatch = CountDownLatch(1)
-        var surfaceView: SurfaceView? = null
-        val destroyLatch = CountDownLatch(1)
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                it.setDestroyCallback { destroyLatch.countDown() }
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        surfaceView = it.mSurfaceView
-                        val transaction = createTransaction(surfaceView!!)
-                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
-                            transaction.addTransactionCommittedListener(
-                                executor!!,
-                                object : SurfaceControlCompat.TransactionCommittedListener {
-                                    override fun onTransactionCommitted() {
-                                        transactionLatch.countDown()
-                                    }
-                                }
-                            )
-                        } else {
-                            transactionLatch.countDown()
+        SurfaceControlUtils.surfaceControlTestHelper(
+            { surfaceView, latch ->
+                val transaction = createTransaction(surfaceView)
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+                    transaction.addTransactionCommittedListener(
+                        executor!!,
+                        object : SurfaceControlCompat.TransactionCommittedListener {
+                            override fun onTransactionCommitted() {
+                                latch.countDown()
+                            }
                         }
-                        transaction.commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-                surfaceView = it.mSurfaceView
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED)
-
-        assertTrue(transactionLatch.await(3000, TimeUnit.MILLISECONDS))
-        val coords = intArrayOf(0, 0)
-        surfaceView!!.getLocationOnScreen(coords)
-        try {
-            SurfaceControlUtils.validateOutput { bitmap ->
-                verifyOutput(
-                    bitmap,
-                    Rect(
-                        coords[0],
-                        coords[1],
-                        coords[0] + SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                        coords[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT
                     )
-                )
-            }
-        } finally {
-            scenario.moveToState(Lifecycle.State.DESTROYED)
-            assertTrue(destroyLatch.await(3000, TimeUnit.MILLISECONDS))
-        }
+                } else {
+                    latch.countDown()
+                }
+                transaction.commit()
+            },
+            verifyOutput
+        )
     }
 
     fun Color.compositeOver(background: Color): Color {
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt
index 4e89941..74031ed 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt
@@ -19,19 +19,86 @@
 import android.app.Instrumentation
 import android.graphics.Bitmap
 import android.graphics.Color
+import android.graphics.Rect
 import android.hardware.HardwareBuffer
 import android.os.Build
 import android.os.SystemClock
+import android.view.SurfaceHolder
+import android.view.SurfaceView
 import android.view.Window
 import androidx.annotation.RequiresApi
+import androidx.lifecycle.Lifecycle
+import androidx.test.core.app.ActivityScenario
 import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
 import org.junit.Assert
 
 @SdkSuppress(minSdkVersion = 29)
 internal class SurfaceControlUtils {
     companion object {
 
+        @RequiresApi(Build.VERSION_CODES.Q)
+        fun surfaceControlTestHelper(
+            onSurfaceCreated: (SurfaceView, CountDownLatch) -> Unit,
+            verifyOutput: (Bitmap, Rect) -> Boolean
+        ) {
+            val setupLatch = CountDownLatch(1)
+            var surfaceView: SurfaceView? = null
+            val destroyLatch = CountDownLatch(1)
+            val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
+                .moveToState(
+                    Lifecycle.State.CREATED
+                ).onActivity {
+                    it.setDestroyCallback { destroyLatch.countDown() }
+                    val callback = object : SurfaceHolder.Callback {
+                        override fun surfaceCreated(sh: SurfaceHolder) {
+                            surfaceView = it.mSurfaceView
+                            onSurfaceCreated(surfaceView!!, setupLatch)
+                        }
+
+                        override fun surfaceChanged(
+                            holder: SurfaceHolder,
+                            format: Int,
+                            width: Int,
+                            height: Int
+                        ) {
+                            // NO-OP
+                        }
+
+                        override fun surfaceDestroyed(holder: SurfaceHolder) {
+                            // NO-OP
+                        }
+                    }
+
+                    it.addSurface(it.mSurfaceView, callback)
+                    surfaceView = it.mSurfaceView
+                }
+
+            scenario.moveToState(Lifecycle.State.RESUMED)
+
+            Assert.assertTrue(setupLatch.await(3000, TimeUnit.MILLISECONDS))
+            val coords = intArrayOf(0, 0)
+            surfaceView!!.getLocationOnScreen(coords)
+            try {
+                validateOutput { bitmap ->
+                    verifyOutput(
+                        bitmap,
+                        Rect(
+                            coords[0],
+                            coords[1],
+                            coords[0] + SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            coords[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT
+                        )
+                    )
+                }
+            } finally {
+                scenario.moveToState(Lifecycle.State.DESTROYED)
+                Assert.assertTrue(destroyLatch.await(3000, TimeUnit.MILLISECONDS))
+            }
+        }
+
         @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
         fun validateOutput(window: Window, block: (bitmap: Bitmap) -> Boolean) {
             val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlWrapperTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlWrapperTest.kt
index 89891d4..0902082 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlWrapperTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlWrapperTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.graphics.surface
 
+import android.graphics.Bitmap
 import android.graphics.Color
 import android.graphics.ColorSpace
 import android.graphics.Rect
@@ -25,6 +26,8 @@
 import android.view.Surface
 import android.view.SurfaceControl
 import android.view.SurfaceHolder
+import android.view.SurfaceView
+import androidx.annotation.RequiresApi
 import androidx.lifecycle.Lifecycle
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -47,7 +50,7 @@
 @SmallTest
 @SdkSuppress(minSdkVersion = 29)
 class SurfaceControlWrapperTest {
-    var executor: Executor? = null
+    private var executor: Executor? = null
 
     @Before
     fun setup() {
@@ -64,16 +67,20 @@
 
     @Test
     fun testCreateFromWindow() {
-        var surfaceControl = SurfaceControl.Builder()
+        val surfaceControl = SurfaceControl.Builder()
             .setName("SurfaceControlCompact_createFromWindow")
             .build()
+        var scWrapper: SurfaceControlWrapper? = null
         try {
-            SurfaceControlWrapper.Builder()
+            scWrapper = SurfaceControlWrapper.Builder()
                 .setParent(Surface(surfaceControl))
                 .setDebugName("SurfaceControlWrapperTest")
                 .build()
         } catch (e: IllegalArgumentException) {
             fail()
+        } finally {
+            scWrapper?.release()
+            surfaceControl.release()
         }
     }
 
@@ -82,22 +89,29 @@
         val surfaceControl = SurfaceControl.Builder()
             .setName("SurfaceControlCompact_createFromWindow")
             .build()
+        var scWrapper: SurfaceControlWrapper? = null
         try {
-            SurfaceControlWrapper.Builder()
+            scWrapper = SurfaceControlWrapper.Builder()
                 .setParent(Surface(surfaceControl))
                 .setDebugName("SurfaceControlWrapperTest")
                 .build()
         } catch (e: IllegalArgumentException) {
             fail()
+        } finally {
+            scWrapper?.release()
+            surfaceControl.release()
         }
     }
 
     @Test
     fun testSurfaceTransactionCreate() {
+        var scWrapperTransaction: SurfaceControlWrapper.Transaction? = null
         try {
-            SurfaceControlWrapper.Transaction()
+            scWrapperTransaction = SurfaceControlWrapper.Transaction()
         } catch (e: java.lang.IllegalArgumentException) {
             fail()
+        } finally {
+            scWrapperTransaction?.close()
         }
     }
 
@@ -128,8 +142,10 @@
         val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
 
+        val destroyLatch = CountDownLatch(1)
         try {
             scenario.onActivity {
+                it.setDestroyCallback { destroyLatch.countDown() }
                 SurfaceControlWrapper.Transaction()
                     .addTransactionCompletedListener(listener)
                     .commit()
@@ -143,6 +159,7 @@
         } finally {
             // ensure activity is destroyed after any failures
             scenario.moveToState(Lifecycle.State.DESTROYED)
+            assertTrue(destroyLatch.await(3000, TimeUnit.MILLISECONDS))
         }
     }
 
@@ -154,8 +171,10 @@
         val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
 
+        val destroyLatch = CountDownLatch(1)
         try {
             scenario.onActivity {
+                it.setDestroyCallback { destroyLatch.countDown() }
                 SurfaceControlWrapper.Transaction()
                     .addTransactionCommittedListener(executor!!, listener)
                     .commit()
@@ -168,6 +187,7 @@
         } finally {
             // ensure activity is destroyed after any failures
             scenario.moveToState(Lifecycle.State.DESTROYED)
+            assertTrue(destroyLatch.await(3000, TimeUnit.MILLISECONDS))
         }
     }
 
@@ -180,8 +200,10 @@
         val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
 
+        val destroyLatch = CountDownLatch(1)
         try {
             scenario.onActivity {
+                it.setDestroyCallback { destroyLatch.countDown() }
                 SurfaceControlWrapper.Transaction()
                     .addTransactionCommittedListener(executor!!, listener)
                     .addTransactionCommittedListener(executor!!, listener2)
@@ -201,6 +223,7 @@
         } finally {
             // ensure activity is destroyed after any failures
             scenario.moveToState(Lifecycle.State.DESTROYED)
+            assertTrue(destroyLatch.await(3000, TimeUnit.MILLISECONDS))
         }
     }
 
@@ -213,8 +236,10 @@
         val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
 
+        val destroyLatch = CountDownLatch(1)
         try {
             scenario.onActivity {
+                it.setDestroyCallback { destroyLatch.countDown() }
                 SurfaceControlWrapper.Transaction()
                     .addTransactionCommittedListener(executor!!, listener1)
                     .addTransactionCompletedListener(listener2)
@@ -233,12 +258,13 @@
         } finally {
             // ensure activity is destroyed after any failures
             scenario.moveToState(Lifecycle.State.DESTROYED)
+            assertTrue(destroyLatch.await(3000, TimeUnit.MILLISECONDS))
         }
     }
 
     @Test
     fun testSurfaceControlIsValid_valid() {
-        var surfaceControl = SurfaceControl.Builder()
+        val surfaceControl = SurfaceControl.Builder()
             .setName("SurfaceControlCompact_createFromWindow")
             .build()
         var scCompat: SurfaceControlWrapper? = null
@@ -247,16 +273,19 @@
                 .setParent(Surface(surfaceControl))
                 .setDebugName("SurfaceControlWrapperTest")
                 .build()
+
+            assertTrue(scCompat.isValid())
         } catch (e: IllegalArgumentException) {
             fail()
+        } finally {
+            scCompat?.release()
+            surfaceControl.release()
         }
-
-        assertTrue(scCompat!!.isValid())
     }
 
     @Test
     fun testSurfaceControlIsValid_validNotValid() {
-        var surfaceControl = SurfaceControl.Builder()
+        val surfaceControl = SurfaceControl.Builder()
             .setName("SurfaceControlCompact_createFromWindow")
             .build()
         var scCompat: SurfaceControlWrapper? = null
@@ -266,18 +295,23 @@
                 .setParent(Surface(surfaceControl))
                 .setDebugName("SurfaceControlWrapperTest")
                 .build()
+            assertTrue(scCompat.isValid())
+
+            scCompat.release()
+            assertFalse(scCompat.isValid())
         } catch (e: IllegalArgumentException) {
             fail()
+        } finally {
+            if (scCompat != null && scCompat.isValid()) {
+                scCompat.release()
+            }
+            surfaceControl.release()
         }
-
-        assertTrue(scCompat!!.isValid())
-        scCompat.release()
-        assertFalse(scCompat.isValid())
     }
 
     @Test
     fun testSurfaceControlIsValid_multipleRelease() {
-        var surfaceControl = SurfaceControl.Builder()
+        val surfaceControl = SurfaceControl.Builder()
             .setName("SurfaceControlCompact_createFromWindow")
             .build()
         var scCompat: SurfaceControlWrapper? = null
@@ -287,668 +321,458 @@
                 .setParent(Surface(surfaceControl))
                 .setDebugName("SurfaceControlWrapperTest")
                 .build()
+            assertTrue(scCompat.isValid())
+            scCompat.release()
+            scCompat.release()
+            assertFalse(scCompat.isValid())
         } catch (e: IllegalArgumentException) {
             fail()
+        } finally {
+            if (scCompat != null && scCompat.isValid()) {
+                scCompat.release()
+            }
+            surfaceControl.release()
         }
-
-        assertTrue(scCompat!!.isValid())
-        scCompat.release()
-        scCompat.release()
-        assertFalse(scCompat.isValid())
     }
 
     @Test
     fun testTransactionReparent_null() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer =
-                            SurfaceControlUtils.getSolidBuffer(
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                Color.BLUE
-                            )
-                        assertNotNull(buffer)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer =
+                    SurfaceControlUtils.getSolidBuffer(
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        Color.BLUE
+                    )
+                assertNotNull(buffer)
 
-                        SurfaceControlWrapper.Transaction()
-                            .setBuffer(scCompat, buffer)
-                            .reparent(scCompat, null)
-                            .commit()
-
-                        // Trying to set a callback with a transaction of a null reparent doesn't
-                        // get called, so lets set a listener for a 2nd transaction instead. This
-                        // should be placed in the queue where this will be executed after the
-                        // reparent transaction
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .reparent(scCompat, null)
+            },
+            { bitmap, rect ->
+                Color.BLACK == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assertTrue(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.BLACK == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionReparent_childOfSibling() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
-                        val scCompat2 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapper")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
+                val scCompat2 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapper")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer =
-                            SurfaceControlUtils.getSolidBuffer(
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                Color.BLUE
-                            )
-                        assertNotNull(buffer)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer =
+                    SurfaceControlUtils.getSolidBuffer(
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        Color.BLUE
+                    )
+                assertNotNull(buffer)
 
-                        val buffer2 =
-                            SurfaceControlUtils.getSolidBuffer(
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                Color.GREEN
-                            )
-                        assertNotNull(buffer2)
+                val buffer2 =
+                    SurfaceControlUtils.getSolidBuffer(
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        Color.GREEN
+                    )
+                assertNotNull(buffer2)
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setBuffer(scCompat2, buffer2)
-                            .reparent(scCompat, scCompat2)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setBuffer(scCompat2, buffer2)
+                    .reparent(scCompat, scCompat2)
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assertTrue(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetVisibility_show() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer =
-                            SurfaceControlUtils.getSolidBuffer(
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                Color.BLUE
-                            )
-                        assertNotNull(buffer)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer =
+                    SurfaceControlUtils.getSolidBuffer(
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        Color.BLUE
+                    )
+                assertNotNull(buffer)
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(
-                                scCompat,
-                                true
-                            ).commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(
+                        scCompat,
+                        true
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assertTrue(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetVisibility_hide() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer =
-                            SurfaceControlUtils.getSolidBuffer(
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                Color.BLUE
-                            )
-                        assertNotNull(buffer)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer =
+                    SurfaceControlUtils.getSolidBuffer(
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        Color.BLUE
+                    )
+                assertNotNull(buffer)
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(
-                                scCompat,
-                                false
-                            ).commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(
+                        scCompat,
+                        false
+                    )
+            },
+            { bitmap, rect ->
+                Color.BLACK == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assertTrue(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.BLACK == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetLayer_zero() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat1 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
-                        val scCompat2 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat1 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
+                val scCompat2 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setLayer(scCompat1, 1)
-                            .setBuffer(
-                                scCompat1,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.BLUE
-                                )
-                            )
-                            .setLayer(scCompat2, 0)
-                            .setBuffer(
-                                scCompat2,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.GREEN
-                                )
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                SurfaceControlWrapper.Transaction()
+                    .setLayer(scCompat1, 1)
+                    .setBuffer(
+                        scCompat1,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.BLUE
+                        )
+                    )
+                    .setLayer(scCompat2, 0)
+                    .setBuffer(
+                        scCompat2,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.GREEN
+                        )
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetLayer_positive() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat1 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
-                        val scCompat2 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat1 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
+                val scCompat2 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setLayer(scCompat1, 1)
-                            .setBuffer(
-                                scCompat1,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.GREEN
-                                )
-                            )
-                            .setLayer(scCompat2, 24)
-                            .setBuffer(
-                                scCompat2,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.BLUE
-                                )
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                SurfaceControlWrapper.Transaction()
+                    .setLayer(scCompat1, 1)
+                    .setBuffer(
+                        scCompat1,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.GREEN
+                        )
+                    )
+                    .setLayer(scCompat2, 24)
+                    .setBuffer(
+                        scCompat2,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.BLUE
+                        )
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetLayer_negative() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat1 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
-                        val scCompat2 = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat1 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
+                val scCompat2 = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setLayer(scCompat1, 1)
-                            .setBuffer(
-                                scCompat1,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.BLUE
-                                )
-                            )
-                            .setLayer(scCompat2, -7)
-                            .setBuffer(
-                                scCompat2,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.GREEN
-                                )
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                SurfaceControlWrapper.Transaction()
+                    .setLayer(scCompat1, 1)
+                    .setBuffer(
+                        scCompat1,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.BLUE
+                        )
+                    )
+                    .setLayer(scCompat2, -7)
+                    .setBuffer(
+                        scCompat2,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.GREEN
+                        )
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetDamageRegion_all() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setDamageRegion(
-                                scCompat,
-                                Region(
-                                    0,
-                                    0,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT
-                                )
-                            )
-                            .setBuffer(
-                                scCompat,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.BLUE
-                                )
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                SurfaceControlWrapper.Transaction()
+                    .setDamageRegion(
+                        scCompat,
+                        Region(
+                            0,
+                            0,
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT
+                        )
+                    )
+                    .setBuffer(
+                        scCompat,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.BLUE
+                        )
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetDamageRegion_null() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setDamageRegion(
-                                scCompat,
-                                null
-                            )
-                            .setBuffer(
-                                scCompat,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.BLUE
-                                )
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                SurfaceControlWrapper.Transaction()
+                    .setDamageRegion(
+                        scCompat,
+                        null
+                    )
+                    .setBuffer(
+                        scCompat,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.BLUE
+                        )
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetDesiredPresentTime_now() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(
-                                scCompat,
-                                SurfaceControlUtils.getSolidBuffer(
-                                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                    Color.BLUE
-                                )
-                            )
-                            .setDesiredPresentTime(0)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(
+                        scCompat,
+                        SurfaceControlUtils.getSolidBuffer(
+                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                            Color.BLUE
+                        )
+                    )
+                    .setDesiredPresentTime(0)
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetBufferTransparency_opaque() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setOpaque(
-                                scCompat,
-                                true
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setOpaque(
+                        scCompat,
+                        true
+                    )
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetAlpha_0_0() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setOpaque(
-                                scCompat,
-                                false
-                            )
-                            .setAlpha(scCompat, 0.0f)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setOpaque(
+                        scCompat,
+                        false
+                    )
+                    .setAlpha(scCompat, 0.0f)
+            },
+            { bitmap, rect ->
+                Color.BLACK == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.BLACK == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetAlpha_0_5() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setAlpha(scCompat, 0.5f)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setAlpha(scCompat, 0.5f)
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 val fConnector: ColorSpace.Connector = ColorSpace.connect(
                     ColorSpace.get(ColorSpace.Named.SRGB),
                     bitmap.colorSpace!!
@@ -969,139 +793,93 @@
                         expectedResult.blue() - bitmap.getColor(coord[0], coord[1]).blue()
                     ) < 2.5e-3f)
             }
-        }
+        )
     }
 
     @Test
     fun testTransactionSetAlpha_1_0() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setAlpha(scCompat, 1.0f)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setAlpha(scCompat, 1.0f)
+            },
+            { bitmap, rect ->
+                Color.RED == bitmap.getPixel(rect.left, rect.top)
             }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                Color.RED == bitmap.getPixel(coord[0], coord[1])
-            }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
     fun testTransactionSetCrop_null() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlWrapperTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlWrapperTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setCrop(scCompat, null)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setCrop(scCompat, null)
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 SurfaceControlUtils.checkNullCrop(bitmap, coord)
             }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
     fun testTransactionSetCrop_standardCrop() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setCrop(scCompat, Rect(20, 30, 90, 60))
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setCrop(scCompat, Rect(20, 30, 90, 60))
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 SurfaceControlUtils.checkStandardCrop(bitmap, coord)
             }
-        }
+        )
     }
 
     @Test
@@ -1172,44 +950,28 @@
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
     fun testTransactionSetPosition() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setPosition(scCompat, 30f, 30f)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
-                // Ensure it actually shifted by checking its outer bounds are black
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setPosition(scCompat, 30f, 30f)
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 Color.BLACK ==
                     bitmap.getPixel(
                         coord[0] + SurfaceControlWrapperTestActivity.DEFAULT_WIDTH / 2,
@@ -1222,49 +984,34 @@
                     ) &&
                     Color.RED == bitmap.getPixel(coord[0] + 30, coord[1] + 30)
             }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
     fun testTransactionSetScale() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getSolidBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setScale(scCompat, 0.5f, 0.5f)
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setScale(scCompat, 0.5f, 0.5f)
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 // Check outer bounds of square to ensure its scaled correctly
                 Color.RED == bitmap.getPixel(coord[0], coord[1]) &&
                     Color.RED ==
@@ -1279,55 +1026,40 @@
                         coord[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT / 2
                     )
             }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
     fun testTransactionSetBufferTransform_identity() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getQuadrantBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE,
-                            Color.BLACK,
-                            Color.BLACK,
-                            Color.BLACK
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getQuadrantBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE,
+                    Color.BLACK,
+                    Color.BLACK,
+                    Color.BLACK
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setBufferTransform(
-                                scCompat,
-                                SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setBufferTransform(
+                        scCompat,
+                        SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY
+                    )
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
 
                 // Check outer bounds of square to ensure its scaled correctly
                 Color.RED == bitmap.getPixel(coord[0], coord[1]) &&
@@ -1342,59 +1074,44 @@
                         coord[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT / 2
                     )
             }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     fun testTransactionSetGeometry_identity() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getQuadrantBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE,
-                            Color.BLACK,
-                            Color.BLACK,
-                            Color.BLACK
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getQuadrantBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE,
+                    Color.BLACK,
+                    Color.BLACK,
+                    Color.BLACK
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setGeometry(
-                                scCompat,
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setGeometry(
+                        scCompat,
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY
+                    )
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
 
                 // Check outer bounds of square to ensure its scaled correctly
                 Color.RED == bitmap.getPixel(coord[0], coord[1]) &&
@@ -1409,55 +1126,40 @@
                         coord[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT / 2
                     )
             }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
     fun testTransactionSetBufferTransform_singleTransform() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getQuadrantBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE,
-                            Color.BLACK,
-                            Color.BLACK,
-                            Color.BLACK
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getQuadrantBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE,
+                    Color.BLACK,
+                    Color.BLACK,
+                    Color.BLACK
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setBufferTransform(
-                                scCompat,
-                                SurfaceControlCompat.BUFFER_TRANSFORM_MIRROR_HORIZONTAL
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setBufferTransform(
+                        scCompat,
+                        SurfaceControlCompat.BUFFER_TRANSFORM_MIRROR_HORIZONTAL
+                    )
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 // Ensure it actually rotated by checking its outer bounds are black
                 Color.BLACK ==
                     bitmap.getPixel(
@@ -1475,59 +1177,44 @@
                         coord[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT / 2 - 1
                     )
             }
-        }
+        )
     }
 
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     fun testTransactionSetGeometry_singleTransform() {
-        val listener = TransactionOnCompleteListener()
-        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
-            .moveToState(
-                Lifecycle.State.CREATED
-            ).onActivity {
-                val callback = object : SurfaceHolderCallback() {
-                    override fun surfaceCreated(sh: SurfaceHolder) {
-                        val scCompat = SurfaceControlWrapper
-                            .Builder()
-                            .setParent(it.getSurfaceView().holder.surface)
-                            .setDebugName("SurfaceControlCompatTest")
-                            .build()
+        verifySurfaceControlWrapperTest(
+            { surfaceView ->
+                val scCompat = SurfaceControlWrapper
+                    .Builder()
+                    .setParent(surfaceView.holder.surface)
+                    .setDebugName("SurfaceControlCompatTest")
+                    .build()
 
-                        // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
-                        val buffer = SurfaceControlUtils.getQuadrantBuffer(
-                            SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                            SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                            Color.BLUE,
-                            Color.BLACK,
-                            Color.BLACK,
-                            Color.BLACK
-                        )
+                // Buffer colorspace is RGBA, so Color.BLUE will be visually Red
+                val buffer = SurfaceControlUtils.getQuadrantBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.BLUE,
+                    Color.BLACK,
+                    Color.BLACK,
+                    Color.BLACK
+                )
 
-                        SurfaceControlWrapper.Transaction()
-                            .addTransactionCompletedListener(listener)
-                            .setBuffer(scCompat, buffer)
-                            .setVisibility(scCompat, true)
-                            .setGeometry(
-                                scCompat,
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
-                                SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
-                                SurfaceControlCompat.BUFFER_TRANSFORM_MIRROR_HORIZONTAL
-                            )
-                            .commit()
-                    }
-                }
-
-                it.addSurface(it.mSurfaceView, callback)
-            }
-
-        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
-            assert(listener.mLatch.await(3000, TimeUnit.MILLISECONDS))
-            SurfaceControlUtils.validateOutput { bitmap ->
-                val coord = intArrayOf(0, 0)
-                it.mSurfaceView.getLocationOnScreen(coord)
+                SurfaceControlWrapper.Transaction()
+                    .setBuffer(scCompat, buffer)
+                    .setVisibility(scCompat, true)
+                    .setGeometry(
+                        scCompat,
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                        SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                        SurfaceControlCompat.BUFFER_TRANSFORM_MIRROR_HORIZONTAL
+                    )
+            },
+            { bitmap, rect ->
+                val coord = intArrayOf(rect.left, rect.top)
                 // Ensure it actually rotated by checking its outer bounds are black
                 Color.BLACK ==
                     bitmap.getPixel(
@@ -1545,7 +1232,33 @@
                         coord[1] + SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT / 2 - 1
                     )
             }
-        }
+        )
+    }
+
+    @RequiresApi(Build.VERSION_CODES.Q)
+    private fun verifySurfaceControlWrapperTest(
+        createTransaction: (SurfaceView) -> SurfaceControlWrapper.Transaction,
+        verifyOutput: (Bitmap, Rect) -> Boolean
+    ) {
+        SurfaceControlUtils.surfaceControlTestHelper(
+            { surfaceView, latch ->
+                val transaction = createTransaction(surfaceView)
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+                    transaction.addTransactionCommittedListener(
+                        executor!!,
+                        object : SurfaceControlCompat.TransactionCommittedListener {
+                            override fun onTransactionCommitted() {
+                                latch.countDown()
+                            }
+                        }
+                    )
+                } else {
+                    latch.countDown()
+                }
+                transaction.commit()
+            },
+            verifyOutput
+        )
     }
 
     fun Color.compositeOver(background: Color): Color {
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/hardware/SyncFenceV19Test.kt b/graphics/graphics-core/src/androidTest/java/androidx/hardware/SyncFenceV19Test.kt
index 7a0a842..889086f 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/hardware/SyncFenceV19Test.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/hardware/SyncFenceV19Test.kt
@@ -29,7 +29,6 @@
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
 @SmallTest
 class SyncFenceV19Test {
 
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRenderer.kt
index 742e437..7b58718 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRenderer.kt
@@ -31,13 +31,14 @@
 import androidx.hardware.HardwareBufferFormat
 import androidx.hardware.HardwareBufferUsage
 import androidx.hardware.SyncFenceCompat
-import java.lang.IllegalStateException
 import java.util.concurrent.Executor
+import kotlin.coroutines.resume
+import kotlinx.coroutines.suspendCancellableCoroutine
 
 /**
  * Creates an instance of a hardware-accelerated renderer. This is used to render a scene built
  * from [RenderNode]s to an output [HardwareBuffer]. There can be as many
- * HardwareBufferRenderer instances as desired.
+ * [CanvasBufferedRenderer] instances as desired.
  *
  * Resources & lifecycle
  *
@@ -125,7 +126,8 @@
      * Returns if the [CanvasBufferedRenderer] has already been closed. That is
      * [CanvasBufferedRenderer.close] has been invoked.
      */
-    fun isClosed(): Boolean = mImpl.isClosed()
+    val isClosed: Boolean
+        get() = mImpl.isClosed()
 
     /**
      * Returns a [RenderRequest] that can be used to render into the provided HardwareBuffer.
@@ -140,7 +142,7 @@
      * Sets the content root to render. It is not necessary to call this whenever the content
      * recording changes. Any mutations to the [RenderNode] content, or any of the [RenderNode]s
      * contained within the content node, will be applied whenever a new [RenderRequest] is issued
-     * via [obtainRenderRequest] and [RenderRequest.draw].
+     * via [obtainRenderRequest] and [RenderRequest.drawAsync].
      */
     fun setContentRoot(renderNode: RenderNode) {
         mImpl.setContentRoot(renderNode)
@@ -217,8 +219,8 @@
          * [CanvasBufferedRenderer].
          * If 1 is specified, then the created [CanvasBufferedRenderer] is running in
          * "single buffer mode". In this case consumption of the buffer content would need to be
-         * coordinated with the [SyncFenceCompat] returned by the callback of [RenderRequest.draw].
-         * @see CanvasBufferedRenderer.RenderRequest.draw
+         * coordinated with the [SyncFenceCompat] returned by the callback of [RenderRequest.drawAsync].
+         * @see CanvasBufferedRenderer.RenderRequest.drawAsync
          *
          * @param numBuffers The number of buffers within the swap chain to be consumed by the
          * created [CanvasBufferedRenderer]. This must be greater than zero. The default
@@ -312,14 +314,42 @@
          * @throws IllegalStateException if this method is invoked after the
          * [CanvasBufferedRenderer] has been closed.
          */
-        fun draw(executor: Executor, callback: Consumer<RenderResult>) {
-            if (isClosed()) {
+        fun drawAsync(executor: Executor, callback: Consumer<RenderResult>) {
+            if (isClosed) {
                 throw IllegalStateException("Attempt to draw after renderer has been closed")
             }
             mImpl.draw(this, executor, callback)
         }
 
         /**
+         * Syncs the [RenderNode] tree to the render thread and requests content to be drawn
+         * synchronously.
+         * This [RenderRequest] instance should no longer be used after calling this method.
+         * The system internally may reuse instances of [RenderRequest] to reduce allocation churn.
+         *
+         * @param waitForFence Optional flag to determine if the [SyncFenceCompat] is also waited
+         * upon before returning as a convenience in order to enable callers to consume the
+         * [HardwareBuffer] returned in the [RenderResult] immediately after this method returns.
+         * Passing `false` here on Android T and below is a no-op as the graphics rendering pipeline
+         * internally blocks on the fence before returning.
+         */
+        suspend fun draw(waitForFence: Boolean = true): RenderResult {
+            check(!isClosed) { "Attempt to draw after renderer has been closed" }
+
+            return suspendCancellableCoroutine { continuation ->
+                drawAsync(Runnable::run) { result ->
+                    if (waitForFence) {
+                        result.fence?.apply {
+                            awaitForever()
+                            close()
+                        }
+                    }
+                    continuation.resume(result)
+                }
+            }
+        }
+
+        /**
          * Specifies a transform to be applied before content is rendered. This is useful
          * for pre-rotating content for the current display orientation to increase performance
          * of displaying the associated buffer. This transformation will also adjust the light
@@ -367,11 +397,19 @@
         /**
          * Determines whether or not previous buffer contents will be persisted across render
          * requests. If false then contents are cleared before issuing drawing instructions,
-         * otherwise contents will remain. If contents are known in advance to be completely opaque
-         * and cover all pixels within the buffer, setting this flag to false will slightly improve
-         * performance as the clear operation will be skipped. Additionally for single buffered
-         * rendering scenarios, persisting contents can be beneficial in order to draw the deltas of
-         * content across frames. The default setting is false
+         * otherwise contents will remain.
+         *
+         * If contents are known in advance to be completely opaque and cover all pixels within the
+         * buffer, setting this flag to true will slightly improve performance as the clear
+         * operation will be skipped.
+         *
+         * For low latency use cases (ex applications that support drawing with a stylus), setting
+         * this value to true alongside single buffered rendering by configuring
+         * [CanvasBufferedRenderer.Builder.setMaxBuffers] to 1 allows for reduced latency by allowing
+         * consumers to only render the deltas across frames as the previous content would be
+         * persisted.
+         *
+         * The default setting is false.
          */
         fun preserveContents(preserve: Boolean): RenderRequest {
             mPreserveContents = preserve
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV29.kt b/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV29.kt
index acb359c..a9ae731 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV29.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV29.kt
@@ -155,7 +155,7 @@
                                     CanvasBufferedRenderer.RenderResult(
                                         buffer,
                                         fence,
-                                        if (result != 0) ERROR_UNKNOWN else SUCCESS
+                                        if (isSuccess(result)) SUCCESS else ERROR_UNKNOWN
                                     )
                                 )
                                 if (mMaxBuffers == 1) {
@@ -171,6 +171,14 @@
         }
     }
 
+    /**
+     * Helper method to determine if [HardwareRenderer.FrameRenderRequest.syncAndDraw] was
+     * successful. In this case we wait for the next buffer even if we miss the vsync.
+     */
+    private fun isSuccess(result: Int) =
+        result == HardwareRenderer.SYNC_OK ||
+        result == HardwareRenderer.SYNC_FRAME_DROPPED
+
     private fun updateTransform(transform: Int): Matrix {
         mBufferTransform = transform
         return BufferTransformHintResolver.configureTransformMatrix(
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/CanvasFrontBufferedRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/CanvasFrontBufferedRenderer.kt
index ba1ff48..062ef16 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/CanvasFrontBufferedRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/CanvasFrontBufferedRenderer.kt
@@ -453,7 +453,7 @@
             val frontBufferSurfaceControl = mFrontBufferSurfaceControl
             val parentSurfaceControl = mParentSurfaceControl
             val multiBufferedCanvasRenderer = mMultiBufferedCanvasRenderer
-            val colorSpace = mColorSpace
+            val targetColorSpace = mColorSpace
             mHandlerThread.execute {
                 multiBufferedCanvasRenderer?.let { multiBufferRenderer ->
                     with(multiBufferRenderer) {
@@ -469,8 +469,8 @@
                                     setBufferTransform(inverse)
                                 }
                             }
-                            .setColorSpace(colorSpace)
-                            .draw(mHandlerThread) { result ->
+                            .setColorSpace(targetColorSpace)
+                            .drawAsync(mHandlerThread) { result ->
                                 setParentSurfaceControlBuffer(
                                     frontBufferSurfaceControl,
                                     parentSurfaceControl,
@@ -525,7 +525,7 @@
             val multiBufferedCanvasRenderer = mMultiBufferedCanvasRenderer
             val inverse = mInverse
             val transform = mTransform
-            val colorSpace = mColorSpace
+            val targetColorSpace = mColorSpace
             mHandlerThread.execute {
                 multiBufferedCanvasRenderer?.let { multiBufferedRenderer ->
                     with(multiBufferedRenderer) {
@@ -542,8 +542,8 @@
                                     setBufferTransform(inverse)
                                 }
                             }
-                            .setColorSpace(colorSpace)
-                            .draw(mHandlerThread) { result ->
+                            .setColorSpace(targetColorSpace)
+                            .drawAsync(mHandlerThread) { result ->
                                 setParentSurfaceControlBuffer(
                                     frontBufferSurfaceControl,
                                     parentSurfaceControl,
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferSyncStrategy.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferSyncStrategy.kt
index b500c89..5915cdc 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferSyncStrategy.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferSyncStrategy.kt
@@ -18,8 +18,6 @@
 
 import android.hardware.HardwareBuffer
 import android.opengl.GLES20
-import android.os.Build
-import androidx.annotation.RequiresApi
 import androidx.graphics.opengl.FrameBufferRenderer
 import androidx.graphics.opengl.SyncStrategy
 import androidx.graphics.opengl.egl.EGLSpec
@@ -65,7 +63,6 @@
      * If front buffer usage is not supported, then a fence is created and destroyed to flush
      * contents to screen.
      */
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     override fun createSyncFence(eglSpec: EGLSpec): SyncFenceCompat? {
         return if (!isVisible) {
             SyncFenceCompat.createNativeSyncFence()
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/PreservedBufferContentsVerifier.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/PreservedBufferContentsVerifier.kt
index 2fe214f..3f15b61 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/PreservedBufferContentsVerifier.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/PreservedBufferContentsVerifier.kt
@@ -85,7 +85,7 @@
         val firstRenderLatch = CountDownLatch(1)
         multiBufferedRenderer.obtainRenderRequest()
             .preserveContents(true)
-            .draw(executor) { _ ->
+            .drawAsync(executor) { _ ->
                 firstRenderLatch.countDown()
             }
 
@@ -107,7 +107,7 @@
         val secondRenderLatch = CountDownLatch(1)
         multiBufferedRenderer.obtainRenderRequest()
             .preserveContents(true)
-            .draw(executor) { result ->
+            .drawAsync(executor) { result ->
                 result.fence?.awaitForever()
                 bitmap = Bitmap.wrapHardwareBuffer(
                     result.hardwareBuffer,
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt
index efee485..699ed6d 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt
@@ -102,8 +102,8 @@
                         setBufferTransform(transformHint)
                     }
                     preserveContents(true)
-                    setColorSpace(colorSpace)
-                    draw(executor) { result ->
+                    setColorSpace([email protected])
+                    drawAsync(executor) { result ->
                         requestComplete.invoke(result.hardwareBuffer, result.fence)
                     }
                 }
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt
index bafcff8..c49cc78 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt
@@ -211,7 +211,6 @@
      *
      * @param eglSpec an [EGLSpec] object to dictate the version of EGL and make EGL calls.
      */
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     fun createSyncFence(eglSpec: EGLSpec): SyncFenceCompat?
 
     companion object {
@@ -220,7 +219,6 @@
          */
         @JvmField
         val ALWAYS = object : SyncStrategy {
-            @RequiresApi(Build.VERSION_CODES.KITKAT)
             override fun createSyncFence(eglSpec: EGLSpec): SyncFenceCompat? {
                 return SyncFenceCompat.createNativeSyncFence()
             }
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
index 6362285..c2cd443 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
@@ -89,7 +89,6 @@
     }
 
     @JvmDefaultWithCompatibility
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     interface Transaction : AutoCloseable {
 
         /**
diff --git a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
index 581b0b2..0c5d152 100644
--- a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
+++ b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
@@ -35,7 +35,6 @@
  * [SurfaceControlCompat.Transaction.setBuffer]. Note that depending on API level, this will
  * utilize either [android.hardware.SyncFence] or a compatibility implementation.
  */
-@RequiresApi(Build.VERSION_CODES.KITKAT)
 class SyncFenceCompat : AutoCloseable {
     internal val mImpl: SyncFenceImpl
 
diff --git a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceV19.kt b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceV19.kt
index 13e9c66..3019108 100644
--- a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceV19.kt
+++ b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceV19.kt
@@ -33,7 +33,6 @@
  * When the fence signals, then the backing storage for the framebuffer may be safely read from,
  * such as for display or media encoding.
  */
-@RequiresApi(Build.VERSION_CODES.KITKAT)
 @JniVisible
 internal class SyncFenceV19(private var fd: Int) : AutoCloseable, SyncFenceImpl {
 
diff --git a/graphics/graphics-core/src/main/java/androidx/opengl/EGLExt.kt b/graphics/graphics-core/src/main/java/androidx/opengl/EGLExt.kt
index b851c5d..89acecb 100644
--- a/graphics/graphics-core/src/main/java/androidx/opengl/EGLExt.kt
+++ b/graphics/graphics-core/src/main/java/androidx/opengl/EGLExt.kt
@@ -573,7 +573,6 @@
          */
         @JvmStatic
         @Suppress("AcronymName")
-        @RequiresApi(Build.VERSION_CODES.KITKAT)
         internal fun eglDupNativeFenceFDANDROID(
             display: EGLDisplay,
             sync: EGLSyncKHR
diff --git a/graphics/graphics-shapes/src/androidInstrumentedTest/kotlin/androidx/graphics/shapes/RoundedPolygonTest.kt b/graphics/graphics-shapes/src/androidInstrumentedTest/kotlin/androidx/graphics/shapes/RoundedPolygonTest.kt
index 2ac9a18..79201f0 100644
--- a/graphics/graphics-shapes/src/androidInstrumentedTest/kotlin/androidx/graphics/shapes/RoundedPolygonTest.kt
+++ b/graphics/graphics-shapes/src/androidInstrumentedTest/kotlin/androidx/graphics/shapes/RoundedPolygonTest.kt
@@ -200,6 +200,46 @@
         }
     }
 
+    @Test
+    fun creatingFullSizeTest() {
+        val radius = 400f
+        val innerRadiusFactor = 0.35f
+        val innerRadius = radius * innerRadiusFactor
+        val roundingFactor = 0.32f
+
+        val fullSizeShape = RoundedPolygon.star(
+            numVerticesPerRadius = 4,
+            radius,
+            innerRadius,
+            rounding = CornerRounding(radius * roundingFactor),
+            innerRounding = CornerRounding(radius * roundingFactor),
+            centerX = radius,
+            centerY = radius
+        ).transformed { x, y -> TransformResult((x - radius) / radius, (y - radius) / radius) }
+
+        val canonicalShape = RoundedPolygon.star(
+            numVerticesPerRadius = 4,
+            1f,
+            innerRadiusFactor,
+            rounding = CornerRounding(roundingFactor),
+            innerRounding = CornerRounding(roundingFactor)
+        )
+
+        val cubics = canonicalShape.cubics
+        val cubics1 = fullSizeShape.cubics
+        assertEquals(cubics.size, cubics1.size)
+        cubics.zip(cubics1).forEach { (cubic, cubic1) ->
+            assertEqualish(cubic.anchor0X, cubic1.anchor0X)
+            assertEqualish(cubic.anchor0Y, cubic1.anchor0Y)
+            assertEqualish(cubic.anchor1X, cubic1.anchor1X)
+            assertEqualish(cubic.anchor1Y, cubic1.anchor1Y)
+            assertEqualish(cubic.control0X, cubic1.control0X)
+            assertEqualish(cubic.control0Y, cubic1.control0Y)
+            assertEqualish(cubic.control1X, cubic1.control1X)
+            assertEqualish(cubic.control1Y, cubic1.control1Y)
+        }
+    }
+
     private fun doUnevenSmoothTest(
         // Corner rounding parameter for vertex 0 (top left)
         rounding0: CornerRounding,
diff --git a/graphics/graphics-shapes/src/commonMain/kotlin/androidx/graphics/shapes/RoundedPolygon.kt b/graphics/graphics-shapes/src/commonMain/kotlin/androidx/graphics/shapes/RoundedPolygon.kt
index 375ab64..99b577e 100644
--- a/graphics/graphics-shapes/src/commonMain/kotlin/androidx/graphics/shapes/RoundedPolygon.kt
+++ b/graphics/graphics-shapes/src/commonMain/kotlin/androidx/graphics/shapes/RoundedPolygon.kt
@@ -572,8 +572,12 @@
     private fun lineIntersection(p0: Point, d0: Point, p1: Point, d1: Point): Point? {
         val rotatedD1 = d1.rotate90()
         val den = d0.dotProduct(rotatedD1)
-        if (abs(den) < AngleEpsilon) return null
-        val k = (p1 - p0).dotProduct(rotatedD1) / den
+        if (abs(den) < DistanceEpsilon) return null
+        val num = (p1 - p0).dotProduct(rotatedD1)
+        // Also check the relative value. This is equivalent to abs(den/num) < DistanceEpsilon,
+        // but avoid doing a division
+        if (abs(den) < DistanceEpsilon * abs(num)) return null
+        val k = num / den
         return p0 + d0 * k
     }
 }
diff --git a/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt b/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt
index 95d9889..0299054 100644
--- a/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt
+++ b/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt
@@ -15,6 +15,7 @@
  */
 package androidx.health.connect.client
 
+import android.app.Application
 import android.content.ComponentName
 import android.content.Context
 import android.content.IntentFilter
@@ -27,6 +28,8 @@
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
+import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Ignore
@@ -222,6 +225,29 @@
             .isNotNull()
     }
 
+    @Test
+    @Config(sdk = [Build.VERSION_CODES.TIRAMISU])
+    fun unbindableService_callThrowsIllegalStateException() {
+        installPackage(
+            context,
+            HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME,
+            versionCode = HealthConnectClient.DEFAULT_PROVIDER_MIN_VERSION_CODE,
+            enabled = true
+        )
+        installService(context, HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME)
+        shadowOf(context.applicationContext as Application)
+            .declareActionUnbindable(HealthDataService.ANDROID_HEALTH_PLATFORM_SERVICE_BIND_ACTION)
+
+        val permissionController =
+            HealthConnectClient.getOrCreate(context).permissionController
+        assertFailsWith<IllegalStateException> {
+            runBlocking {
+                // Simplest API call that requires no parameters
+                permissionController.getGrantedPermissions()
+            }
+        }
+    }
+
     private fun installPackage(
         context: Context,
         packageName: String,
diff --git a/health/connect/connect-client/src/test/java/androidx/health/platform/client/impl/ipc/internal/ServiceConnectionTest.java b/health/connect/connect-client/src/test/java/androidx/health/platform/client/impl/ipc/internal/ServiceConnectionTest.java
index 7336e28..cf4035b 100644
--- a/health/connect/connect-client/src/test/java/androidx/health/platform/client/impl/ipc/internal/ServiceConnectionTest.java
+++ b/health/connect/connect-client/src/test/java/androidx/health/platform/client/impl/ipc/internal/ServiceConnectionTest.java
@@ -57,27 +57,28 @@
     private final FakeConnectionCallback mConnectionCallback = new FakeConnectionCallback();
     private final VersionQueueOperation mVersionOperation = new VersionQueueOperation();
 
+    private ConnectionConfiguration mClientConfiguration;
     private ServiceConnection mConnection;
 
     @Before
     public void setUp() {
-        ConnectionConfiguration clientConfiguration =
+        mClientConfiguration =
                 new ConnectionConfiguration("", "client_name", "bind_action", mVersionOperation);
         Intent bindIntent =
                 new Intent()
-                        .setPackage(clientConfiguration.getPackageName())
-                        .setAction(clientConfiguration.getBindAction());
+                        .setPackage(mClientConfiguration.getPackageName())
+                        .setAction(mClientConfiguration.getBindAction());
         shadowOf((Application) getApplicationContext())
                 .setComponentNameAndServiceForBindServiceForIntent(
                         bindIntent,
                         new ComponentName(
-                                clientConfiguration.getPackageName(),
-                                clientConfiguration.getClientName()),
+                                mClientConfiguration.getPackageName(),
+                                mClientConfiguration.getClientName()),
                         mBinder);
         mConnection =
                 new ServiceConnection(
                         ApplicationProvider.getApplicationContext(),
-                        clientConfiguration,
+                        mClientConfiguration,
                         mTracker,
                         mConnectionCallback);
     }
@@ -159,6 +160,22 @@
     }
 
     @Test
+    public void enqueueOperation_unbindableService_throwsIllegalStateException() {
+        shadowOf((Application) getApplicationContext())
+                .declareComponentUnbindable(new ComponentName(mClientConfiguration.getPackageName(),
+                        mClientConfiguration.getClientName()
+                ));
+
+        FakeQueueOperation queueOperation = new FakeQueueOperation(mClientConfiguration);
+
+        mConnection.enqueue(queueOperation);
+        shadowOf(getMainLooper()).idle();
+
+        assertThat(queueOperation.isExecuted()).isFalse();
+        assertThat(queueOperation.mThrowable).isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
     public void clearConnection_failQueuedOperation() {
         SettableFuture<Void> settableFuture = SettableFuture.create();
         FakeQueueOperation queueOperation = new FakeQueueOperation(
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java
index 6dcaaa3..3403d9bf 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java
@@ -23,7 +23,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.input.motionprediction.common.SystemProperty;
+import androidx.input.motionprediction.common.Configuration;
 import androidx.input.motionprediction.kalman.KalmanMotionEventPredictor;
 import androidx.input.motionprediction.system.SystemMotionEventPredictor;
 
@@ -73,7 +73,7 @@
     static MotionEventPredictor newInstance(@NonNull View view) {
         Context context = view.getContext();
         if (Build.VERSION.SDK_INT >= 34
-                && SystemProperty.getBoolean("debug.input.prefer_system_prediction")) {
+                && Configuration.getInstance().preferSystemPrediction()) {
             return SystemMotionEventPredictor.newInstance(context);
         } else {
             return new KalmanMotionEventPredictor(context);
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/Configuration.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/Configuration.java
new file mode 100644
index 0000000..c0b64b5
--- /dev/null
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/Configuration.java
@@ -0,0 +1,85 @@
+/*
+ * 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.input.motionprediction.common;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/**
+ */
+@RestrictTo(LIBRARY)
+public class Configuration {
+    private static volatile Configuration sInstance = null;
+    private static final Object sLock = new Object();
+
+    private final boolean mPredictLift;
+    private final boolean mPreferSystemPrediction;
+    private final int mPredictionOffset;
+
+    /**
+     * Returns the configuration for prediction in this system.
+     *
+     * @return the prediction configuration
+     */
+    public static @NonNull Configuration getInstance() {
+        if (sInstance == null) {
+            synchronized (sLock) {
+                if (sInstance == null) {
+                    sInstance = new Configuration();
+                }
+            }
+        }
+        return sInstance;
+    }
+
+    private Configuration() {
+        // This class is non-instantiable externally.
+        mPreferSystemPrediction = SystemProperty
+                .getBoolean("debug.input.androidx_prefer_system_prediction");
+        mPredictionOffset = SystemProperty.getInt("debug.input.androidx_prediction_offset");
+        mPredictLift = SystemProperty.getBoolean("debug.input.androidx_predict_lift");
+    }
+
+    /**
+     * Returns whether or not the library should prefer the system prediction when available
+     *
+     * @return true if the system prediction should be used when available
+     */
+    public boolean preferSystemPrediction() {
+        return mPreferSystemPrediction;
+    }
+
+    /**
+     * Returns the number of milliseconds to add to the computed prediction target
+     *
+     * @return number of additional milliseconds to predict
+     */
+    public int predictionOffset() {
+        return mPredictionOffset;
+    }
+
+    /**
+     * Returns whether or not the pressure should be used to adjust the distance of the prediction
+     *
+     * @return true if the pressure should be used to determine the prediction length
+     */
+    public boolean predictLift() {
+        return mPredictLift;
+    }
+}
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/PredictionEstimator.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/PredictionEstimator.java
index 3376643..6bbd88c 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/PredictionEstimator.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/PredictionEstimator.java
@@ -41,9 +41,11 @@
 
     private long mLastEventTime = -1;
     private final float mFrameTimeMs;
+    private final int mOffsetMs;
 
     public PredictionEstimator(@NonNull Context context) {
         mFrameTimeMs = getFastestFrameTimeMs(context);
+        mOffsetMs = Configuration.getInstance().predictionOffset();
     }
 
     /** Records the needed information from the event to calculate the prediction. */
@@ -54,12 +56,12 @@
     /** Return the estimated amount of prediction needed. */
     public int estimate() {
         if (mLastEventTime <= 0) {
-            return (int) mFrameTimeMs;
+            return ((int) mFrameTimeMs) + mOffsetMs;
         }
         // The amount of prediction is the estimated amount of time it will take to land the
         // information on the screen from now, plus the time since the last recorded MotionEvent
         int estimatedMs = (int) (SystemClock.uptimeMillis() - mLastEventTime + mFrameTimeMs);
-        return Math.min(MAX_PREDICTION_MS, estimatedMs);
+        return Math.min(MAX_PREDICTION_MS, estimatedMs + mOffsetMs);
     }
 
     private Display getDisplayForContext(Context context) {
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/SystemProperty.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/SystemProperty.java
index 2899359..6375163 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/SystemProperty.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/common/SystemProperty.java
@@ -29,7 +29,8 @@
  */
 @RestrictTo(LIBRARY)
 public class SystemProperty {
-    private static final boolean PROPERTY_DEFAULT = false;
+    private static final boolean BOOLEAN_PROPERTY_DEFAULT = false;
+    private static final int INT_PROPERTY_DEFAULT = 0;
 
     private SystemProperty() {
         // This class is non-instantiable.
@@ -50,12 +51,42 @@
                     String.class,
                     boolean.class);
             @SuppressLint("BanUncheckedReflection")
-            Boolean result = (Boolean) getMethod.invoke(systemProperties, name, PROPERTY_DEFAULT);
+            Boolean result = (Boolean) getMethod.invoke(
+                    systemProperties,
+                    name,
+                    BOOLEAN_PROPERTY_DEFAULT);
             if (result != null) {
                 return result.booleanValue();
             }
         } catch (Exception e) {
         }
-        return false;
+        return BOOLEAN_PROPERTY_DEFAULT;
+    }
+
+    /**
+     * Reads a system property and returns its integer value.
+     *
+     * @param name the name of the system property
+     * @return the integer value of the property if defined, zero otherwise
+     */
+    public static int getInt(@NonNull String name) {
+        try {
+            @SuppressLint("PrivateApi")
+            Class<?> systemProperties = Class.forName("android.os.SystemProperties");
+            Method getMethod = systemProperties.getMethod(
+                    "getInt",
+                    String.class,
+                    int.class);
+            @SuppressLint("BanUncheckedReflection")
+            Integer result = (Integer) getMethod.invoke(
+                    systemProperties,
+                    name,
+                    INT_PROPERTY_DEFAULT);
+            if (result != null) {
+                return result.intValue();
+            }
+        } catch (Exception e) {
+        }
+        return INT_PROPERTY_DEFAULT;
     }
 }
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
index fd64a94..f5d22c3 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
@@ -24,6 +24,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.input.motionprediction.common.Configuration;
 import androidx.input.motionprediction.kalman.matrix.DVector2;
 
 import java.util.LinkedList;
@@ -92,6 +93,8 @@
     private double mLastOrientation = 0;
     private double mLastTilt = 0;
 
+    private final boolean mPredictLift;
+
     /**
      * Kalman based predictor, predicting the location of the pen `predictionTarget`
      * milliseconds into the future.
@@ -107,6 +110,7 @@
         mDownEventTime = 0;
         mPointerId = pointerId;
         mToolType = toolType;
+        mPredictLift = Configuration.getInstance().predictLift();
     }
 
     private void update(float x, float y, float pressure, float orientation,
@@ -277,7 +281,8 @@
             long nextPredictedEventTime = predictedEventTime + Math.round(mReportRateMs);
 
             // Abort prediction if the pen is to be lifted.
-            if (mPressure < 0.1
+            if (mPredictLift
+                    && mPressure < 0.1
                     && nextPredictedEventTime > mLastPredictEventTime) {
                 //TODO: Should we generate ACTION_UP MotionEvent instead of ACTION_MOVE?
                 break;
diff --git a/input/input-motionprediction/src/test/kotlin/androidx/input/motionprediction/kalman/SinglePointerPredictorTest.kt b/input/input-motionprediction/src/test/kotlin/androidx/input/motionprediction/kalman/SinglePointerPredictorTest.kt
index 2f66349..d14ac06 100644
--- a/input/input-motionprediction/src/test/kotlin/androidx/input/motionprediction/kalman/SinglePointerPredictorTest.kt
+++ b/input/input-motionprediction/src/test/kotlin/androidx/input/motionprediction/kalman/SinglePointerPredictorTest.kt
@@ -92,23 +92,22 @@
     }
 
     @Test
-    fun predictionNeverGoesBackwardsEvenWhenLifting() {
+    fun liftingDoesNotAffectPredictionDistance() {
         val predictor = constructPredictor()
         val coordGenerator = { delta: Long -> delta.toFloat() }
         // Pressure will be 1 at the beginning and trend to zero while never getting there
         val pressureGenerator = fun(delta: Long): Float {
-                if (delta > 500) {
-                    return ((700 - delta) / 500).toFloat()
-                }
-                return 1f
+            if (delta > 500) {
+                return ((700 - delta) / 500).toFloat()
             }
+            return 1f
+        }
         val motionGenerator =
                 MotionEventGenerator(coordGenerator, coordGenerator, pressureGenerator)
         var lastPredictedTime = 0L
         var lastPredictedEvent: MotionEvent? = null
         var predicted: MotionEvent?
-        var iteration = 0
-        do {
+        for (i in 1..MAX_ITERATIONS) {
             predictor.onTouchEvent(motionGenerator.next())
             predicted = predictor.predict(motionGenerator.getRateMs().toInt() * 10)
             if (predicted != null) {
@@ -118,8 +117,10 @@
                 assertThat(lastPredictedEvent.getHistorySize()).isEqualTo(0);
             }
             lastPredictedEvent = predicted
-            iteration++
-        } while (predicted != null || iteration < INITIAL_FEED)
+            if (i > INITIAL_FEED) {
+                assertThat(predicted).isNotNull()
+            }
+        }
     }
 }
 
@@ -129,4 +130,5 @@
 )
 
 private const val INITIAL_FEED = 20
+private const val MAX_ITERATIONS = 10000
 private const val PREDICT_LENGTH = 10
diff --git a/kruth/kruth/api/api_lint.ignore b/kruth/kruth/api/api_lint.ignore
index 97444da..7ac8a1f 100644
--- a/kruth/kruth/api/api_lint.ignore
+++ b/kruth/kruth/api/api_lint.ignore
@@ -7,6 +7,10 @@
     Method parameter should be Collection<Object> (or subclass) instead of raw array; was `java.lang.Object[]`
 ArrayReturn: androidx.kruth.IterableSubject#containsNoneIn(Object[]) parameter #0:
     Method parameter should be Collection<Object> (or subclass) instead of raw array; was `java.lang.Object[]`
+ArrayReturn: androidx.kruth.KruthKt#assertThat(T[]) parameter #0:
+    Method parameter should be Collection<T> (or subclass) instead of raw array; was `T[]`
+ArrayReturn: androidx.kruth.StandardSubjectBuilder#that(T[]) parameter #0:
+    Method parameter should be Collection<T> (or subclass) instead of raw array; was `T[]`
 
 
 AutoBoxing: androidx.kruth.KruthKt#assertThat(Boolean) parameter #0:
@@ -43,10 +47,26 @@
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(String)
 BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(T):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(T)
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(T[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(T[])
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(boolean[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(boolean[])
 BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(byte[]):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(byte[])
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(char[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(char[])
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(double[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(double[])
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(float[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(float[])
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(int[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(int[])
 BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(java.util.Map<K,? extends V>):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(java.util.Map<K,? extends V>)
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(long[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(long[])
+BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#that(short[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.that(short[])
 BuilderSetStyle: androidx.kruth.StandardSubjectBuilder#withMessage(String):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.kruth.StandardSubjectBuilder.withMessage(String)
 
diff --git a/kruth/kruth/api/current.ignore b/kruth/kruth/api/current.ignore
index 33fd741..f064a31 100644
--- a/kruth/kruth/api/current.ignore
+++ b/kruth/kruth/api/current.ignore
@@ -39,8 +39,20 @@
     Class androidx.kruth.ThrowableSubject added 'final' qualifier
 
 
+ChangedType: androidx.kruth.ObjectArraySubject#asList():
+    Method androidx.kruth.ObjectArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<?>
+ChangedType: androidx.kruth.PrimitiveBooleanArraySubject#asList():
+    Method androidx.kruth.PrimitiveBooleanArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Boolean>
 ChangedType: androidx.kruth.PrimitiveByteArraySubject#asList():
     Method androidx.kruth.PrimitiveByteArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Byte>
+ChangedType: androidx.kruth.PrimitiveCharArraySubject#asList():
+    Method androidx.kruth.PrimitiveCharArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Character>
+ChangedType: androidx.kruth.PrimitiveIntArraySubject#asList():
+    Method androidx.kruth.PrimitiveIntArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Integer>
+ChangedType: androidx.kruth.PrimitiveLongArraySubject#asList():
+    Method androidx.kruth.PrimitiveLongArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Long>
+ChangedType: androidx.kruth.PrimitiveShortArraySubject#asList():
+    Method androidx.kruth.PrimitiveShortArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Short>
 ChangedType: androidx.kruth.SimpleSubjectBuilder#that(T):
     Method androidx.kruth.SimpleSubjectBuilder.that has changed return type from SubjectT (extends androidx.kruth.Subject) to S (extends androidx.kruth.Subject<? extends T>)
 ChangedType: androidx.kruth.StandardSubjectBuilder#about(androidx.kruth.Subject.Factory<? extends S,T>):
@@ -51,8 +63,8 @@
     Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<T>
 ChangedType: androidx.kruth.StandardSubjectBuilder#that(T):
     Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.ClassSubject to androidx.kruth.Subject<T>
-ChangedType: androidx.kruth.StandardSubjectBuilder#that(byte[]):
-    Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.ObjectArraySubject<T> to androidx.kruth.PrimitiveByteArraySubject
+ChangedType: androidx.kruth.StandardSubjectBuilder#that(T[]):
+    Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.ObjectArraySubject<T> to androidx.kruth.ObjectArraySubject<T>
 ChangedType: androidx.kruth.StandardSubjectBuilder#that(java.util.Map<K,? extends V>):
     Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.MapSubject to androidx.kruth.MapSubject<K,V>
 ChangedType: androidx.kruth.Subject#failWithActual(String, Object):
@@ -123,22 +135,10 @@
     Removed class androidx.kruth.MultimapSubject
 RemovedClass: androidx.kruth.MultisetSubject:
     Removed class androidx.kruth.MultisetSubject
-RemovedClass: androidx.kruth.ObjectArraySubject:
-    Removed class androidx.kruth.ObjectArraySubject
-RemovedClass: androidx.kruth.PrimitiveBooleanArraySubject:
-    Removed class androidx.kruth.PrimitiveBooleanArraySubject
-RemovedClass: androidx.kruth.PrimitiveCharArraySubject:
-    Removed class androidx.kruth.PrimitiveCharArraySubject
-RemovedClass: androidx.kruth.PrimitiveDoubleArraySubject:
-    Removed class androidx.kruth.PrimitiveDoubleArraySubject
-RemovedClass: androidx.kruth.PrimitiveFloatArraySubject:
-    Removed class androidx.kruth.PrimitiveFloatArraySubject
-RemovedClass: androidx.kruth.PrimitiveIntArraySubject:
-    Removed class androidx.kruth.PrimitiveIntArraySubject
-RemovedClass: androidx.kruth.PrimitiveLongArraySubject:
-    Removed class androidx.kruth.PrimitiveLongArraySubject
-RemovedClass: androidx.kruth.PrimitiveShortArraySubject:
-    Removed class androidx.kruth.PrimitiveShortArraySubject
+RemovedClass: androidx.kruth.PrimitiveDoubleArraySubject.DoubleArrayAsIterable:
+    Removed class androidx.kruth.PrimitiveDoubleArraySubject.DoubleArrayAsIterable
+RemovedClass: androidx.kruth.PrimitiveFloatArraySubject.FloatArrayAsIterable:
+    Removed class androidx.kruth.PrimitiveFloatArraySubject.FloatArrayAsIterable
 RemovedClass: androidx.kruth.TableSubject:
     Removed class androidx.kruth.TableSubject
 RemovedClass: androidx.kruth.Truth:
@@ -181,6 +181,14 @@
     Removed method androidx.kruth.MapSubject.containsExactly(Object,Object,java.lang.Object...)
 RemovedMethod: androidx.kruth.MapSubject#formattingDiffsUsing(androidx.kruth.Correspondence.DiffFormatter<? super V,? super V>):
     Removed method androidx.kruth.MapSubject.formattingDiffsUsing(androidx.kruth.Correspondence.DiffFormatter<? super V,? super V>)
+RemovedMethod: androidx.kruth.PrimitiveDoubleArraySubject#usingExactEquality():
+    Removed method androidx.kruth.PrimitiveDoubleArraySubject.usingExactEquality()
+RemovedMethod: androidx.kruth.PrimitiveDoubleArraySubject#usingTolerance(double):
+    Removed method androidx.kruth.PrimitiveDoubleArraySubject.usingTolerance(double)
+RemovedMethod: androidx.kruth.PrimitiveFloatArraySubject#usingExactEquality():
+    Removed method androidx.kruth.PrimitiveFloatArraySubject.usingExactEquality()
+RemovedMethod: androidx.kruth.PrimitiveFloatArraySubject#usingTolerance(double):
+    Removed method androidx.kruth.PrimitiveFloatArraySubject.usingTolerance(double)
 RemovedMethod: androidx.kruth.StandardSubjectBuilder#about(androidx.kruth.CustomSubjectBuilder.Factory<CustomSubjectBuilderT>):
     Removed method androidx.kruth.StandardSubjectBuilder.about(androidx.kruth.CustomSubjectBuilder.Factory<CustomSubjectBuilderT>)
 RemovedMethod: androidx.kruth.StandardSubjectBuilder#withMessage(String, java.lang.Object...):
diff --git a/kruth/kruth/api/current.txt b/kruth/kruth/api/current.txt
index 8c39acad..4ab5149 100644
--- a/kruth/kruth/api/current.txt
+++ b/kruth/kruth/api/current.txt
@@ -113,16 +113,24 @@
 
   public final class KruthKt {
     method public static <S extends androidx.kruth.Subject<? extends T>, T> androidx.kruth.SimpleSubjectBuilder<S,T> assertAbout(androidx.kruth.Subject.Factory<? extends S,T> subjectFactory);
+    method public static androidx.kruth.PrimitiveBooleanArraySubject assertThat(boolean[]? actual);
     method public static androidx.kruth.PrimitiveByteArraySubject assertThat(byte[]? actual);
+    method public static androidx.kruth.PrimitiveCharArraySubject assertThat(char[]? actual);
+    method public static androidx.kruth.PrimitiveDoubleArraySubject assertThat(double[]? actual);
+    method public static androidx.kruth.PrimitiveFloatArraySubject assertThat(float[]? actual);
+    method public static androidx.kruth.PrimitiveIntArraySubject assertThat(int[]? actual);
     method public static androidx.kruth.BooleanSubject assertThat(Boolean? actual);
     method public static androidx.kruth.DoubleSubject assertThat(Double? actual);
     method public static androidx.kruth.IntegerSubject assertThat(Integer? actual);
     method public static <T> androidx.kruth.IterableSubject<T> assertThat(Iterable<? extends T>? actual);
     method public static androidx.kruth.StringSubject assertThat(String? actual);
     method public static <K, V> androidx.kruth.MapSubject<K,V> assertThat(java.util.Map<K,? extends V>? actual);
+    method public static androidx.kruth.PrimitiveLongArraySubject assertThat(long[]? actual);
+    method public static androidx.kruth.PrimitiveShortArraySubject assertThat(short[]? actual);
     method public static <T extends java.lang.Comparable<? super T>> androidx.kruth.ComparableSubject<T> assertThat(T? actual);
     method public static <T> androidx.kruth.Subject<T> assertThat(T? actual);
     method public static <T extends java.lang.Throwable> androidx.kruth.ThrowableSubject<T> assertThat(T? actual);
+    method public static <T> androidx.kruth.ObjectArraySubject<T> assertThat(T![]? actual);
     method public static androidx.kruth.StandardSubjectBuilder assertWithMessage(String messageToPrepend);
   }
 
@@ -142,10 +150,24 @@
     method public void isNotEmpty();
   }
 
+  public final class ObjectArraySubject<T> extends androidx.kruth.Subject<T[]> {
+    method public androidx.kruth.IterableSubject<?> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
   public interface Ordered {
     method public void inOrder();
   }
 
+  public final class PrimitiveBooleanArraySubject extends androidx.kruth.Subject<boolean[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Boolean> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
   public final class PrimitiveByteArraySubject extends androidx.kruth.Subject<byte[]> {
     method public androidx.kruth.IterableSubject<java.lang.Byte> asList();
     method public void hasLength(int length);
@@ -153,6 +175,48 @@
     method public void isNotEmpty();
   }
 
+  public final class PrimitiveCharArraySubject extends androidx.kruth.Subject<char[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Character> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveDoubleArraySubject extends androidx.kruth.Subject<double[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Double> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveFloatArraySubject extends androidx.kruth.Subject<float[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Float> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveIntArraySubject extends androidx.kruth.Subject<int[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Integer> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveLongArraySubject extends androidx.kruth.Subject<long[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Long> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveShortArraySubject extends androidx.kruth.Subject<short[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Short> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
   public final class SimpleSubjectBuilder<S extends androidx.kruth.Subject<? extends T>, T> {
     method public S that(T actual);
   }
@@ -160,23 +224,31 @@
   public final class StandardSubjectBuilder {
     method public <T, S extends androidx.kruth.Subject<? extends T>> androidx.kruth.SimpleSubjectBuilder<S,T> about(androidx.kruth.Subject.Factory<? extends S,T> subjectFactory);
     method public Void fail();
-    method public static androidx.kruth.StandardSubjectBuilder? forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
+    method public static androidx.kruth.StandardSubjectBuilder forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
+    method public androidx.kruth.PrimitiveBooleanArraySubject that(boolean[]? actual);
     method public androidx.kruth.PrimitiveByteArraySubject that(byte[]? actual);
+    method public androidx.kruth.PrimitiveCharArraySubject that(char[]? actual);
+    method public androidx.kruth.PrimitiveDoubleArraySubject that(double[]? actual);
+    method public androidx.kruth.PrimitiveFloatArraySubject that(float[]? actual);
+    method public androidx.kruth.PrimitiveIntArraySubject that(int[]? actual);
     method public androidx.kruth.BooleanSubject that(Boolean? actual);
     method public androidx.kruth.DoubleSubject that(Double? actual);
     method public androidx.kruth.IntegerSubject that(Integer? actual);
     method public <T> androidx.kruth.IterableSubject<T> that(Iterable<? extends T>? actual);
     method public androidx.kruth.StringSubject that(String? actual);
     method public <K, V> androidx.kruth.MapSubject<K,V> that(java.util.Map<K,? extends V>? actual);
+    method public androidx.kruth.PrimitiveLongArraySubject that(long[]? actual);
+    method public androidx.kruth.PrimitiveShortArraySubject that(short[]? actual);
     method public <T> androidx.kruth.Subject<T> that(T actual);
     method public <T extends java.lang.Comparable<? super T>> androidx.kruth.ComparableSubject<T> that(T? actual);
     method public <T extends java.lang.Throwable> androidx.kruth.ThrowableSubject<T> that(T? actual);
+    method public <T> androidx.kruth.ObjectArraySubject<T> that(T![]? actual);
     method public androidx.kruth.StandardSubjectBuilder withMessage(String messageToPrepend);
     field public static final androidx.kruth.StandardSubjectBuilder.Companion Companion;
   }
 
   public static final class StandardSubjectBuilder.Companion {
-    method public androidx.kruth.StandardSubjectBuilder? forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
+    method public androidx.kruth.StandardSubjectBuilder forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
   }
 
   public final class StringSubject extends androidx.kruth.ComparableSubject<java.lang.String> {
diff --git a/kruth/kruth/api/restricted_current.ignore b/kruth/kruth/api/restricted_current.ignore
index 33fd741..f064a31 100644
--- a/kruth/kruth/api/restricted_current.ignore
+++ b/kruth/kruth/api/restricted_current.ignore
@@ -39,8 +39,20 @@
     Class androidx.kruth.ThrowableSubject added 'final' qualifier
 
 
+ChangedType: androidx.kruth.ObjectArraySubject#asList():
+    Method androidx.kruth.ObjectArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<?>
+ChangedType: androidx.kruth.PrimitiveBooleanArraySubject#asList():
+    Method androidx.kruth.PrimitiveBooleanArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Boolean>
 ChangedType: androidx.kruth.PrimitiveByteArraySubject#asList():
     Method androidx.kruth.PrimitiveByteArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Byte>
+ChangedType: androidx.kruth.PrimitiveCharArraySubject#asList():
+    Method androidx.kruth.PrimitiveCharArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Character>
+ChangedType: androidx.kruth.PrimitiveIntArraySubject#asList():
+    Method androidx.kruth.PrimitiveIntArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Integer>
+ChangedType: androidx.kruth.PrimitiveLongArraySubject#asList():
+    Method androidx.kruth.PrimitiveLongArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Long>
+ChangedType: androidx.kruth.PrimitiveShortArraySubject#asList():
+    Method androidx.kruth.PrimitiveShortArraySubject.asList has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<java.lang.Short>
 ChangedType: androidx.kruth.SimpleSubjectBuilder#that(T):
     Method androidx.kruth.SimpleSubjectBuilder.that has changed return type from SubjectT (extends androidx.kruth.Subject) to S (extends androidx.kruth.Subject<? extends T>)
 ChangedType: androidx.kruth.StandardSubjectBuilder#about(androidx.kruth.Subject.Factory<? extends S,T>):
@@ -51,8 +63,8 @@
     Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.IterableSubject to androidx.kruth.IterableSubject<T>
 ChangedType: androidx.kruth.StandardSubjectBuilder#that(T):
     Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.ClassSubject to androidx.kruth.Subject<T>
-ChangedType: androidx.kruth.StandardSubjectBuilder#that(byte[]):
-    Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.ObjectArraySubject<T> to androidx.kruth.PrimitiveByteArraySubject
+ChangedType: androidx.kruth.StandardSubjectBuilder#that(T[]):
+    Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.ObjectArraySubject<T> to androidx.kruth.ObjectArraySubject<T>
 ChangedType: androidx.kruth.StandardSubjectBuilder#that(java.util.Map<K,? extends V>):
     Method androidx.kruth.StandardSubjectBuilder.that has changed return type from androidx.kruth.MapSubject to androidx.kruth.MapSubject<K,V>
 ChangedType: androidx.kruth.Subject#failWithActual(String, Object):
@@ -123,22 +135,10 @@
     Removed class androidx.kruth.MultimapSubject
 RemovedClass: androidx.kruth.MultisetSubject:
     Removed class androidx.kruth.MultisetSubject
-RemovedClass: androidx.kruth.ObjectArraySubject:
-    Removed class androidx.kruth.ObjectArraySubject
-RemovedClass: androidx.kruth.PrimitiveBooleanArraySubject:
-    Removed class androidx.kruth.PrimitiveBooleanArraySubject
-RemovedClass: androidx.kruth.PrimitiveCharArraySubject:
-    Removed class androidx.kruth.PrimitiveCharArraySubject
-RemovedClass: androidx.kruth.PrimitiveDoubleArraySubject:
-    Removed class androidx.kruth.PrimitiveDoubleArraySubject
-RemovedClass: androidx.kruth.PrimitiveFloatArraySubject:
-    Removed class androidx.kruth.PrimitiveFloatArraySubject
-RemovedClass: androidx.kruth.PrimitiveIntArraySubject:
-    Removed class androidx.kruth.PrimitiveIntArraySubject
-RemovedClass: androidx.kruth.PrimitiveLongArraySubject:
-    Removed class androidx.kruth.PrimitiveLongArraySubject
-RemovedClass: androidx.kruth.PrimitiveShortArraySubject:
-    Removed class androidx.kruth.PrimitiveShortArraySubject
+RemovedClass: androidx.kruth.PrimitiveDoubleArraySubject.DoubleArrayAsIterable:
+    Removed class androidx.kruth.PrimitiveDoubleArraySubject.DoubleArrayAsIterable
+RemovedClass: androidx.kruth.PrimitiveFloatArraySubject.FloatArrayAsIterable:
+    Removed class androidx.kruth.PrimitiveFloatArraySubject.FloatArrayAsIterable
 RemovedClass: androidx.kruth.TableSubject:
     Removed class androidx.kruth.TableSubject
 RemovedClass: androidx.kruth.Truth:
@@ -181,6 +181,14 @@
     Removed method androidx.kruth.MapSubject.containsExactly(Object,Object,java.lang.Object...)
 RemovedMethod: androidx.kruth.MapSubject#formattingDiffsUsing(androidx.kruth.Correspondence.DiffFormatter<? super V,? super V>):
     Removed method androidx.kruth.MapSubject.formattingDiffsUsing(androidx.kruth.Correspondence.DiffFormatter<? super V,? super V>)
+RemovedMethod: androidx.kruth.PrimitiveDoubleArraySubject#usingExactEquality():
+    Removed method androidx.kruth.PrimitiveDoubleArraySubject.usingExactEquality()
+RemovedMethod: androidx.kruth.PrimitiveDoubleArraySubject#usingTolerance(double):
+    Removed method androidx.kruth.PrimitiveDoubleArraySubject.usingTolerance(double)
+RemovedMethod: androidx.kruth.PrimitiveFloatArraySubject#usingExactEquality():
+    Removed method androidx.kruth.PrimitiveFloatArraySubject.usingExactEquality()
+RemovedMethod: androidx.kruth.PrimitiveFloatArraySubject#usingTolerance(double):
+    Removed method androidx.kruth.PrimitiveFloatArraySubject.usingTolerance(double)
 RemovedMethod: androidx.kruth.StandardSubjectBuilder#about(androidx.kruth.CustomSubjectBuilder.Factory<CustomSubjectBuilderT>):
     Removed method androidx.kruth.StandardSubjectBuilder.about(androidx.kruth.CustomSubjectBuilder.Factory<CustomSubjectBuilderT>)
 RemovedMethod: androidx.kruth.StandardSubjectBuilder#withMessage(String, java.lang.Object...):
diff --git a/kruth/kruth/api/restricted_current.txt b/kruth/kruth/api/restricted_current.txt
index 66bf3b0..e00143f 100644
--- a/kruth/kruth/api/restricted_current.txt
+++ b/kruth/kruth/api/restricted_current.txt
@@ -113,16 +113,24 @@
 
   public final class KruthKt {
     method public static <S extends androidx.kruth.Subject<? extends T>, T> androidx.kruth.SimpleSubjectBuilder<S,T> assertAbout(androidx.kruth.Subject.Factory<? extends S,T> subjectFactory);
+    method public static androidx.kruth.PrimitiveBooleanArraySubject assertThat(boolean[]? actual);
     method public static androidx.kruth.PrimitiveByteArraySubject assertThat(byte[]? actual);
+    method public static androidx.kruth.PrimitiveCharArraySubject assertThat(char[]? actual);
+    method public static androidx.kruth.PrimitiveDoubleArraySubject assertThat(double[]? actual);
+    method public static androidx.kruth.PrimitiveFloatArraySubject assertThat(float[]? actual);
+    method public static androidx.kruth.PrimitiveIntArraySubject assertThat(int[]? actual);
     method public static androidx.kruth.BooleanSubject assertThat(Boolean? actual);
     method public static androidx.kruth.DoubleSubject assertThat(Double? actual);
     method public static androidx.kruth.IntegerSubject assertThat(Integer? actual);
     method public static <T> androidx.kruth.IterableSubject<T> assertThat(Iterable<? extends T>? actual);
     method public static androidx.kruth.StringSubject assertThat(String? actual);
     method public static <K, V> androidx.kruth.MapSubject<K,V> assertThat(java.util.Map<K,? extends V>? actual);
+    method public static androidx.kruth.PrimitiveLongArraySubject assertThat(long[]? actual);
+    method public static androidx.kruth.PrimitiveShortArraySubject assertThat(short[]? actual);
     method public static <T extends java.lang.Comparable<? super T>> androidx.kruth.ComparableSubject<T> assertThat(T? actual);
     method public static <T> androidx.kruth.Subject<T> assertThat(T? actual);
     method public static <T extends java.lang.Throwable> androidx.kruth.ThrowableSubject<T> assertThat(T? actual);
+    method public static <T> androidx.kruth.ObjectArraySubject<T> assertThat(T![]? actual);
     method public static androidx.kruth.StandardSubjectBuilder assertWithMessage(String messageToPrepend);
   }
 
@@ -142,10 +150,24 @@
     method public void isNotEmpty();
   }
 
+  public final class ObjectArraySubject<T> extends androidx.kruth.Subject<T[]> {
+    method public androidx.kruth.IterableSubject<?> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
   public interface Ordered {
     method public void inOrder();
   }
 
+  public final class PrimitiveBooleanArraySubject extends androidx.kruth.Subject<boolean[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Boolean> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
   public final class PrimitiveByteArraySubject extends androidx.kruth.Subject<byte[]> {
     method public androidx.kruth.IterableSubject<java.lang.Byte> asList();
     method public void hasLength(int length);
@@ -153,6 +175,48 @@
     method public void isNotEmpty();
   }
 
+  public final class PrimitiveCharArraySubject extends androidx.kruth.Subject<char[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Character> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveDoubleArraySubject extends androidx.kruth.Subject<double[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Double> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveFloatArraySubject extends androidx.kruth.Subject<float[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Float> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveIntArraySubject extends androidx.kruth.Subject<int[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Integer> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveLongArraySubject extends androidx.kruth.Subject<long[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Long> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
+  public final class PrimitiveShortArraySubject extends androidx.kruth.Subject<short[]> {
+    method public androidx.kruth.IterableSubject<java.lang.Short> asList();
+    method public void hasLength(int length);
+    method public void isEmpty();
+    method public void isNotEmpty();
+  }
+
   public final class SimpleSubjectBuilder<S extends androidx.kruth.Subject<? extends T>, T> {
     method public S that(T actual);
   }
@@ -160,23 +224,31 @@
   public final class StandardSubjectBuilder {
     method public <T, S extends androidx.kruth.Subject<? extends T>> androidx.kruth.SimpleSubjectBuilder<S,T> about(androidx.kruth.Subject.Factory<? extends S,T> subjectFactory);
     method public Void fail();
-    method public static androidx.kruth.StandardSubjectBuilder? forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
+    method public static androidx.kruth.StandardSubjectBuilder forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
+    method public androidx.kruth.PrimitiveBooleanArraySubject that(boolean[]? actual);
     method public androidx.kruth.PrimitiveByteArraySubject that(byte[]? actual);
+    method public androidx.kruth.PrimitiveCharArraySubject that(char[]? actual);
+    method public androidx.kruth.PrimitiveDoubleArraySubject that(double[]? actual);
+    method public androidx.kruth.PrimitiveFloatArraySubject that(float[]? actual);
+    method public androidx.kruth.PrimitiveIntArraySubject that(int[]? actual);
     method public androidx.kruth.BooleanSubject that(Boolean? actual);
     method public androidx.kruth.DoubleSubject that(Double? actual);
     method public androidx.kruth.IntegerSubject that(Integer? actual);
     method public <T> androidx.kruth.IterableSubject<T> that(Iterable<? extends T>? actual);
     method public androidx.kruth.StringSubject that(String? actual);
     method public <K, V> androidx.kruth.MapSubject<K,V> that(java.util.Map<K,? extends V>? actual);
+    method public androidx.kruth.PrimitiveLongArraySubject that(long[]? actual);
+    method public androidx.kruth.PrimitiveShortArraySubject that(short[]? actual);
     method public <T> androidx.kruth.Subject<T> that(T actual);
     method public <T extends java.lang.Comparable<? super T>> androidx.kruth.ComparableSubject<T> that(T? actual);
     method public <T extends java.lang.Throwable> androidx.kruth.ThrowableSubject<T> that(T? actual);
+    method public <T> androidx.kruth.ObjectArraySubject<T> that(T![]? actual);
     method public androidx.kruth.StandardSubjectBuilder withMessage(String messageToPrepend);
     field public static final androidx.kruth.StandardSubjectBuilder.Companion Companion;
   }
 
   public static final class StandardSubjectBuilder.Companion {
-    method public androidx.kruth.StandardSubjectBuilder? forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
+    method public androidx.kruth.StandardSubjectBuilder forCustomFailureStrategy(androidx.kruth.FailureStrategy failureStrategy);
   }
 
   public final class StringSubject extends androidx.kruth.ComparableSubject<java.lang.String> {
diff --git a/kruth/kruth/build.gradle b/kruth/kruth/build.gradle
index 1726625..5025ed1 100644
--- a/kruth/kruth/build.gradle
+++ b/kruth/kruth/build.gradle
@@ -72,6 +72,10 @@
             nativeMain {
                 dependsOn(commonMain)
             }
+
+            nativeTest {
+                dependsOn(commonTest)
+            }
         }
 
         targets.all { target ->
@@ -79,6 +83,9 @@
                 target.compilations["main"].defaultSourceSet {
                     dependsOn(nativeMain)
                 }
+                target.compilations["test"].defaultSourceSet {
+                    dependsOn(nativeTest)
+                }
             }
         }
 
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/HelperArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/HelperArraySubject.kt
new file mode 100644
index 0000000..029e460
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/HelperArraySubject.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.kruth
+
+internal class HelperArraySubject<out T>(
+    actual: T?,
+    private val size: (T) -> Int,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<T>(actual = actual, metadata = metadata) {
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        metadata.assertNotNull(actual) { "Expected array to be empty, but was null" }
+
+        if (size(actual) > 0) {
+            failWithActual(Fact.simpleFact("Expected to be empty"))
+        }
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        metadata.assertNotNull(actual) { "Expected array not to be empty, but was null" }
+
+        if (size(actual) == 0) {
+            failWithoutActual(Fact.simpleFact("Expected not to be empty"))
+        }
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        require(length >= 0) { "length (%d) must be >= 0" }
+
+        metadata.assertNotNull(actual) { "Expected length to be equal to $length, but was null" }
+
+        val actualSize = size(actual)
+        metadata.assertEquals(length, actualSize) {
+            "Expected length to be equal to $length, but was $actualSize"
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/Kruth.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/Kruth.kt
index 5454dfa..9e6da3f 100644
--- a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/Kruth.kt
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/Kruth.kt
@@ -51,9 +51,33 @@
 fun <T> assertThat(actual: Iterable<T>?): IterableSubject<T> =
     IterableSubject(actual)
 
+fun <T> assertThat(actual: Array<out T>?): ObjectArraySubject<T> =
+    ObjectArraySubject(actual)
+
+fun assertThat(actual: BooleanArray?): PrimitiveBooleanArraySubject =
+    PrimitiveBooleanArraySubject(actual)
+
+fun assertThat(actual: ShortArray?): PrimitiveShortArraySubject =
+    PrimitiveShortArraySubject(actual)
+
+fun assertThat(actual: IntArray?): PrimitiveIntArraySubject =
+    PrimitiveIntArraySubject(actual)
+
+fun assertThat(actual: LongArray?): PrimitiveLongArraySubject =
+    PrimitiveLongArraySubject(actual)
+
 fun assertThat(actual: ByteArray?): PrimitiveByteArraySubject =
     PrimitiveByteArraySubject(actual)
 
+fun assertThat(actual: CharArray?): PrimitiveCharArraySubject =
+    PrimitiveCharArraySubject(actual)
+
+fun assertThat(actual: FloatArray?): PrimitiveFloatArraySubject =
+    PrimitiveFloatArraySubject(actual)
+
+fun assertThat(actual: DoubleArray?): PrimitiveDoubleArraySubject =
+    PrimitiveDoubleArraySubject(actual)
+
 fun <K, V> assertThat(actual: Map<K, V>?): MapSubject<K, V> =
     MapSubject(actual)
 
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/ObjectArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/ObjectArraySubject.kt
new file mode 100644
index 0000000..fb4125a
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/ObjectArraySubject.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for object arrays.
+ */
+class ObjectArraySubject<T> internal constructor(
+    actual: Array<out T>?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<Array<out T>>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = Array<*>::size,
+            metadata = metadata,
+        )
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [ObjectArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<*> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.toList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveBooleanArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveBooleanArraySubject.kt
new file mode 100644
index 0000000..e260fb7
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveBooleanArraySubject.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Boolean] arrays.
+ */
+class PrimitiveBooleanArraySubject internal constructor(
+    actual: BooleanArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<BooleanArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = BooleanArray::size,
+            metadata = metadata,
+        )
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Boolean> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveByteArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveByteArraySubject.kt
index f9a044a..98ff764 100644
--- a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveByteArraySubject.kt
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveByteArraySubject.kt
@@ -16,29 +16,26 @@
 
 package androidx.kruth
 
-import androidx.kruth.Fact.Companion.simpleFact
-
 class PrimitiveByteArraySubject internal constructor(
     actual: ByteArray?,
     metadata: FailureMetadata = FailureMetadata(),
 ) : Subject<ByteArray?>(actual = actual, metadata = metadata) {
 
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = ByteArray::size,
+            metadata = metadata,
+        )
+
     /** Fails if the array is not empty (i.e. `array.size > 0`). */
     fun isEmpty() {
-        metadata.assertNotNull(actual) { "Expected array to be empty, but was null" }
-
-        if (actual.isNotEmpty()) {
-            failWithActual(simpleFact("Expected to be empty"))
-        }
+        helper.isEmpty()
     }
 
     /** Fails if the array is empty (i.e. `array.size == 0`). */
     fun isNotEmpty() {
-        metadata.assertNotNull(actual) { "Expected array not to be empty, but was null" }
-
-        if (actual.isEmpty()) {
-            failWithoutActual(simpleFact("Expected not to be empty"))
-        }
+        helper.isNotEmpty()
     }
 
     /**
@@ -47,19 +44,13 @@
      * @throws IllegalArgumentException if [length] < 0
      */
     fun hasLength(length: Int) {
-        require(length >= 0) { "length (%d) must be >= 0" }
-
-        metadata.assertNotNull(actual) { "Expected length to be equal to $length, but was null" }
-
-        metadata.assertEquals(length, actual.size) {
-            "Expected length to be equal to $length, but was ${actual.size}"
-        }
+        helper.hasLength(length)
     }
 
     /** Converts this [PrimitiveByteArraySubject] to [IterableSubject].*/
     fun asList(): IterableSubject<Byte> {
         metadata.assertNotNull(actual)
 
-        return IterableSubject(actual = actual.toList(), metadata = metadata)
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
     }
 }
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveCharArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveCharArraySubject.kt
new file mode 100644
index 0000000..d11c068
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveCharArraySubject.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Char] arrays.
+ */
+class PrimitiveCharArraySubject internal constructor(
+    actual: CharArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<CharArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = CharArray::size,
+            metadata = metadata,
+        )
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Char> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveDoubleArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveDoubleArraySubject.kt
new file mode 100644
index 0000000..8ffcce7
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveDoubleArraySubject.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Char] arrays.
+ */
+class PrimitiveDoubleArraySubject internal constructor(
+    actual: DoubleArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<DoubleArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = DoubleArray::size,
+            metadata = metadata,
+        )
+
+    /**
+     * A check that the actual array and [expected] are arrays of the same length and type,
+     * containing elements such that each element in [expected] is equal to each element in the
+     * actual array, and in the same position, with element equality defined the same way that
+     * [Double.equals] define it (which is different to the way that the `==` operator on primitive
+     * [Double] defines it). This method is *not* recommended when the code under test is doing any
+     * kind of arithmetic: use `usingTolerance` with a suitable tolerance in that case, e.g.
+     * `assertThat(actualArray).usingTolerance(1.0e-10).containsExactly(expectedArray).inOrder()`.
+     * (Remember that the exact result of floating point arithmetic is sensitive to apparently
+     * trivial changes such as replacing `(a + b) + c` with `a + (b + c)`, and that unless
+     * `strictfp` is in force even the result of `(a + b) + c` is sensitive to the JVM's choice of
+     * precision for the intermediate result.) This method is recommended when the code under test
+     * is specified as either copying values without modification from its input or returning
+     * well-defined literal or constant values.
+     *
+     * - It considers [Double.POSITIVE_INFINITY], [Double.NEGATIVE_INFINITY], and
+     * [Double.NaN] to be equal to themselves (contrast with `usingTolerance(0.0)` which does not).
+     * - It does *not* consider `-0.0` to be equal to `0.0` (contrast with `usingTolerance(0.0)`
+     * which does).
+     */
+    @Suppress("RedundantOverride") // Documented
+    override fun isEqualTo(expected: Any?) {
+        super.isEqualTo(expected)
+    }
+
+    /**
+     * A check that the actual array and [unexpected] are not arrays of the same length and type,
+     * containing elements such that each element in [unexpected] is equal to each element in the
+     * actual array, and in the same position, with element equality defined the same way that
+     * [Double.equals] define it (which is different to the way that the `==` operator on primitive
+     * [Double] defines it). See [isEqualTo] for advice on when exact equality is recommended.
+     *
+     * - It considers [Double.POSITIVE_INFINITY], [Double.NEGATIVE_INFINITY], and [Double.NaN] to be
+     * equal to themselves.
+     * - It does *not* consider `-0.0` to be equal to `0.0`.
+     */
+    @Suppress("RedundantOverride") // Documented
+    override fun isNotEqualTo(unexpected: Any?) {
+        super.isNotEqualTo(unexpected)
+    }
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Double> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveFloatArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveFloatArraySubject.kt
new file mode 100644
index 0000000..c2b7deaa
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveFloatArraySubject.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Char] arrays.
+ */
+class PrimitiveFloatArraySubject internal constructor(
+    actual: FloatArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<FloatArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = FloatArray::size,
+            metadata = metadata,
+        )
+
+    /**
+     * A check that the actual array and [expected] are arrays of the same length and type,
+     * containing elements such that each element in [expected] is equal to each element in the
+     * actual array, and in the same position, with element equality defined the same way that
+     * [Float.equals] define it (which is different to the way that the `==` operator on primitive
+     * [Float] defines it). This method is *not* recommended when the code under test is doing any
+     * kind of arithmetic: use `usingTolerance` with a suitable tolerance in that case, e.g.
+     * `assertThat(actualArray).usingTolerance(1.0e-10).containsExactly(expectedArray).inOrder()`.
+     * (Remember that the exact result of floating point arithmetic is sensitive to apparently
+     * trivial changes such as replacing `(a + b) + c` with `a + (b + c)`, and that unless
+     * `strictfp` is in force even the result of `(a + b) + c` is sensitive to the JVM's choice of
+     * precision for the intermediate result.) This method is recommended when the code under test
+     * is specified as either copying values without modification from its input or returning
+     * well-defined literal or constant values.
+     *
+     * - It considers [Float.POSITIVE_INFINITY], [Float.NEGATIVE_INFINITY], and
+     * [Float.NaN] to be equal to themselves (contrast with `usingTolerance(0.0)` which does not).
+     * - It does *not* consider `-0.0` to be equal to `0.0` (contrast with `usingTolerance(0.0)`
+     * which does).
+     */
+    @Suppress("RedundantOverride") // Documented
+    override fun isEqualTo(expected: Any?) {
+        super.isEqualTo(expected)
+    }
+
+    /**
+     * A check that the actual array and [unexpected] are not arrays of the same length and type,
+     * containing elements such that each element in [unexpected] is equal to each element in the
+     * actual array, and in the same position, with element equality defined the same way that
+     * [Float.equals] define it (which is different to the way that the `==` operator on primitive
+     * [Float] defines it). See [isEqualTo] for advice on when exact equality is recommended.
+     *
+     * - It considers [Float.POSITIVE_INFINITY], [Float.NEGATIVE_INFINITY], and [Float.NaN] to be
+     * equal to themselves.
+     * - It does *not* consider `-0.0` to be equal to `0.0`.
+     */
+    @Suppress("RedundantOverride") // Documented
+    override fun isNotEqualTo(unexpected: Any?) {
+        super.isNotEqualTo(unexpected)
+    }
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Float> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveIntArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveIntArraySubject.kt
new file mode 100644
index 0000000..b4b1a4f
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveIntArraySubject.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Char] arrays.
+ */
+class PrimitiveIntArraySubject internal constructor(
+    actual: IntArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<IntArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = IntArray::size,
+            metadata = metadata,
+        )
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Int> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveLongArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveLongArraySubject.kt
new file mode 100644
index 0000000..934506b
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveLongArraySubject.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Char] arrays.
+ */
+class PrimitiveLongArraySubject internal constructor(
+    actual: LongArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<LongArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = LongArray::size,
+            metadata = metadata,
+        )
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Long> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveShortArraySubject.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveShortArraySubject.kt
new file mode 100644
index 0000000..d0231d7
--- /dev/null
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/PrimitiveShortArraySubject.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.kruth
+
+/**
+ * A Subject for [Char] arrays.
+ */
+class PrimitiveShortArraySubject internal constructor(
+    actual: ShortArray?,
+    metadata: FailureMetadata = FailureMetadata(),
+) : Subject<ShortArray?>(actual = actual, metadata = metadata) {
+
+    private val helper =
+        HelperArraySubject(
+            actual = actual,
+            size = ShortArray::size,
+            metadata = metadata,
+        )
+
+    /** Fails if the array is not empty (i.e. `array.size > 0`). */
+    fun isEmpty() {
+        helper.isEmpty()
+    }
+
+    /** Fails if the array is empty (i.e. `array.size == 0`). */
+    fun isNotEmpty() {
+        helper.isNotEmpty()
+    }
+
+    /**
+     * Fails if the array does not have the given length.
+     *
+     * @throws IllegalArgumentException if [length] < 0
+     */
+    fun hasLength(length: Int) {
+        helper.hasLength(length)
+    }
+
+    /** Converts this [PrimitiveBooleanArraySubject] to [IterableSubject].*/
+    fun asList(): IterableSubject<Short> {
+        metadata.assertNotNull(actual)
+
+        return IterableSubject(actual = actual.asList(), metadata = metadata)
+    }
+}
diff --git a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/StandardSubjectBuilder.kt b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/StandardSubjectBuilder.kt
index fc5ebc5..fc9e951 100644
--- a/kruth/kruth/src/commonMain/kotlin/androidx/kruth/StandardSubjectBuilder.kt
+++ b/kruth/kruth/src/commonMain/kotlin/androidx/kruth/StandardSubjectBuilder.kt
@@ -33,7 +33,7 @@
          * Returns a new instance that invokes the given [FailureStrategy] when a check fails.
          */
         @JvmStatic
-        fun forCustomFailureStrategy(failureStrategy: FailureStrategy): StandardSubjectBuilder? {
+        fun forCustomFailureStrategy(failureStrategy: FailureStrategy): StandardSubjectBuilder {
             return StandardSubjectBuilder(FailureMetadata.forFailureStrategy(failureStrategy))
         }
     }
@@ -70,9 +70,33 @@
     fun <T> that(actual: Iterable<T>?): IterableSubject<T> =
         IterableSubject(actual = actual, metadata = metadata)
 
+    fun <T> that(actual: Array<out T>?): ObjectArraySubject<T> =
+        ObjectArraySubject(actual = actual, metadata = metadata)
+
+    fun that(actual: BooleanArray?): PrimitiveBooleanArraySubject =
+        PrimitiveBooleanArraySubject(actual = actual, metadata = metadata)
+
+    fun that(actual: ShortArray?): PrimitiveShortArraySubject =
+        PrimitiveShortArraySubject(actual = actual, metadata = metadata)
+
+    fun that(actual: IntArray?): PrimitiveIntArraySubject =
+        PrimitiveIntArraySubject(actual = actual, metadata = metadata)
+
+    fun that(actual: LongArray?): PrimitiveLongArraySubject =
+        PrimitiveLongArraySubject(actual = actual, metadata = metadata)
+
     fun that(actual: ByteArray?): PrimitiveByteArraySubject =
         PrimitiveByteArraySubject(actual = actual, metadata = metadata)
 
+    fun that(actual: CharArray?): PrimitiveCharArraySubject =
+        PrimitiveCharArraySubject(actual = actual, metadata = metadata)
+
+    fun that(actual: FloatArray?): PrimitiveFloatArraySubject =
+        PrimitiveFloatArraySubject(actual = actual, metadata = metadata)
+
+    fun that(actual: DoubleArray?): PrimitiveDoubleArraySubject =
+        PrimitiveDoubleArraySubject(actual = actual, metadata = metadata)
+
     fun <K, V> that(actual: Map<K, V>?): MapSubject<K, V> =
         MapSubject(actual = actual, metadata = metadata)
 
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/ObjectArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/ObjectArraySubjectTest.kt
new file mode 100644
index 0000000..4ece17a
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/ObjectArraySubjectTest.kt
@@ -0,0 +1,279 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+import kotlin.test.fail
+
+class ObjectArraySubjectTest {
+
+    @Test
+    fun isEqualTo() {
+        assertThat(arrayOf("A", 5L)).isEqualTo(arrayOf("A", 5L))
+    }
+
+    @Test
+    fun isEqualTo_same() {
+        val same = arrayOf("A", 5L)
+        assertThat(same).isEqualTo(same)
+    }
+
+    @Test
+    fun asList() {
+        assertThat(arrayOf("A", 5L)).asList().contains("A")
+    }
+
+    @Test
+    fun hasLength() {
+        assertThat(emptyArray<Any>()).hasLength(0)
+        assertThat(arrayOf("A", 5L)).hasLength(2)
+        assertThat(arrayOf<Array<Any>>()).hasLength(0)
+        assertThat(arrayOf<Array<Any>>(emptyArray())).hasLength(1)
+    }
+
+    @Test
+    fun hasLengthFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", 5L)).hasLength(1)
+        }
+    }
+
+    @Test
+    fun hasLengthMultiFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf<Array<Any>>(arrayOf("A"), arrayOf(5L))).hasLength(1)
+        }
+    }
+
+    @Test
+    fun hasLengthNegative() {
+        try {
+            assertThat(arrayOf(2, 5)).hasLength(-1)
+            fail("Should have failed")
+        } catch (expected: IllegalArgumentException) {
+            // no-op
+        }
+    }
+
+    @Test
+    fun isEmpty() {
+        assertThat(emptyArray<Any>()).isEmpty()
+        assertThat(arrayOf<Array<Any>>()).isEmpty()
+    }
+
+    @Test
+    fun isEmptyFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", 5L)).isEmpty()
+        }
+    }
+
+    @Test
+    fun isNotEmpty() {
+        assertThat(arrayOf("A", 5L)).isNotEmpty()
+        assertThat(arrayOf(arrayOf("A"), arrayOf(5L))).isNotEmpty()
+    }
+
+    @Test
+    fun isNotEmptyFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(emptyArray<Any>()).isNotEmpty()
+        }
+    }
+
+    @Test
+    fun isEqualTo_fail_unequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", 5L)).isEqualTo(arrayOf(5L, "A"))
+        }
+    }
+
+    @Test
+    fun isEqualTo_fail_unequalOrderingMultiDimensional_00() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(arrayOf("A"), arrayOf(5L)))
+                .isEqualTo(arrayOf(arrayOf(5L), arrayOf("A")))
+        }
+    }
+
+    @Test
+    fun isEqualTo_fail_unequalOrderingMultiDimensional_01() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(arrayOf("A", "B"), arrayOf(5L)))
+                .isEqualTo(arrayOf(arrayOf("A"), arrayOf(5L)))
+        }
+    }
+
+    @Test
+    fun isEqualTo_fail_unequalOrderingMultiDimensional_11() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(arrayOf("A"), arrayOf(5L)))
+                .isEqualTo(arrayOf(arrayOf("A"), arrayOf(5L, 6L)))
+        }
+    }
+
+    @Test
+    fun isEqualTo_fail_notAnArray() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", 5L)).isEqualTo(Any())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_sameLengths() {
+        assertThat(arrayOf("A", 5L)).isNotEqualTo(arrayOf("C", 5L))
+        assertThat(arrayOf(arrayOf("A"), arrayOf(5L)))
+            .isNotEqualTo(arrayOf(arrayOf("C"), arrayOf(5L)))
+    }
+
+    @Test
+    fun isNotEqualTo_differentLengths() {
+        assertThat(arrayOf("A", 5L)).isNotEqualTo(arrayOf("A", 5L, "c"))
+        assertThat(arrayOf(arrayOf("A"), arrayOf(5L)))
+            .isNotEqualTo(arrayOf(arrayOf("A", "c"), arrayOf(5L)))
+        assertThat(arrayOf(arrayOf("A"), arrayOf(5L)))
+            .isNotEqualTo(arrayOf(arrayOf("A"), arrayOf(5L), arrayOf("C")))
+    }
+
+    @Test
+    fun isNotEqualTo_differentTypes() {
+        assertThat(arrayOf("A", 5L)).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun isNotEqualTo_failEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", 5L)).isNotEqualTo(arrayOf("A", 5L))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_failEqualsMultiDimensional() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(arrayOf("A"), arrayOf(5L)))
+                .isNotEqualTo(arrayOf(arrayOf("A"), arrayOf(5L)))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_failSame() {
+        val same = arrayOf("A", 5L)
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_failSameMultiDimensional() {
+        val same = arrayOf(arrayOf("A"), arrayOf(5L))
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+
+    @Test
+    fun stringArrayIsEqualTo() {
+        assertThat(arrayOf("A", "B")).isEqualTo(arrayOf("A", "B"))
+        assertThat(arrayOf(arrayOf("A"), arrayOf("B")))
+            .isEqualTo(arrayOf(arrayOf("A"), arrayOf("B")))
+    }
+
+    @Test
+    fun stringArrayAsList() {
+        assertThat(arrayOf("A", "B")).asList().contains("A")
+    }
+
+    @Test
+    fun multiDimensionalStringArrayAsList() {
+        val ab = arrayOf("A", "B")
+        assertThat(arrayOf(ab, arrayOf("C"))).asList().contains(ab)
+    }
+
+    @Test
+    fun stringArrayIsEqualTo_fail_unequalLength() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", "B")).isEqualTo(arrayOf("B"))
+        }
+    }
+
+    @Test
+    fun stringArrayIsEqualTo_fail_unequalLengthMultiDimensional() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(arrayOf("A"), arrayOf("B")))
+                .isEqualTo(arrayOf(arrayOf("A")))
+        }
+    }
+
+    @Test
+    fun stringArrayIsEqualTo_fail_unequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf("A", "B")).isEqualTo(arrayOf("B", "A"))
+        }
+    }
+
+    @Test
+    fun stringArrayIsEqualTo_fail_unequalOrderingMultiDimensional() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(arrayOf("A"), arrayOf("B")))
+                .isEqualTo(arrayOf(arrayOf("B"), arrayOf("A")))
+        }
+    }
+
+    @Test
+    fun setArrayIsEqualTo_fail_unequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(setOf("A"), setOf("B")))
+                .isEqualTo(arrayOf(setOf("B"), setOf("A")))
+        }
+    }
+
+    @Test
+    fun primitiveMultiDimensionalArrayIsEqualTo() {
+        assertThat(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6)))
+            .isEqualTo(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6)))
+    }
+
+    @Test
+    fun primitiveMultiDimensionalArrayIsEqualTo_fail_unequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6)))
+                .isEqualTo(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6, 7)))
+        }
+    }
+
+    @Test
+    fun primitiveMultiDimensionalArrayIsNotEqualTo() {
+        assertThat(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6)))
+            .isNotEqualTo(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6, 7)))
+    }
+
+    @Test
+    fun primitiveMultiDimensionalArrayIsNotEqualTo_fail_equal() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6)))
+                .isNotEqualTo(arrayOf(intArrayOf(1, 2), intArrayOf(3), intArrayOf(4, 5, 6)))
+        }
+    }
+
+    @Test
+    fun boxedAndUnboxed() {
+        assertFailsWith<AssertionError> {
+            assertThat(arrayOf(intArrayOf(0))).isEqualTo(arrayOf(arrayOf(0)))
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveBooleanArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveBooleanArraySubjectTest.kt
new file mode 100644
index 0000000..4b23cc5
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveBooleanArraySubjectTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class PrimitiveBooleanArraySubjectTest {
+
+    @Test
+    fun isEqualTo() {
+        assertThat(booleanArrayOf(true, false, true)).isEqualTo(booleanArrayOf(true, false, true))
+    }
+
+    @Test
+    fun isEqualTo_Same() {
+        val same = booleanArrayOf(true, false, true)
+        assertThat(same).isEqualTo(same)
+    }
+
+    @Test
+    fun asList() {
+        assertThat(booleanArrayOf(true, true, false)).asList().containsAtLeast(true, false)
+    }
+
+    @Test
+    fun isEqualTo_Fail_UnequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(booleanArrayOf(true, false, true))
+                .isEqualTo(booleanArrayOf(false, true, true))
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_NotAnArray() {
+        assertFailsWith<AssertionError> {
+            assertThat(booleanArrayOf(true, false, true)).isEqualTo(Any())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_SameLengths() {
+        assertThat(booleanArrayOf(true, false)).isNotEqualTo(booleanArrayOf(true, true))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentLengths() {
+        assertThat(booleanArrayOf(true, false)).isNotEqualTo(booleanArrayOf(true, false, true))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentTypes() {
+        assertThat(booleanArrayOf(true, false)).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun isNotEqualTo_FailEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(booleanArrayOf(true, false)).isNotEqualTo(booleanArrayOf(true, false))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_FailSame() {
+        val same = booleanArrayOf(true, false)
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveCharArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveCharArraySubjectTest.kt
new file mode 100644
index 0000000..2ca29ff
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveCharArraySubjectTest.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class PrimitiveCharArraySubjectTest {
+
+    @Test
+    fun isEqualTo() {
+        assertThat(charArrayOf('a', 'q')).isEqualTo(charArrayOf('a', 'q'))
+    }
+
+    @Test
+    fun isEqualTo_Same() {
+        val same = charArrayOf('a', 'q')
+        assertThat(same).isEqualTo(same)
+    }
+
+    @Test
+    fun asList() {
+        assertThat(charArrayOf('a', 'q', 'z')).asList().containsAtLeast('a', 'z')
+    }
+
+    @Test
+    fun isEqualTo_Fail_UnequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(charArrayOf('a', 'q')).isEqualTo(charArrayOf('q', 'a'))
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_DifferentKindOfcharArrayOf() {
+        assertFailsWith<AssertionError> {
+            assertThat(charArrayOf('a', 'q')).isEqualTo(intArrayOf())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_SameLengths() {
+        assertThat(charArrayOf('a', 'q')).isNotEqualTo(charArrayOf('q', 'a'))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentLengths() {
+        assertThat(charArrayOf('a', 'q')).isNotEqualTo(charArrayOf('q', 'a', 'b'))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentTypes() {
+        assertThat(charArrayOf('a', 'q')).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun isNotEqualTo_FailEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(charArrayOf('a', 'q')).isNotEqualTo(charArrayOf('a', 'q'))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_FailSame() {
+        val same = charArrayOf('a', 'q')
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveDoubleArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveDoubleArraySubjectTest.kt
new file mode 100644
index 0000000..5199d0c
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveDoubleArraySubjectTest.kt
@@ -0,0 +1,167 @@
+/*
+ * 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.kruth
+
+import kotlin.Double.Companion.NEGATIVE_INFINITY
+import kotlin.Double.Companion.NaN
+import kotlin.Double.Companion.POSITIVE_INFINITY
+import kotlin.math.nextDown
+import kotlin.math.nextUp
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class PrimitiveDoubleArraySubjectTest {
+
+    @Test
+    fun testDoubleConstants_matchNextAfter() {
+        assertThat((2.0 + DEFAULT_TOLERANCE).nextDown()).isEqualTo(TOLERABLE_2)
+        assertThat((2.2 + DEFAULT_TOLERANCE).nextDown()).isEqualTo(TOLERABLE_2POINT2)
+        assertThat((2.2 + DEFAULT_TOLERANCE).nextUp()).isEqualTo(INTOLERABLE_2POINT2)
+        assertThat(2.2.nextUp()).isEqualTo(OVER_2POINT2)
+        assertThat((3.3 + DEFAULT_TOLERANCE).nextDown()).isEqualTo(TOLERABLE_3POINT3)
+        assertThat((3.3 + DEFAULT_TOLERANCE).nextUp()).isEqualTo(INTOLERABLE_3POINT3)
+        assertThat(Long.MIN_VALUE.toDouble().nextDown()).isEqualTo(UNDER_MIN_OF_LONG)
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Success() {
+        assertThat(doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY, 0.0, -0.0))
+            .isEqualTo(doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY, 0.0, -0.0))
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_NaN_Success() {
+        val actual = doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0, -0.0)
+        val expected = doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0, -0.0)
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_NotEqual() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(2.2)).isEqualTo(doubleArrayOf(OVER_2POINT2))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_DifferentOrder() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(2.2, 3.3)).isEqualTo(doubleArrayOf(3.3, 2.2))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_Longer() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(2.2, 3.3)).isEqualTo(doubleArrayOf(2.2, 3.3, 4.4))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_Shorter() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(2.2, 3.3)).isEqualTo(doubleArrayOf(2.2))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_PlusMinusZero() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(0.0)).isEqualTo(doubleArrayOf(-0.0))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_NotAndoubleArrayOf() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(2.2, 3.3, 4.4)).isEqualTo(Any())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_FailEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY))
+                .isNotEqualTo(doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_NaN_plusZero_FailEquals() {
+        val actual = doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0, -0.0)
+        val expected = doubleArrayOf(2.2, 5.4, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0, -0.0)
+        assertFailsWith<AssertionError> {
+            assertThat(actual).isNotEqualTo(expected)
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_NotEqual() {
+        assertThat(doubleArrayOf(2.2)).isNotEqualTo(doubleArrayOf(OVER_2POINT2))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_DifferentOrder() {
+        assertThat(doubleArrayOf(2.2, 3.3)).isNotEqualTo(doubleArrayOf(3.3, 2.2))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_Longer() {
+        assertThat(doubleArrayOf(2.2, 3.3)).isNotEqualTo(doubleArrayOf(2.2, 3.3, 4.4))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_Shorter() {
+        assertThat(doubleArrayOf(2.2, 3.3)).isNotEqualTo(doubleArrayOf(2.2))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_PlusMinusZero() {
+        assertThat(doubleArrayOf(0.0)).isNotEqualTo(doubleArrayOf(-0.0))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_NotAndoubleArrayOf() {
+        assertThat(doubleArrayOf(2.2, 3.3, 4.4)).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun smallDifferenceInLongRepresentation() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(-4.4501477170144023E-308))
+                .isEqualTo(doubleArrayOf(-4.450147717014402E-308))
+        }
+    }
+
+    @Test
+    fun noCommas() {
+        assertFailsWith<AssertionError> {
+            assertThat(doubleArrayOf(10000.0)).isEqualTo(doubleArrayOf(20000.0))
+        }
+    }
+
+    private companion object {
+        private const val DEFAULT_TOLERANCE = 0.000005
+        private const val OVER_2POINT2 = 2.2000000000000006
+        private const val TOLERABLE_2 = 2.0000049999999994
+        private const val TOLERABLE_2POINT2 = 2.2000049999999995
+        private const val INTOLERABLE_2POINT2 = 2.2000050000000004
+        private const val TOLERABLE_3POINT3 = 3.300004999999999
+        private const val INTOLERABLE_3POINT3 = 3.300005
+        private const val UNDER_MIN_OF_LONG = -9.223372036854778E18
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveFloatArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveFloatArraySubjectTest.kt
new file mode 100644
index 0000000..c2845b5
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveFloatArraySubjectTest.kt
@@ -0,0 +1,140 @@
+/*
+ * 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.kruth
+
+import kotlin.Float.Companion.NEGATIVE_INFINITY
+import kotlin.Float.Companion.NaN
+import kotlin.Float.Companion.POSITIVE_INFINITY
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class PrimitiveFloatArraySubjectTest {
+
+    @Test
+    fun testFloatConstants_matchNextAfter() {
+        assertThat(2.2F.nextUp()).isEqualTo(JUST_OVER_2POINT2)
+        assertThat(3.3f.nextUp()).isEqualTo(JUST_OVER_3POINT3)
+        assertThat((3.3f + DEFAULT_TOLERANCE).nextDown()).isEqualTo(TOLERABLE_3POINT3)
+        assertThat((3.3f + DEFAULT_TOLERANCE).nextUp()).isEqualTo(INTOLERABLE_3POINT3)
+        assertThat(Long.MIN_VALUE.toFloat().nextDown()).isEqualTo(UNDER_LONG_MIN)
+        assertThat((2.2f + DEFAULT_TOLERANCE).nextDown()).isEqualTo(TOLERABLE_2POINT2)
+        assertThat((2.2f + DEFAULT_TOLERANCE).nextUp()).isEqualTo(INTOLERABLE_2POINT2)
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Success() {
+        val actual =
+            floatArrayOf(2.2f, 5.4f, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0f, -0.0f)
+        val expected =
+            floatArrayOf(2.2f, 5.4f, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0f, -0.0f)
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_NotEqual() {
+        assertFailsWith<AssertionError> {
+            assertThat(floatArrayOf(2.2f)).isEqualTo(floatArrayOf(JUST_OVER_2POINT2))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_DifferentOrder() {
+        assertFailsWith<AssertionError> {
+            assertThat(floatArrayOf(2.2f, 3.3f)).isEqualTo(floatArrayOf(3.3f, 2.2f))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_Longer() {
+        assertFailsWith<AssertionError> {
+            assertThat(floatArrayOf(2.2f, 3.3f)).isEqualTo(floatArrayOf(2.2f, 3.3f, 4.4f))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_Shorter() {
+        assertFailsWith<AssertionError> {
+            assertThat(floatArrayOf(2.2f, 3.3f)).isEqualTo(floatArrayOf(2.2f))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_PlusMinusZero() {
+        assertFailsWith<AssertionError> {
+            assertThat(floatArrayOf(0.0f)).isEqualTo(floatArrayOf(-0.0f))
+        }
+    }
+
+    @Test
+    fun isEqualTo_WithoutToleranceParameter_Fail_NotAnfloatArrayOf() {
+        assertFailsWith<AssertionError> {
+            assertThat(floatArrayOf(2.2f, 3.3f, 4.4f)).isEqualTo(Any())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_FailEquals() {
+        val actual =
+            floatArrayOf(2.2f, 5.4f, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0f, -0.0f)
+        val expected =
+            floatArrayOf(2.2f, 5.4f, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, 0.0f, -0.0f)
+        assertFailsWith<AssertionError> {
+            assertThat(actual).isNotEqualTo(expected)
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_NotEqual() {
+        assertThat(floatArrayOf(2.2f)).isNotEqualTo(floatArrayOf(JUST_OVER_2POINT2))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_DifferentOrder() {
+        assertThat(floatArrayOf(2.2f, 3.3f)).isNotEqualTo(floatArrayOf(3.3f, 2.2f))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_Longer() {
+        assertThat(floatArrayOf(2.2f, 3.3f)).isNotEqualTo(floatArrayOf(2.2f, 3.3f, 4.4f))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_Shorter() {
+        assertThat(floatArrayOf(2.2f, 3.3f)).isNotEqualTo(floatArrayOf(2.2f))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_PlusMinusZero() {
+        assertThat(floatArrayOf(0.0f)).isNotEqualTo(floatArrayOf(-0.0f))
+    }
+
+    @Test
+    fun isNotEqualTo_WithoutToleranceParameter_Success_NotAnfloatArrayOf() {
+        assertThat(floatArrayOf(2.2f, 3.3f, 4.4f)).isNotEqualTo(Any())
+    }
+
+    private companion object {
+        private const val DEFAULT_TOLERANCE = 0.000005f
+        private const val JUST_OVER_2POINT2 = 2.2000003f
+        private const val JUST_OVER_3POINT3 = 3.3000002f
+        private const val TOLERABLE_3POINT3 = 3.3000047f
+        private const val INTOLERABLE_3POINT3 = 3.3000052f
+        private const val UNDER_LONG_MIN = -9.223373E18f
+        private const val TOLERABLE_2POINT2 = 2.2000048f
+        private const val INTOLERABLE_2POINT2 = 2.2000053f
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveIntArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveIntArraySubjectTest.kt
new file mode 100644
index 0000000..8a7b1a5
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveIntArraySubjectTest.kt
@@ -0,0 +1,131 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+import kotlin.test.fail
+
+class PrimitiveIntArraySubjectTest {
+
+    @Test
+    fun isEqualTo() {
+        assertThat(intArrayOf(2, 5)).isEqualTo(intArrayOf(2, 5))
+    }
+
+    @Test
+    fun isEqualTo_Same() {
+        val same = intArrayOf(2, 5)
+        assertThat(same).isEqualTo(same)
+    }
+
+    @Test
+    fun asList() {
+        assertThat(intArrayOf(5, 2, 9)).asList().containsAtLeast(2, 9)
+    }
+
+    @Test
+    fun hasLength() {
+        assertThat(intArrayOf()).hasLength(0)
+        assertThat(intArrayOf(2, 5)).hasLength(2)
+    }
+
+    @Test
+    fun hasLengthFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(intArrayOf(2, 5)).hasLength(1)
+        }
+    }
+
+    @Test
+    fun hasLengthNegative() {
+        try {
+            assertThat(intArrayOf(2, 5)).hasLength(-1)
+            fail("Should have failed.")
+        } catch (expected: IllegalArgumentException) {
+            // no-op
+        }
+    }
+
+    @Test
+    fun isEmpty() {
+        assertThat(intArrayOf()).isEmpty()
+    }
+
+    @Test
+    fun isEmptyFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(intArrayOf(2, 5)).isEmpty()
+        }
+    }
+
+    @Test
+    fun isNotEmpty() {
+        assertThat(intArrayOf(2, 5)).isNotEmpty()
+    }
+
+    @Test
+    fun isNotEmptyFail() {
+        assertFailsWith<AssertionError> {
+            assertThat(intArrayOf()).isNotEmpty()
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_UnequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(intArrayOf(2, 3)).isEqualTo(intArrayOf(3, 2))
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_NotAnintArrayOf() {
+        assertFailsWith<AssertionError> {
+            assertThat(intArrayOf(2, 3, 4)).isEqualTo(Any())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_SameLengths() {
+        assertThat(intArrayOf(2, 3)).isNotEqualTo(intArrayOf(3, 2))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentLengths() {
+        assertThat(intArrayOf(2, 3)).isNotEqualTo(intArrayOf(2, 3, 1))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentTypes() {
+        assertThat(intArrayOf(2, 3)).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun isNotEqualTo_FailEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(intArrayOf(2, 3)).isNotEqualTo(intArrayOf(2, 3))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_FailSame() {
+        val same = intArrayOf(2, 3)
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveLongArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveLongArraySubjectTest.kt
new file mode 100644
index 0000000..9f23b73
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveLongArraySubjectTest.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class PrimitiveLongArraySubjectTest {
+
+    @Test
+    fun isEqualTo() {
+        assertThat(longArrayOf(2, 5)).isEqualTo(longArrayOf(2, 5))
+    }
+
+    @Test
+    fun isEqualTo_Same() {
+        val same = longArrayOf(2, 5)
+        assertThat(same).isEqualTo(same)
+    }
+
+    @Test
+    fun asList() {
+        assertThat(longArrayOf(5, 2, 9)).asList().containsAtLeast(2L, 9L)
+    }
+
+    @Test
+    fun isEqualTo_Fail_UnequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(longArrayOf(2, 3)).isEqualTo(longArrayOf(3, 2))
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_NotAnlongArrayOf() {
+        assertFailsWith<AssertionError> {
+            assertThat(longArrayOf(2, 3, 4)).isEqualTo(intArrayOf())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_SameLengths() {
+        assertThat(longArrayOf(2, 3)).isNotEqualTo(longArrayOf(3, 2))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentLengths() {
+        assertThat(longArrayOf(2, 3)).isNotEqualTo(longArrayOf(2, 3, 1))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentTypes() {
+        assertThat(longArrayOf(2, 3)).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun isNotEqualTo_FailEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(longArrayOf(2, 3)).isNotEqualTo(longArrayOf(2, 3))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_FailSame() {
+        val same = longArrayOf(2, 3)
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveShortArraySubjectTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveShortArraySubjectTest.kt
new file mode 100644
index 0000000..4742fbc
--- /dev/null
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/PrimitiveShortArraySubjectTest.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class PrimitiveShortArraySubjectTest {
+
+    @Test
+    fun isEqualTo() {
+        assertThat(shortArrayOf(1, 0, 1)).isEqualTo(shortArrayOf(1, 0, 1))
+    }
+
+    @Test
+    fun isEqualTo_Same() {
+        val same = shortArrayOf(1, 0, 1)
+        assertThat(same).isEqualTo(same)
+    }
+
+    @Test
+    fun asList() {
+        assertThat(shortArrayOf(1, 1, 0)).asList().containsAtLeast(1.toShort(), 0.toShort())
+    }
+
+    @Test
+    fun asListWithoutCastingFails() {
+        assertFailsWith<AssertionError> {
+            assertThat(shortArrayOf(1, 1, 0)).asList().containsAtLeast(1, 0)
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_UnequalOrdering() {
+        assertFailsWith<AssertionError> {
+            assertThat(shortArrayOf(1, 0, 1)).isEqualTo(shortArrayOf(0, 1, 1))
+        }
+    }
+
+    @Test
+    fun isEqualTo_Fail_NotAnshortArrayOf() {
+        assertFailsWith<AssertionError> {
+            assertThat(shortArrayOf(1, 0, 1)).isEqualTo(Any())
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_SameLengths() {
+        assertThat(shortArrayOf(1, 0)).isNotEqualTo(shortArrayOf(1, 1))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentLengths() {
+        assertThat(shortArrayOf(1, 0)).isNotEqualTo(shortArrayOf(1, 0, 1))
+    }
+
+    @Test
+    fun isNotEqualTo_DifferentTypes() {
+        assertThat(shortArrayOf(1, 0)).isNotEqualTo(Any())
+    }
+
+    @Test
+    fun isNotEqualTo_FailEquals() {
+        assertFailsWith<AssertionError> {
+            assertThat(shortArrayOf(1, 0)).isNotEqualTo(shortArrayOf(1, 0))
+        }
+    }
+
+    @Test
+    fun isNotEqualTo_FailSame() {
+        val same = shortArrayOf(1, 0)
+        assertFailsWith<AssertionError> {
+            assertThat(same).isNotEqualTo(same)
+        }
+    }
+}
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/TestingUtils.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/TestingUtils.kt
index 4f9dfa1..dffae5e 100644
--- a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/TestingUtils.kt
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/TestingUtils.kt
@@ -27,3 +27,7 @@
         assertEquals(expected = message, actual = e.message)
     }
 }
+
+internal expect fun Float.nextUp(): Float
+
+internal expect fun Float.nextDown(): Float
diff --git a/kruth/kruth/src/jvmTest/kotlin/androidx/kruth/TestingUtils.jvm.kt b/kruth/kruth/src/jvmTest/kotlin/androidx/kruth/TestingUtils.jvm.kt
new file mode 100644
index 0000000..0903009
--- /dev/null
+++ b/kruth/kruth/src/jvmTest/kotlin/androidx/kruth/TestingUtils.jvm.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.kruth
+
+import kotlin.math.nextDown as kotlinNextDown
+import kotlin.math.nextUp as kotlinNextUp
+
+internal actual fun Float.nextUp(): Float =
+    kotlinNextUp()
+
+internal actual fun Float.nextDown(): Float =
+    kotlinNextDown()
diff --git a/kruth/kruth/src/nativeTest/kotlin/androidx/kruth/TestingUtils.jvm.kt b/kruth/kruth/src/nativeTest/kotlin/androidx/kruth/TestingUtils.jvm.kt
new file mode 100644
index 0000000..0903009
--- /dev/null
+++ b/kruth/kruth/src/nativeTest/kotlin/androidx/kruth/TestingUtils.jvm.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.kruth
+
+import kotlin.math.nextDown as kotlinNextDown
+import kotlin.math.nextUp as kotlinNextUp
+
+internal actual fun Float.nextUp(): Float =
+    kotlinNextUp()
+
+internal actual fun Float.nextDown(): Float =
+    kotlinNextDown()
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/CompositeDrawableTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/CompositeDrawableTest.java
index 1cbaa74..a4b38df 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/CompositeDrawableTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/CompositeDrawableTest.java
@@ -23,11 +23,9 @@
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
-import android.os.Build;
 
 import androidx.leanback.graphics.BoundsRule.ValueRule;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -161,7 +159,6 @@
     }
 
 
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     public void constantState() {
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/FitWidthBitmapDrawableTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/FitWidthBitmapDrawableTest.java
index 43cf638..6212404 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/FitWidthBitmapDrawableTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/graphics/FitWidthBitmapDrawableTest.java
@@ -24,11 +24,9 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.os.Build;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -69,7 +67,6 @@
     }
 
     @SmallTest
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     public void constantState() {
         FitWidthBitmapDrawable drawable = new FitWidthBitmapDrawable();
diff --git a/leanback/leanback/src/main/java/androidx/leanback/app/BackgroundManager.java b/leanback/leanback/src/main/java/androidx/leanback/app/BackgroundManager.java
index 9f58f44..3fc4c83 100644
--- a/leanback/leanback/src/main/java/androidx/leanback/app/BackgroundManager.java
+++ b/leanback/leanback/src/main/java/androidx/leanback/app/BackgroundManager.java
@@ -42,7 +42,6 @@
 import androidx.core.graphics.drawable.DrawableCompat;
 import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
 import androidx.leanback.R;
-import androidx.leanback.widget.BackgroundHelper;
 
 import java.lang.ref.WeakReference;
 
@@ -354,8 +353,7 @@
                 // For each child drawable, we multiple Wrapper's alpha and LayerDrawable's alpha
                 // temporarily using mSuspendInvalidation to suppress invalidate event.
                 if (mWrapper[i] != null && (d = mWrapper[i].getDrawable()) != null) {
-                    int alpha = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
-                            ? DrawableCompat.getAlpha(d) : FULL_ALPHA;
+                    int alpha = DrawableCompat.getAlpha(d);
                     final int savedAlpha = alpha;
                     int multiple = 0;
                     if (mAlpha < FULL_ALPHA) {
@@ -791,7 +789,10 @@
         mLayerDrawable = createTranslucentLayerDrawable(layerDrawable);
         mImageInWrapperIndex = mLayerDrawable.findWrapperIndexById(R.id.background_imagein);
         mImageOutWrapperIndex = mLayerDrawable.findWrapperIndexById(R.id.background_imageout);
-        BackgroundHelper.setBackgroundPreservingAlpha(mBgView, mLayerDrawable);
+        if (mBgView.getBackground() != null) {
+            ((Drawable) mLayerDrawable).setAlpha(mBgView.getBackground().getAlpha());
+        }
+        mBgView.setBackground(mLayerDrawable);
     }
 
     private void updateImmediate() {
diff --git a/leanback/leanback/src/main/java/androidx/leanback/transition/LeanbackTransitionHelper.java b/leanback/leanback/src/main/java/androidx/leanback/transition/LeanbackTransitionHelper.java
index f1389ba..5c5eda2 100644
--- a/leanback/leanback/src/main/java/androidx/leanback/transition/LeanbackTransitionHelper.java
+++ b/leanback/leanback/src/main/java/androidx/leanback/transition/LeanbackTransitionHelper.java
@@ -30,7 +30,7 @@
 public class LeanbackTransitionHelper {
 
     public static Object loadTitleInTransition(Context context) {
-        if (Build.VERSION.SDK_INT < 19 || Build.VERSION.SDK_INT >= 21) {
+        if (Build.VERSION.SDK_INT >= 21) {
             return TransitionHelper.loadTransition(context, R.transition.lb_title_in);
         }
 
@@ -43,7 +43,7 @@
     }
 
     public static Object loadTitleOutTransition(Context context) {
-        if (Build.VERSION.SDK_INT < 19 || Build.VERSION.SDK_INT >= 21) {
+        if (Build.VERSION.SDK_INT >= 21) {
             return TransitionHelper.loadTransition(context, R.transition.lb_title_out);
         }
 
diff --git a/leanback/leanback/src/main/java/androidx/leanback/transition/TransitionHelper.java b/leanback/leanback/src/main/java/androidx/leanback/transition/TransitionHelper.java
index c117aa5..7e2f8e4c 100644
--- a/leanback/leanback/src/main/java/androidx/leanback/transition/TransitionHelper.java
+++ b/leanback/leanback/src/main/java/androidx/leanback/transition/TransitionHelper.java
@@ -39,8 +39,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 
-import java.util.ArrayList;
-
 /**
  * Helper for view transitions.
  */
@@ -59,8 +57,6 @@
     }
 
     private static class TransitionStub {
-        ArrayList<TransitionListener> mTransitionListeners;
-
         TransitionStub() {
         }
     }
@@ -174,23 +170,17 @@
     @SuppressLint("ClassVerificationFailure")
     @Nullable
     public static Object createScene(@NonNull ViewGroup sceneRoot, @Nullable Runnable r) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Scene scene = new Scene(sceneRoot);
-            scene.setEnterAction(r);
-            return scene;
-        }
-        return r;
+        Scene scene = new Scene(sceneRoot);
+        scene.setEnterAction(r);
+        return scene;
     }
 
     @SuppressLint("ClassVerificationFailure")
     @NonNull
     public static Object createChangeBounds(boolean reparent) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            CustomChangeBounds changeBounds = new CustomChangeBounds();
-            changeBounds.setReparent(reparent);
-            return changeBounds;
-        }
-        return new TransitionStub();
+        CustomChangeBounds changeBounds = new CustomChangeBounds();
+        changeBounds.setReparent(reparent);
+        return changeBounds;
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -208,9 +198,7 @@
             @NonNull View view,
             int startDelay
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((CustomChangeBounds) changeBounds).setStartDelay(view, startDelay);
-        }
+        ((CustomChangeBounds) changeBounds).setStartDelay(view, startDelay);
     }
 
     public static void setChangeBoundsStartDelay(
@@ -218,9 +206,7 @@
             int viewId,
             int startDelay
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((CustomChangeBounds) changeBounds).setStartDelay(viewId, startDelay);
-        }
+        ((CustomChangeBounds) changeBounds).setStartDelay(viewId, startDelay);
     }
 
     public static void setChangeBoundsStartDelay(
@@ -228,40 +214,30 @@
             @NonNull String className,
             int startDelay
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((CustomChangeBounds) changeBounds).setStartDelay(className, startDelay);
-        }
+        ((CustomChangeBounds) changeBounds).setStartDelay(className, startDelay);
     }
 
     public static void setChangeBoundsDefaultStartDelay(
             @NonNull Object changeBounds,
             int startDelay
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((CustomChangeBounds) changeBounds).setDefaultStartDelay(startDelay);
-        }
+        ((CustomChangeBounds) changeBounds).setDefaultStartDelay(startDelay);
     }
 
     @SuppressLint("ClassVerificationFailure")
     @NonNull
     public static Object createTransitionSet(boolean sequential) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            TransitionSet set = new TransitionSet();
-            set.setOrdering(sequential ? TransitionSet.ORDERING_SEQUENTIAL
-                    : TransitionSet.ORDERING_TOGETHER);
-            return set;
-        }
-        return new TransitionStub();
+        TransitionSet set = new TransitionSet();
+        set.setOrdering(sequential ? TransitionSet.ORDERING_SEQUENTIAL
+                : TransitionSet.ORDERING_TOGETHER);
+        return set;
     }
 
     @NonNull
     public static Object createSlide(int slideEdge) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            SlideKitkat slide = new SlideKitkat();
-            slide.setSlideEdge(slideEdge);
-            return slide;
-        }
-        return new TransitionStub();
+        SlideKitkat slide = new SlideKitkat();
+        slide.setSlideEdge(slideEdge);
+        return slide;
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -270,24 +246,17 @@
         if (Build.VERSION.SDK_INT >= 21) {
             return new ChangeTransform();
         }
-        if (Build.VERSION.SDK_INT >= 19) {
-            return new Scale();
-        }
-        return new TransitionStub();
+        return new Scale();
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void addTransition(@NonNull Object transitionSet, @NonNull Object transition) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((TransitionSet) transitionSet).addTransition((Transition) transition);
-        }
+        ((TransitionSet) transitionSet).addTransition((Transition) transition);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void exclude(@NonNull Object transition, int targetId, boolean exclude) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).excludeTarget(targetId, exclude);
-        }
+        ((Transition) transition).excludeTarget(targetId, exclude);
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -296,16 +265,12 @@
             @NonNull View targetView,
             boolean exclude
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).excludeTarget(targetView, exclude);
-        }
+        ((Transition) transition).excludeTarget(targetView, exclude);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void excludeChildren(@NonNull Object transition, int targetId, boolean exclude) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).excludeChildren(targetId, exclude);
-        }
+        ((Transition) transition).excludeChildren(targetId, exclude);
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -314,55 +279,39 @@
             @NonNull View targetView,
             boolean exclude
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).excludeChildren(targetView, exclude);
-        }
+        ((Transition) transition).excludeChildren(targetView, exclude);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void include(@NonNull Object transition, int targetId) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).addTarget(targetId);
-        }
+        ((Transition) transition).addTarget(targetId);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void include(@NonNull Object transition, @NonNull View targetView) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).addTarget(targetView);
-        }
+        ((Transition) transition).addTarget(targetView);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void setStartDelay(@NonNull Object transition, long startDelay) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).setStartDelay(startDelay);
-        }
+        ((Transition) transition).setStartDelay(startDelay);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void setDuration(@NonNull Object transition, long duration) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).setDuration(duration);
-        }
+        ((Transition) transition).setDuration(duration);
     }
 
     @SuppressLint("ClassVerificationFailure")
     @NonNull
     public static Object createAutoTransition() {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return new AutoTransition();
-        }
-        return new TransitionStub();
+        return new AutoTransition();
     }
 
     @SuppressLint("ClassVerificationFailure")
     @NonNull
     public static Object createFadeTransition(int fadeMode) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return new Fade(fadeMode);
-        }
-        return new TransitionStub();
+        return new Fade(fadeMode);
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -373,42 +322,34 @@
         if (listener == null) {
             return;
         }
-        if (Build.VERSION.SDK_INT >= 19) {
-            Transition t = (Transition) transition;
-            listener.mImpl = new Transition.TransitionListener() {
-                @Override
-                public void onTransitionStart(Transition transition11) {
-                    listener.onTransitionStart(transition11);
-                }
-
-                @Override
-                public void onTransitionResume(Transition transition11) {
-                    listener.onTransitionResume(transition11);
-                }
-
-                @Override
-                public void onTransitionPause(Transition transition11) {
-                    listener.onTransitionPause(transition11);
-                }
-
-                @Override
-                public void onTransitionEnd(Transition transition11) {
-                    listener.onTransitionEnd(transition11);
-                }
-
-                @Override
-                public void onTransitionCancel(Transition transition11) {
-                    listener.onTransitionCancel(transition11);
-                }
-            };
-            t.addListener((Transition.TransitionListener) listener.mImpl);
-        } else {
-            TransitionStub stub = (TransitionStub) transition;
-            if (stub.mTransitionListeners == null) {
-                stub.mTransitionListeners = new ArrayList<>();
+        Transition t = (Transition) transition;
+        listener.mImpl = new Transition.TransitionListener() {
+            @Override
+            public void onTransitionStart(Transition transition11) {
+                listener.onTransitionStart(transition11);
             }
-            stub.mTransitionListeners.add(listener);
-        }
+
+            @Override
+            public void onTransitionResume(Transition transition11) {
+                listener.onTransitionResume(transition11);
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition11) {
+                listener.onTransitionPause(transition11);
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition11) {
+                listener.onTransitionEnd(transition11);
+            }
+
+            @Override
+            public void onTransitionCancel(Transition transition11) {
+                listener.onTransitionCancel(transition11);
+            }
+        };
+        t.addListener((Transition.TransitionListener) listener.mImpl);
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -416,42 +357,17 @@
             @NonNull Object transition,
             @Nullable TransitionListener listener
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            if (listener == null || listener.mImpl == null) {
-                return;
-            }
-            Transition t = (Transition) transition;
-            t.removeListener((Transition.TransitionListener) listener.mImpl);
-            listener.mImpl = null;
-        } else {
-            TransitionStub stub = (TransitionStub) transition;
-            if (stub.mTransitionListeners != null) {
-                stub.mTransitionListeners.remove(listener);
-            }
+        if (listener == null || listener.mImpl == null) {
+            return;
         }
+        Transition t = (Transition) transition;
+        t.removeListener((Transition.TransitionListener) listener.mImpl);
+        listener.mImpl = null;
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void runTransition(@Nullable Object scene, @Nullable Object transition) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            TransitionManager.go((Scene) scene, (Transition) transition);
-        } else {
-            TransitionStub transitionStub = (TransitionStub) transition;
-            if (transitionStub != null && transitionStub.mTransitionListeners != null) {
-                for (int i = 0, size = transitionStub.mTransitionListeners.size(); i < size; i++) {
-                    transitionStub.mTransitionListeners.get(i).onTransitionStart(transition);
-                }
-            }
-            Runnable r = ((Runnable) scene);
-            if (r != null) {
-                r.run();
-            }
-            if (transitionStub != null && transitionStub.mTransitionListeners != null) {
-                for (int i = 0, size = transitionStub.mTransitionListeners.size(); i < size; i++) {
-                    transitionStub.mTransitionListeners.get(i).onTransitionEnd(transition);
-                }
-            }
-        }
+        TransitionManager.go((Scene) scene, (Transition) transition);
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -459,16 +375,12 @@
             @NonNull Object transition,
             @Nullable Object timeInterpolator
     ) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).setInterpolator((TimeInterpolator) timeInterpolator);
-        }
+        ((Transition) transition).setInterpolator((TimeInterpolator) timeInterpolator);
     }
 
     @SuppressLint("ClassVerificationFailure")
     public static void addTarget(@NonNull Object transition, @NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            ((Transition) transition).addTarget(view);
-        }
+        ((Transition) transition).addTarget(view);
     }
 
     @SuppressLint("ClassVerificationFailure")
@@ -484,10 +396,7 @@
     @SuppressLint("ClassVerificationFailure")
     @NonNull
     public static Object loadTransition(@NonNull Context context, int resId) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return TransitionInflater.from(context).inflateTransition(resId);
-        }
-        return new TransitionStub();
+        return TransitionInflater.from(context).inflateTransition(resId);
     }
 
     @SuppressLint({"ReferencesDeprecated", "ClassVerificationFailure"})
diff --git a/leanback/leanback/src/main/java/androidx/leanback/widget/BackgroundHelper.java b/leanback/leanback/src/main/java/androidx/leanback/widget/BackgroundHelper.java
index 69fa9dc..c3df78f 100644
--- a/leanback/leanback/src/main/java/androidx/leanback/widget/BackgroundHelper.java
+++ b/leanback/leanback/src/main/java/androidx/leanback/widget/BackgroundHelper.java
@@ -18,7 +18,6 @@
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.view.View;
 
 import androidx.annotation.RestrictTo;
@@ -29,15 +28,10 @@
 @RestrictTo(LIBRARY_GROUP_PREFIX)
 public final class BackgroundHelper {
     public static void setBackgroundPreservingAlpha(View view, Drawable drawable) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            if (view.getBackground() != null) {
-                drawable.setAlpha(view.getBackground().getAlpha());
-            }
-            view.setBackground(drawable);
-        } else {
-            // Cannot query drawable alpha
-            view.setBackground(drawable);
+        if (view.getBackground() != null) {
+            drawable.setAlpha(view.getBackground().getAlpha());
         }
+        view.setBackground(drawable);
     }
 
     private BackgroundHelper() {
diff --git a/libraryversions.toml b/libraryversions.toml
index 9de34c8..872c259 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -1,7 +1,7 @@
 [versions]
 ACTIVITY = "1.9.0-alpha01"
 ANNOTATION = "1.8.0-alpha01"
-ANNOTATION_EXPERIMENTAL = "1.4.0-alpha01"
+ANNOTATION_EXPERIMENTAL = "1.4.0-beta01"
 APPACTIONS_BUILTINTYPES = "1.0.0-alpha01"
 APPACTIONS_INTERACTION = "1.0.0-alpha01"
 APPCOMPAT = "1.7.0-alpha04"
@@ -19,11 +19,11 @@
 CAMERA_TESTING = "1.0.0-alpha01"
 CARDVIEW = "1.1.0-alpha01"
 CAR_APP = "1.7.0-alpha01"
-COLLECTION = "1.4.0-beta01"
+COLLECTION = "1.4.0-beta02"
 COMPOSE = "1.7.0-alpha01"
-COMPOSE_COMPILER = "1.5.5"
-COMPOSE_MATERIAL3 = "1.2.0-alpha12"
-COMPOSE_MATERIAL3_ADAPTIVE = "1.0.0-alpha01"
+COMPOSE_COMPILER = "1.5.6"
+COMPOSE_MATERIAL3 = "1.2.0-beta01"
+COMPOSE_MATERIAL3_ADAPTIVE = "1.0.0-alpha02"
 COMPOSE_MATERIAL3_ADAPTIVE_NAVIGATION_SUITE = "1.0.0-alpha01"
 COMPOSE_MATERIAL3_COMMON = "1.0.0-alpha01"
 COMPOSE_RUNTIME_TRACING = "1.0.0-beta01"
@@ -67,7 +67,7 @@
 GLANCE_PREVIEW = "1.0.0-alpha06"
 GLANCE_TEMPLATE = "1.0.0-alpha06"
 GLANCE_WEAR_TILES = "1.0.0-alpha06"
-GRAPHICS_CORE = "1.0.0-alpha06"
+GRAPHICS_CORE = "1.0.0-beta01"
 GRAPHICS_FILTERS = "1.0.0-alpha01"
 GRAPHICS_PATH = "1.0.0-beta01"
 GRAPHICS_SHAPES = "1.0.0-alpha03"
@@ -94,7 +94,7 @@
 LIFECYCLE_EXTENSIONS = "2.2.0"
 LOADER = "1.2.0-alpha01"
 MEDIA = "1.7.0-rc01"
-MEDIA2 = "1.3.0-beta01"
+MEDIA2 = "1.3.0-rc01"
 MEDIAROUTER = "1.7.0-beta01"
 METRICS = "1.0.0-alpha05"
 NAVIGATION = "2.8.0-alpha01"
@@ -136,17 +136,17 @@
 SWIPEREFRESHLAYOUT = "1.2.0-alpha01"
 TESTEXT = "1.0.0-alpha02"
 TESTSCREENSHOT = "1.0.0-alpha01"
-TEST_UIAUTOMATOR = "2.3.0-alpha05"
+TEST_UIAUTOMATOR = "2.3.0-beta01"
 TEXT = "1.0.0-alpha01"
 TRACING = "1.3.0-alpha02"
-TRACING_PERFETTO = "1.0.0-beta03"
+TRACING_PERFETTO = "1.0.0"
 TRANSITION = "1.5.0-alpha05"
 TV = "1.0.0-alpha11"
 TVPROVIDER = "1.1.0-alpha02"
 VECTORDRAWABLE = "1.2.0-rc01"
 VECTORDRAWABLE_ANIMATED = "1.2.0-rc01"
 VECTORDRAWABLE_SEEKABLE = "1.0.0-rc01"
-VERSIONED_PARCELABLE = "1.2.0-beta01"
+VERSIONED_PARCELABLE = "1.2.0-rc01"
 VIEWPAGER = "1.1.0-alpha02"
 VIEWPAGER2 = "1.1.0-beta03"
 WEAR = "1.4.0-alpha01"
@@ -161,7 +161,7 @@
 WEAR_TILES = "1.3.0-alpha03"
 WEAR_TOOLING_PREVIEW = "1.0.0-rc01"
 WEAR_WATCHFACE = "1.3.0-alpha01"
-WEBKIT = "1.10.0-alpha01"
+WEBKIT = "1.10.0-beta01"
 # Adding a comment to prevent merge conflicts for Window artifact
 WINDOW = "1.3.0-alpha01"
 WINDOW_EXTENSIONS = "1.3.0-alpha01"
diff --git a/media/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java b/media/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java
index afb4f31..8c3a9c8 100644
--- a/media/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java
+++ b/media/media/src/main/java/android/support/v4/media/MediaMetadataCompat.java
@@ -425,13 +425,9 @@
     public RatingCompat getRating(@RatingKey String key) {
         RatingCompat rating = null;
         try {
-            if (Build.VERSION.SDK_INT >= 19) {
-                // On platform version 19 or higher, mBundle stores a Rating object. Convert it to
-                // RatingCompat.
-                rating = RatingCompat.fromRating(mBundle.getParcelable(key));
-            } else {
-                rating = mBundle.getParcelable(key);
-            }
+            // On platform version 19 or higher, mBundle stores a Rating object. Convert it to
+            // RatingCompat.
+            rating = RatingCompat.fromRating(mBundle.getParcelable(key));
         } catch (Exception e) {
             // ignore, value was not a bitmap
             Log.w(TAG, "Failed to retrieve a key as Rating.", e);
@@ -819,13 +815,9 @@
                             + " key cannot be used to put a Rating");
                 }
             }
-            if (Build.VERSION.SDK_INT >= 19) {
-                // On platform version 19 or higher, use Rating instead of RatingCompat so mBundle
-                // can be unmarshalled.
-                mBundle.putParcelable(key, (Parcelable) value.getRating());
-            } else {
-                mBundle.putParcelable(key, value);
-            }
+            // On platform version 19 or higher, use Rating instead of RatingCompat so mBundle
+            // can be unmarshalled.
+            mBundle.putParcelable(key, (Parcelable) value.getRating());
             return this;
         }
 
diff --git a/media/media/src/main/java/android/support/v4/media/RatingCompat.java b/media/media/src/main/java/android/support/v4/media/RatingCompat.java
index 570577f..c49338e 100644
--- a/media/media/src/main/java/android/support/v4/media/RatingCompat.java
+++ b/media/media/src/main/java/android/support/v4/media/RatingCompat.java
@@ -21,14 +21,11 @@
 
 import android.annotation.SuppressLint;
 import android.media.Rating;
-import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.IntDef;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 
 import java.lang.annotation.Retention;
@@ -329,27 +326,28 @@
      * @param ratingObj A {@link android.media.Rating} object, or null if none.
      * @return An equivalent {@link RatingCompat} object, or null if none.
      */
+    @SuppressLint("WrongConstant")
     public static RatingCompat fromRating(Object ratingObj) {
-        if (ratingObj != null && Build.VERSION.SDK_INT >= 19) {
-            final int ratingStyle = Api19Impl.getRatingStyle((Rating) ratingObj);
+        if (ratingObj != null) {
+            final int ratingStyle = ((Rating) ratingObj).getRatingStyle();
             final RatingCompat rating;
-            if (Api19Impl.isRated((Rating) ratingObj)) {
+            if (((Rating) ratingObj).isRated()) {
                 switch (ratingStyle) {
                     case RATING_HEART:
-                        rating = newHeartRating(Api19Impl.hasHeart((Rating) ratingObj));
+                        rating = newHeartRating(((Rating) ratingObj).hasHeart());
                         break;
                     case RATING_THUMB_UP_DOWN:
-                        rating = newThumbRating(Api19Impl.isThumbUp((Rating) ratingObj));
+                        rating = newThumbRating(((Rating) ratingObj).isThumbUp());
                         break;
                     case RATING_3_STARS:
                     case RATING_4_STARS:
                     case RATING_5_STARS:
                         rating = newStarRating(ratingStyle,
-                                Api19Impl.getStarRating((Rating) ratingObj));
+                                ((Rating) ratingObj).getStarRating());
                         break;
                     case RATING_PERCENTAGE:
                         rating = newPercentageRating(
-                                Api19Impl.getPercentRating((Rating) ratingObj));
+                                ((Rating) ratingObj).getPercentRating());
                         break;
                     default:
                         return null;
@@ -373,91 +371,30 @@
      * @return An equivalent {@link android.media.Rating} object, or null if none.
      */
     public Object getRating() {
-        if (mRatingObj == null && Build.VERSION.SDK_INT >= 19) {
+        if (mRatingObj == null) {
             if (isRated()) {
                 switch (mRatingStyle) {
                     case RATING_HEART:
-                        mRatingObj = Api19Impl.newHeartRating(hasHeart());
+                        mRatingObj = Rating.newHeartRating(hasHeart());
                         break;
                     case RATING_THUMB_UP_DOWN:
-                        mRatingObj = Api19Impl.newThumbRating(isThumbUp());
+                        mRatingObj = Rating.newThumbRating(isThumbUp());
                         break;
                     case RATING_3_STARS:
                     case RATING_4_STARS:
                     case RATING_5_STARS:
-                        mRatingObj = Api19Impl.newStarRating(mRatingStyle,
-                                getStarRating());
+                        mRatingObj = Rating.newStarRating(mRatingStyle, getStarRating());
                         break;
                     case RATING_PERCENTAGE:
-                        mRatingObj = Api19Impl.newPercentageRating(getPercentRating());
+                        mRatingObj = Rating.newPercentageRating(getPercentRating());
                         break;
                     default:
                         return null;
                 }
             } else {
-                mRatingObj = Api19Impl.newUnratedRating(mRatingStyle);
+                mRatingObj = Rating.newUnratedRating(mRatingStyle);
             }
         }
         return mRatingObj;
     }
-
-    @RequiresApi(19)
-    private static class Api19Impl {
-        private Api19Impl() {}
-
-        @DoNotInline
-        static int getRatingStyle(Rating rating) {
-            return rating.getRatingStyle();
-        }
-
-        @DoNotInline
-        static boolean isRated(Rating rating) {
-            return rating.isRated();
-        }
-
-        @DoNotInline
-        static boolean hasHeart(Rating rating) {
-            return rating.hasHeart();
-        }
-
-        @DoNotInline
-        static boolean isThumbUp(Rating rating) {
-            return rating.isThumbUp();
-        }
-
-        @DoNotInline
-        static float getStarRating(Rating rating) {
-            return rating.getStarRating();
-        }
-
-        @DoNotInline
-        static float getPercentRating(Rating rating) {
-            return rating.getPercentRating();
-        }
-
-        @DoNotInline
-        static Rating newHeartRating(boolean hasHeart) {
-            return Rating.newHeartRating(hasHeart);
-        }
-
-        @DoNotInline
-        static Rating newThumbRating(boolean thumbIsUp) {
-            return Rating.newThumbRating(thumbIsUp);
-        }
-
-        @DoNotInline
-        static Rating newStarRating(int starRatingStyle, float starRating) {
-            return Rating.newStarRating(starRatingStyle, starRating);
-        }
-
-        @DoNotInline
-        static Rating newPercentageRating(float percent) {
-            return Rating.newPercentageRating(percent);
-        }
-
-        @DoNotInline
-        static Rating newUnratedRating(int ratingStyle) {
-            return Rating.newUnratedRating(ratingStyle);
-        }
-    }
 }
diff --git a/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java b/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
index a92d2198..cf9e20d 100644
--- a/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -553,15 +553,9 @@
                     ? Looper.myLooper() : Looper.getMainLooper());
             setCallback(new Callback() {}, handler);
             mImpl.setMediaButtonReceiver(mbrIntent);
-        } else if (android.os.Build.VERSION.SDK_INT >= 19) {
+        } else {
             mImpl = new MediaSessionImplApi19(context, tag, mbrComponent, mbrIntent,
                     session2Token, sessionInfo);
-        } else if (android.os.Build.VERSION.SDK_INT >= 18) {
-            mImpl = new MediaSessionImplApi18(context, tag, mbrComponent, mbrIntent,
-                    session2Token, sessionInfo);
-        } else {
-            mImpl = new MediaSessionImplBase(context, tag, mbrComponent, mbrIntent, session2Token,
-                    sessionInfo);
         }
         mController = new MediaControllerCompat(context, this);
 
@@ -3758,7 +3752,6 @@
         }
     }
 
-    @RequiresApi(18)
     static class MediaSessionImplApi18 extends MediaSessionImplBase {
         private static boolean sIsMbrPendingIntentSupported = true;
 
@@ -3844,7 +3837,6 @@
         }
     }
 
-    @RequiresApi(19)
     static class MediaSessionImplApi19 extends MediaSessionImplApi18 {
         MediaSessionImplApi19(Context context, String tag, ComponentName mbrComponent,
                 PendingIntent mbrIntent, VersionedParcelable session2Token, Bundle sessionInfo) {
diff --git a/media/media/src/main/java/androidx/media/AudioFocusRequestCompat.java b/media/media/src/main/java/androidx/media/AudioFocusRequestCompat.java
index d79fdc5..a126a53 100644
--- a/media/media/src/main/java/androidx/media/AudioFocusRequestCompat.java
+++ b/media/media/src/main/java/androidx/media/AudioFocusRequestCompat.java
@@ -263,10 +263,6 @@
                 throw new IllegalArgumentException("Illegal audio focus gain type " + focusGain);
             }
 
-            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT
-                    && focusGain == AudioManagerCompat.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
-                focusGain = AudioManagerCompat.AUDIOFOCUS_GAIN_TRANSIENT;
-            }
             mFocusGain = focusGain;
             return this;
         }
diff --git a/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java b/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java
index ecba28f..e24f55e 100644
--- a/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java
+++ b/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java
@@ -318,9 +318,7 @@
         Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
         intent.setComponent(mbrComponent);
         intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
-        if (Build.VERSION.SDK_INT >= 16) {
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        }
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         return PendingIntent.getBroadcast(context, keyCode, intent,
                 Build.VERSION.SDK_INT >= 31 ? PendingIntent.FLAG_MUTABLE : 0);
     }
diff --git a/media/version-compat-tests/lib/src/main/java/android/support/mediacompat/testlib/util/IntentUtil.java b/media/version-compat-tests/lib/src/main/java/android/support/mediacompat/testlib/util/IntentUtil.java
index 20bc0d5..221520a 100644
--- a/media/version-compat-tests/lib/src/main/java/android/support/mediacompat/testlib/util/IntentUtil.java
+++ b/media/version-compat-tests/lib/src/main/java/android/support/mediacompat/testlib/util/IntentUtil.java
@@ -19,7 +19,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcelable;
 
@@ -57,9 +56,7 @@
     public static void callMediaBrowserServiceMethod(int methodId, Object arg, Context context) {
         Intent intent = createIntent(SERVICE_RECEIVER_COMPONENT_NAME, methodId, arg);
         intent.setAction(ACTION_CALL_MEDIA_BROWSER_SERVICE_METHOD);
-        if (Build.VERSION.SDK_INT >= 16) {
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        }
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         context.sendBroadcast(intent);
     }
 
@@ -69,9 +66,7 @@
     public static void callMediaSessionMethod(int methodId, Object arg, Context context) {
         Intent intent = createIntent(SERVICE_RECEIVER_COMPONENT_NAME, methodId, arg);
         intent.setAction(ACTION_CALL_MEDIA_SESSION_METHOD);
-        if (Build.VERSION.SDK_INT >= 16) {
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        }
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         context.sendBroadcast(intent);
     }
 
@@ -83,9 +78,7 @@
         Intent intent = createIntent(CLIENT_RECEIVER_COMPONENT_NAME, methodId, arg);
         intent.setAction(ACTION_CALL_MEDIA_CONTROLLER_METHOD);
         intent.putExtra(KEY_SESSION_TOKEN, token);
-        if (Build.VERSION.SDK_INT >= 16) {
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        }
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         context.sendBroadcast(intent);
     }
 
@@ -97,9 +90,7 @@
         Intent intent = createIntent(CLIENT_RECEIVER_COMPONENT_NAME, methodId, arg);
         intent.setAction(ACTION_CALL_TRANSPORT_CONTROLS_METHOD);
         intent.putExtra(KEY_SESSION_TOKEN, token);
-        if (Build.VERSION.SDK_INT >= 16) {
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        }
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         context.sendBroadcast(intent);
     }
 
diff --git a/media2/media2-common/src/main/java/androidx/media2/common/ClassVerificationHelper.java b/media2/media2-common/src/main/java/androidx/media2/common/ClassVerificationHelper.java
index f6e962ee..5fc397b 100644
--- a/media2/media2-common/src/main/java/androidx/media2/common/ClassVerificationHelper.java
+++ b/media2/media2-common/src/main/java/androidx/media2/common/ClassVerificationHelper.java
@@ -51,25 +51,6 @@
         private AudioManager() {}
     }
 
-    /** Helper class for {@link android.os.HandlerThread}. */
-    public static final class HandlerThread {
-
-        /** Helper methods for {@link android.os.HandlerThread} APIs added in API level 18. */
-        @RequiresApi(18)
-        public static final class Api18 {
-
-            /** Helper method to call {@link android.os.HandlerThread#quitSafely()}. */
-            @DoNotInline
-            public static boolean quitSafely(@NonNull android.os.HandlerThread handlerThread) {
-                return handlerThread.quitSafely();
-            }
-
-            private Api18() {}
-        }
-
-        private HandlerThread() {}
-    }
-
     /** Helper class for {@link android.app.PendingIntent}. */
     public static final class PendingIntent {
 
diff --git a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
index c12fa6e..11585c6 100644
--- a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
+++ b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
@@ -1349,8 +1349,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MKV_H265_1280x720_500kbps_25fps_AAC_Stereo_128kbps_44100Hz()
             throws Exception {
         playVideoTest(
@@ -1359,8 +1358,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_500kbps_25fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1369,8 +1367,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_500kbps_30fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1379,8 +1376,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_1000kbps_25fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1389,8 +1385,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_1000kbps_30fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1399,8 +1394,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_1350kbps_25fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1409,8 +1403,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_1350kbps_30fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1419,8 +1412,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_1350kbps_30fps_AAC_Stereo_128kbps_44110Hz_frag()
             throws Exception {
         playVideoTest(
@@ -1430,8 +1422,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_MP4_H264_480x360_1350kbps_30fps_AAC_Stereo_192kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1440,8 +1431,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_12fps_AAC_Mono_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1450,8 +1440,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_12fps_AAC_Mono_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1460,8 +1449,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1470,8 +1458,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1480,8 +1467,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_128kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1490,8 +1476,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_12fps_AAC_Stereo_128kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1500,8 +1485,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_25fps_AAC_Mono_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1510,8 +1494,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_25fps_AAC_Mono_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1520,8 +1503,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1530,8 +1512,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1540,8 +1521,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_128kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1550,8 +1530,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_56kbps_25fps_AAC_Stereo_128kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1560,8 +1539,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_12fps_AAC_Mono_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1570,8 +1548,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_12fps_AAC_Mono_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1580,8 +1557,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1590,8 +1566,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1600,8 +1575,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_128kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1610,8 +1584,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_12fps_AAC_Stereo_128kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1620,8 +1593,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_25fps_AAC_Mono_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1630,8 +1602,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_25fps_AAC_Mono_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1640,8 +1611,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_24kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1650,8 +1620,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_24kbps_22050Hz()
             throws Exception {
         playVideoTest(
@@ -1660,8 +1629,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_128kbps_11025Hz()
             throws Exception {
         playVideoTest(
@@ -1670,8 +1638,7 @@
 
     @Test
     @LargeTest
-    @SdkSuppress(
-            minSdkVersion = Build.VERSION_CODES.KITKAT, maxSdkVersion = Build.VERSION_CODES.O_MR1)
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
     public void localVideo_3gp_H263_176x144_300kbps_25fps_AAC_Stereo_128kbps_22050Hz()
             throws Exception {
         playVideoTest(
diff --git a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java
index 20d1c73..6636bb4 100644
--- a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java
+++ b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer_AudioFocusTest.java
@@ -43,7 +43,6 @@
 import android.content.Intent;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
-import android.os.Build;
 import android.os.Build.VERSION;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -125,11 +124,7 @@
             if (sHandler == null) {
                 return;
             }
-            if (Build.VERSION.SDK_INT >= 18) {
-                sHandler.getLooper().quitSafely();
-            } else {
-                sHandler.getLooper().quit();
-            }
+            sHandler.getLooper().quitSafely();
             sHandler = null;
             sHandlerExecutor = null;
         }
diff --git a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaControllerTest.java b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaControllerTest.java
index 47e8b34..603f846 100644
--- a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaControllerTest.java
+++ b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaControllerTest.java
@@ -82,7 +82,7 @@
 // TODO(jaewan): Implement host-side test so controller and session can run in different processes.
 // TODO(jaewan): Fix flaky failure -- see MediaControllerImpl.getController()
 // TODO(jaeawn): Revisit create/close session in the sHandler. It's no longer necessary.
-@SdkSuppress(maxSdkVersion = 32, minSdkVersion = 19) // b/244312419 and b/259936005
+@SdkSuppress(maxSdkVersion = 32) // b/244312419 and b/259936005
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 @FlakyTest
diff --git a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaController_SurfaceTest.java b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaController_SurfaceTest.java
index 6c602f0..7fa8fc8 100644
--- a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaController_SurfaceTest.java
+++ b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaController_SurfaceTest.java
@@ -47,7 +47,7 @@
 /**
  * Tests {@link MediaController#setSurface(Surface)}.
  */
-@SdkSuppress(maxSdkVersion = 32, minSdkVersion = 19) // b/244312419 and b/259936005
+@SdkSuppress(maxSdkVersion = 32) // b/244312419 and b/259936005
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 public class MediaController_SurfaceTest extends MediaSessionTestBase {
diff --git a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTest.java b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTest.java
index d4ba3c3..fff5512 100644
--- a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTest.java
+++ b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTest.java
@@ -71,7 +71,7 @@
 /**
  * Tests {@link MediaSession}.
  */
-@SdkSuppress(maxSdkVersion = 32, minSdkVersion = 19) // b/244312419 and b/259936005
+@SdkSuppress(maxSdkVersion = 32) // b/244312419 and b/259936005
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 public class MediaSessionTest extends MediaSessionTestBase {
diff --git a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTestBase.java b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTestBase.java
index d39d457..2b482e0 100644
--- a/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTestBase.java
+++ b/media2/media2-session/src/androidTest/java/androidx/media2/session/MediaSessionTestBase.java
@@ -17,7 +17,6 @@
 package androidx.media2.session;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 
@@ -84,11 +83,7 @@
             if (sHandler == null) {
                 return;
             }
-            if (Build.VERSION.SDK_INT >= 18) {
-                sHandler.getLooper().quitSafely();
-            } else {
-                sHandler.getLooper().quit();
-            }
+            sHandler.getLooper().quitSafely();
             sHandler = null;
             sHandlerExecutor = null;
         }
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java b/media2/media2-session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java
index dc21534..9a4987c 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/MediaControllerImplLegacy.java
@@ -36,7 +36,6 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -56,7 +55,6 @@
 import androidx.annotation.Nullable;
 import androidx.concurrent.futures.ResolvableFuture;
 import androidx.core.util.ObjectsCompat;
-import androidx.media2.common.ClassVerificationHelper;
 import androidx.media2.common.MediaItem;
 import androidx.media2.common.MediaMetadata;
 import androidx.media2.common.Rating;
@@ -205,11 +203,7 @@
             }
             mHandler.removeCallbacksAndMessages(null);
 
-            if (Build.VERSION.SDK_INT >= 18) {
-                ClassVerificationHelper.HandlerThread.Api18.quitSafely(mHandlerThread);
-            } else {
-                mHandlerThread.quit();
-            }
+            mHandlerThread.quitSafely();
 
             mClosed = true;
 
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
index 52ae967..e4ea230 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
@@ -322,11 +322,7 @@
         });
         mHandler.removeCallbacksAndMessages(null);
         if (mHandlerThread.isAlive()) {
-            if (Build.VERSION.SDK_INT >= 18) {
-                ClassVerificationHelper.HandlerThread.Api18.quitSafely(mHandlerThread);
-            } else {
-                mHandlerThread.quit();
-            }
+            mHandlerThread.quitSafely();
         }
     }
 
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/MediaUtils.java b/media2/media2-session/src/main/java/androidx/media2/session/MediaUtils.java
index d726eb2..0aaec2b 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/MediaUtils.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/MediaUtils.java
@@ -48,7 +48,6 @@
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.BadParcelableException;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -334,8 +333,7 @@
                 builder.putBitmap(metadataKey, (Bitmap) value);
             } else if (value instanceof Long) {
                 builder.putLong(metadataKey, (Long) value);
-            } else if ((value instanceof RatingCompat)
-                    || (Build.VERSION.SDK_INT >= 19 && value instanceof android.media.Rating)) {
+            } else if (value instanceof RatingCompat || value instanceof android.media.Rating) {
                 // Must be fwk Rating or RatingCompat according to SDK versions.
                 // Use MediaMetadataCompat#getRating(key) to get a RatingCompat object.
                 try {
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/SessionToken.java b/media2/media2-session/src/main/java/androidx/media2/session/SessionToken.java
index b6c7f26..a0997be 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/SessionToken.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/SessionToken.java
@@ -23,7 +23,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -38,7 +37,6 @@
 import androidx.annotation.RestrictTo;
 import androidx.media.MediaBrowserServiceCompat;
 import androidx.media.MediaSessionManager;
-import androidx.media2.common.ClassVerificationHelper;
 import androidx.versionedparcelable.ParcelField;
 import androidx.versionedparcelable.VersionedParcelable;
 import androidx.versionedparcelable.VersionedParcelize;
@@ -345,11 +343,7 @@
 
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     static void quitHandlerThread(HandlerThread thread) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            ClassVerificationHelper.HandlerThread.Api18.quitSafely(thread);
-        } else {
-            thread.quit();
-        }
+        thread.quitSafely();
     }
 
     @SuppressWarnings("deprecation")
diff --git a/media2/media2-session/version-compat-tests/common/src/main/java/androidx/media2/test/common/TestUtils.java b/media2/media2-session/version-compat-tests/common/src/main/java/androidx/media2/test/common/TestUtils.java
index 51689e8..1fd6712 100644
--- a/media2/media2-session/version-compat-tests/common/src/main/java/androidx/media2/test/common/TestUtils.java
+++ b/media2/media2-session/version-compat-tests/common/src/main/java/androidx/media2/test/common/TestUtils.java
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -74,11 +73,7 @@
     // Copied code from ObjectsCompat.java due to build dependency problem of
     // previous version of support lib.
     public static boolean equals(Object a, Object b) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            return Objects.equals(a, b);
-        } else {
-            return (a == b) || (a != null && a.equals(b));
-        }
+        return Objects.equals(a, b);
     }
 
     /**
diff --git a/media2/media2-session/version-compat-tests/current/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java b/media2/media2-session/version-compat-tests/current/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java
index 639fb5b..ea17c74 100644
--- a/media2/media2-session/version-compat-tests/current/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java
+++ b/media2/media2-session/version-compat-tests/current/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java
@@ -17,7 +17,6 @@
 package androidx.media2.test.client.tests;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.support.v4.media.session.MediaSessionCompat;
@@ -88,11 +87,7 @@
             if (sHandler == null) {
                 return;
             }
-            if (Build.VERSION.SDK_INT >= 18) {
-                sHandler.getLooper().quitSafely();
-            } else {
-                sHandler.getLooper().quit();
-            }
+            sHandler.getLooper().quitSafely();
             sHandler = null;
             sHandlerExecutor = null;
         }
diff --git a/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java b/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java
index 78b5841..cb8b580 100644
--- a/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java
+++ b/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java
@@ -54,7 +54,6 @@
 
 import android.app.Service;
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.util.Log;
@@ -124,11 +123,7 @@
             sAssertLibraryParams = false;
             sExpectedParams = null;
         }
-        if (Build.VERSION.SDK_INT >= 18) {
-            mHandler.getLooper().quitSafely();
-        } else {
-            mHandler.getLooper().quit();
-        }
+        mHandler.getLooper().quitSafely();
         mHandler = null;
         TestServiceRegistry.getInstance().cleanUp();
     }
diff --git a/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java b/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java
index 6db0c22..40529f8 100644
--- a/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java
+++ b/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java
@@ -17,7 +17,6 @@
 package androidx.media2.test.service.tests;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 
@@ -79,11 +78,7 @@
             if (sHandler == null) {
                 return;
             }
-            if (Build.VERSION.SDK_INT >= 18) {
-                sHandler.getLooper().quitSafely();
-            } else {
-                sHandler.getLooper().quit();
-            }
+            sHandler.getLooper().quitSafely();
             sHandler = null;
             sHandlerExecutor = null;
         }
diff --git a/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java b/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
index 6104b39..c12f098 100644
--- a/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
+++ b/media2/media2-session/version-compat-tests/current/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
@@ -39,7 +39,6 @@
 import androidx.media2.test.service.R;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.After;
 import org.junit.Before;
@@ -54,7 +53,6 @@
  * In order to get the media key events, the player state is set to 'Playing' before every test
  * method.
  */
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT) // For AudioManager#dispatchMediaKeyEvent()
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 public class MediaSession_KeyEventTest extends MediaSessionTestBase {
diff --git a/media2/media2-session/version-compat-tests/previous/client/build.gradle b/media2/media2-session/version-compat-tests/previous/client/build.gradle
index 5ca0a2c..d16354e 100644
--- a/media2/media2-session/version-compat-tests/previous/client/build.gradle
+++ b/media2/media2-session/version-compat-tests/previous/client/build.gradle
@@ -20,7 +20,7 @@
 }
 
 dependencies {
-    androidTestImplementation("androidx.media2:media2-session:1.2.0-rc01")
+    androidTestImplementation("androidx.media2:media2-session:1.2.0")
     androidTestImplementation(project(":media2:media2-session:version-compat-tests:common"))
 
     androidTestImplementation(libs.testExtJunit)
diff --git a/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java b/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java
index 639fb5b..ea17c74 100644
--- a/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java
+++ b/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaSessionTestBase.java
@@ -17,7 +17,6 @@
 package androidx.media2.test.client.tests;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.support.v4.media.session.MediaSessionCompat;
@@ -88,11 +87,7 @@
             if (sHandler == null) {
                 return;
             }
-            if (Build.VERSION.SDK_INT >= 18) {
-                sHandler.getLooper().quitSafely();
-            } else {
-                sHandler.getLooper().quit();
-            }
+            sHandler.getLooper().quitSafely();
             sHandler = null;
             sHandlerExecutor = null;
         }
diff --git a/media2/media2-session/version-compat-tests/previous/service/build.gradle b/media2/media2-session/version-compat-tests/previous/service/build.gradle
index 0f6afc1..001262f 100644
--- a/media2/media2-session/version-compat-tests/previous/service/build.gradle
+++ b/media2/media2-session/version-compat-tests/previous/service/build.gradle
@@ -20,7 +20,7 @@
 }
 
 dependencies {
-    androidTestImplementation("androidx.media2:media2-session:1.2.0-rc01")
+    androidTestImplementation("androidx.media2:media2-session:1.2.0")
     androidTestImplementation(project(":media2:media2-session:version-compat-tests:common"))
 
     androidTestImplementation(libs.testExtJunit)
diff --git a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java
index 78b5841..cb8b580 100644
--- a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java
+++ b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/MockMediaLibraryService.java
@@ -54,7 +54,6 @@
 
 import android.app.Service;
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.util.Log;
@@ -124,11 +123,7 @@
             sAssertLibraryParams = false;
             sExpectedParams = null;
         }
-        if (Build.VERSION.SDK_INT >= 18) {
-            mHandler.getLooper().quitSafely();
-        } else {
-            mHandler.getLooper().quit();
-        }
+        mHandler.getLooper().quitSafely();
         mHandler = null;
         TestServiceRegistry.getInstance().cleanUp();
     }
diff --git a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java
index 6db0c22..40529f8 100644
--- a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java
+++ b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTestBase.java
@@ -17,7 +17,6 @@
 package androidx.media2.test.service.tests;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 
@@ -79,11 +78,7 @@
             if (sHandler == null) {
                 return;
             }
-            if (Build.VERSION.SDK_INT >= 18) {
-                sHandler.getLooper().quitSafely();
-            } else {
-                sHandler.getLooper().quit();
-            }
+            sHandler.getLooper().quitSafely();
             sHandler = null;
             sHandlerExecutor = null;
         }
diff --git a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
index 6104b39..c12f098 100644
--- a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
+++ b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSession_KeyEventTest.java
@@ -39,7 +39,6 @@
 import androidx.media2.test.service.R;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.After;
 import org.junit.Before;
@@ -54,7 +53,6 @@
  * In order to get the media key events, the player state is set to 'Playing' before every test
  * method.
  */
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT) // For AudioManager#dispatchMediaKeyEvent()
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 public class MediaSession_KeyEventTest extends MediaSessionTestBase {
diff --git a/media2/media2-widget/src/main/java/androidx/media2/widget/CaptioningManagerHelper.java b/media2/media2-widget/src/main/java/androidx/media2/widget/CaptioningManagerHelper.java
deleted file mode 100644
index d94b2ad..0000000
--- a/media2/media2-widget/src/main/java/androidx/media2/widget/CaptioningManagerHelper.java
+++ /dev/null
@@ -1,67 +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.
- */
-
-package androidx.media2.widget;
-
-import android.view.accessibility.CaptioningManager;
-
-import androidx.annotation.DoNotInline;
-import androidx.annotation.RequiresApi;
-
-import java.util.Locale;
-
-final class CaptioningManagerHelper {
-
-    @RequiresApi(19)
-    static final class Api19Impl {
-
-        @DoNotInline
-        static void addCaptioningChangeListener(CaptioningManager manager,
-                CaptioningManager.CaptioningChangeListener listener) {
-            manager.addCaptioningChangeListener(listener);
-        }
-
-        @DoNotInline
-        static void removeCaptioningChangeListener(CaptioningManager manager,
-                CaptioningManager.CaptioningChangeListener listener) {
-            manager.removeCaptioningChangeListener(listener);
-        }
-
-        @DoNotInline
-        static float getFontScale(CaptioningManager manager) {
-            return manager.getFontScale();
-        }
-
-        @DoNotInline
-        static Locale getLocale(CaptioningManager manager) {
-            return manager.getLocale();
-        }
-
-        @DoNotInline
-        static CaptioningManager.CaptionStyle getUserStyle(CaptioningManager manager) {
-            return manager.getUserStyle();
-        }
-
-        @DoNotInline
-        static boolean isEnabled(CaptioningManager manager) {
-            return manager.isEnabled();
-        }
-
-        private Api19Impl() {}
-    }
-
-    private CaptioningManagerHelper() {}
-}
diff --git a/media2/media2-widget/src/main/java/androidx/media2/widget/Cea708CaptionRenderer.java b/media2/media2-widget/src/main/java/androidx/media2/widget/Cea708CaptionRenderer.java
index e7d9609..25c513c 100644
--- a/media2/media2-widget/src/main/java/androidx/media2/widget/Cea708CaptionRenderer.java
+++ b/media2/media2-widget/src/main/java/androidx/media2/widget/Cea708CaptionRenderer.java
@@ -787,17 +787,13 @@
                 addView(mCCView, params);
 
                 // Set the system wide CC preferences to the subtitle view.
-                if (Build.VERSION.SDK_INT >= 19) {
-                    CaptioningManager captioningManager =
-                            (CaptioningManager) context.getSystemService(
-                                    Context.CAPTIONING_SERVICE);
-                    mFontScale = CaptioningManagerHelper.Api19Impl.getFontScale(captioningManager);
-                    setCaptionStyle(new CaptionStyle(
-                            CaptioningManagerHelper.Api19Impl.getUserStyle(captioningManager)));
-                } else {
-                    mFontScale = 1f;
-                    setCaptionStyle(CaptionStyle.DEFAULT);
-                }
+                CaptioningManager captioningManager =
+                        (CaptioningManager) context.getSystemService(
+                                Context.CAPTIONING_SERVICE);
+                mFontScale = captioningManager.getFontScale();
+                setCaptionStyle(new CaptionStyle(
+                        captioningManager.getUserStyle()));
+
                 mCCView.setText("");
                 updateWidestChar();
             }
diff --git a/media2/media2-widget/src/main/java/androidx/media2/widget/ClosedCaptionWidget.java b/media2/media2-widget/src/main/java/androidx/media2/widget/ClosedCaptionWidget.java
index 70d7711..66c8cc2 100644
--- a/media2/media2-widget/src/main/java/androidx/media2/widget/ClosedCaptionWidget.java
+++ b/media2/media2-widget/src/main/java/androidx/media2/widget/ClosedCaptionWidget.java
@@ -17,7 +17,6 @@
 package androidx.media2.widget;
 
 import android.content.Context;
-import android.os.Build.VERSION;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
@@ -69,27 +68,21 @@
         // Cannot render text over video when layer type is hardware.
         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
 
-        float fontScale = 1.f;
-        if (VERSION.SDK_INT >= 19) {
-            mCaptioningListener = new CaptioningChangeListener() {
-                @Override
-                public void onUserStyleChanged(CaptioningManager.CaptionStyle userStyle) {
-                    mCaptionStyle = new CaptionStyle(userStyle);
-                    mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
-                }
+        mCaptioningListener = new CaptioningChangeListener() {
+            @Override
+            public void onUserStyleChanged(CaptioningManager.CaptionStyle userStyle) {
+                mCaptionStyle = new CaptionStyle(userStyle);
+                mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+            }
 
-                @Override
-                public void onFontScaleChanged(float fontScale) {
-                    mClosedCaptionLayout.setFontScale(fontScale);
-                }
-            };
-            mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
-            mCaptionStyle = new CaptionStyle(
-                    CaptioningManagerHelper.Api19Impl.getUserStyle(mManager));
-            fontScale = CaptioningManagerHelper.Api19Impl.getFontScale(mManager);
-        } else {
-            mCaptionStyle = CaptionStyle.DEFAULT;
-        }
+            @Override
+            public void onFontScaleChanged(float fontScale) {
+                mClosedCaptionLayout.setFontScale(fontScale);
+            }
+        };
+        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptionStyle = new CaptionStyle(mManager.getUserStyle());
+        float fontScale = mManager.getFontScale();
 
         mClosedCaptionLayout = createCaptionLayout(context);
         mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
@@ -156,20 +149,15 @@
      * Manages whether this renderer is listening for caption style changes.
      */
     private void manageChangeListener() {
-        if (VERSION.SDK_INT < 19) {
-            return;
-        }
         final boolean needsListener =
                 ViewCompat.isAttachedToWindow(this) && getVisibility() == View.VISIBLE;
         if (mHasChangeListener != needsListener) {
             mHasChangeListener = needsListener;
 
             if (needsListener) {
-                CaptioningManagerHelper.Api19Impl.addCaptioningChangeListener(mManager,
-                        mCaptioningListener);
+                mManager.addCaptioningChangeListener(mCaptioningListener);
             } else {
-                CaptioningManagerHelper.Api19Impl.removeCaptioningChangeListener(mManager,
-                        mCaptioningListener);
+                mManager.removeCaptioningChangeListener(mCaptioningListener);
             }
         }
     }
diff --git a/media2/media2-widget/src/main/java/androidx/media2/widget/SubtitleController.java b/media2/media2-widget/src/main/java/androidx/media2/widget/SubtitleController.java
index d43ae78..4526353 100644
--- a/media2/media2-widget/src/main/java/androidx/media2/widget/SubtitleController.java
+++ b/media2/media2-widget/src/main/java/androidx/media2/widget/SubtitleController.java
@@ -20,7 +20,6 @@
 import android.media.MediaFormat;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.TrackInfo;
-import android.os.Build.VERSION;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -100,30 +99,24 @@
 
         mRenderers = new ArrayList<Renderer>();
         mTracks = new ArrayList<SubtitleTrack>();
-        if (VERSION.SDK_INT >= 19) {
-            mCaptioningManager =
-                    (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
-            mCaptioningChangeListener =
-                new CaptioningManager.CaptioningChangeListener() {
-                    @Override
-                    public void onEnabledChanged(boolean enabled) {
-                        selectDefaultTrack();
-                    }
+        mCaptioningManager =
+                (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptioningChangeListener = new CaptioningManager.CaptioningChangeListener() {
+                @Override
+                public void onEnabledChanged(boolean enabled) {
+                    selectDefaultTrack();
+                }
 
-                    @Override
-                    public void onLocaleChanged(Locale locale) {
-                        selectDefaultTrack();
-                    }
-            };
-        }
+                @Override
+                public void onLocaleChanged(Locale locale) {
+                    selectDefaultTrack();
+                }
+        };
     }
 
     @Override
     protected void finalize() throws Throwable {
-        if (VERSION.SDK_INT >= 19) {
-            CaptioningManagerHelper.Api19Impl.removeCaptioningChangeListener(mCaptioningManager,
-                    mCaptioningChangeListener);
-        }
+        mCaptioningManager.removeCaptioningChangeListener(mCaptioningChangeListener);
         super.finalize();
     }
 
@@ -228,14 +221,12 @@
         SubtitleTrack bestTrack = null;
         int bestScore = -1;
 
-        Locale selectedLocale = VERSION.SDK_INT >= 19
-                ? CaptioningManagerHelper.Api19Impl.getLocale(mCaptioningManager) : null;
+        Locale selectedLocale = mCaptioningManager.getLocale();
         Locale locale = selectedLocale;
         if (locale == null) {
             locale = Locale.getDefault();
         }
-        boolean selectForced = VERSION.SDK_INT >= 19
-                ? !CaptioningManagerHelper.Api19Impl.isEnabled(mCaptioningManager) : true;
+        boolean selectForced = !mCaptioningManager.isEnabled();
 
         synchronized (mTracksLock) {
             for (SubtitleTrack track: mTracks) {
@@ -302,8 +293,7 @@
             }
             // If track selection is explicit, but visibility
             // is not, it falls back to the captioning setting
-            boolean captionIsEnabledOnSystem = VERSION.SDK_INT >= 19
-                    ? CaptioningManagerHelper.Api19Impl.isEnabled(mCaptioningManager) : false;
+            boolean captionIsEnabledOnSystem = mCaptioningManager.isEnabled();
             if (captionIsEnabledOnSystem
                     || (mSelectedTrack != null && MediaFormatUtil.getInteger(
                             mSelectedTrack.getFormat(),
@@ -337,10 +327,7 @@
         mTracks.clear();
         mTrackIsExplicit = false;
         mVisibilityIsExplicit = false;
-        if (VERSION.SDK_INT >= 19) {
-            CaptioningManagerHelper.Api19Impl.removeCaptioningChangeListener(mCaptioningManager,
-                    mCaptioningChangeListener);
-        }
+        mCaptioningManager.removeCaptioningChangeListener(mCaptioningChangeListener);
     }
 
     /**
@@ -357,9 +344,9 @@
                     SubtitleTrack track = renderer.createTrack(format);
                     if (track != null) {
                         synchronized (mTracksLock) {
-                            if (mTracks.size() == 0 && VERSION.SDK_INT >= 19) {
-                                CaptioningManagerHelper.Api19Impl.addCaptioningChangeListener(
-                                        mCaptioningManager, mCaptioningChangeListener);
+                            if (mTracks.size() == 0) {
+                                mCaptioningManager.addCaptioningChangeListener(
+                                        mCaptioningChangeListener);
                             }
                             mTracks.add(track);
                         }
diff --git a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2Test.java b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2Test.java
index 6601791..ba339c6 100644
--- a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2Test.java
+++ b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2Test.java
@@ -19,6 +19,7 @@
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -198,6 +199,51 @@
         assertTrue(onRouteEnabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
+    @Test
+    @MediumTest
+    public void addUserRouteFromMr1_isSystemRoute_returnsFalse() throws Exception {
+        getInstrumentation()
+                .runOnMainSync(
+                        () -> {
+                            android.media.MediaRouter mediaRouter1 =
+                                    (android.media.MediaRouter)
+                                            mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+
+                            android.media.MediaRouter.RouteCategory sampleRouteCategory =
+                                    mediaRouter1.createRouteCategory(
+                                            "SAMPLE_ROUTE_CATEGORY", /* isGroupable= */ false);
+
+                            android.media.MediaRouter.UserRouteInfo sampleUserRoute =
+                                    mediaRouter1.createUserRoute(sampleRouteCategory);
+                            sampleUserRoute.setName("SAMPLE_USER_ROUTE");
+
+                            mediaRouter1.addUserRoute(sampleUserRoute);
+
+                            for (RouteInfo routeInfo : mRouter.getRoutes()) {
+                                // We are checking for this route using getRoutes rather than
+                                // through the onRouteAdded callback because of b/312700919
+                                if (routeInfo.getName().equals("SAMPLE_USER_ROUTE")) {
+                                    assertFalse(routeInfo.isSystemRoute());
+                                }
+                            }
+                        });
+
+    }
+
+    @Test
+    @MediumTest
+    public void defaultAndBluetoothRoutes_isSystemRoute_returnsTrue() {
+        getInstrumentation()
+                .runOnMainSync(
+                        () -> {
+                            for (RouteInfo routeInfo : mRouter.getRoutes()) {
+                                if (routeInfo.isDefaultOrBluetooth()) {
+                                    assertTrue(routeInfo.isSystemRoute());
+                                }
+                            }
+                        });
+    }
+
     @SmallTest
     @Test
     public void setRouteVolume_onStaticNonGroupRoute() {
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/GlobalMediaRouter.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/GlobalMediaRouter.java
index 1fde149..66f2397 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/GlobalMediaRouter.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/GlobalMediaRouter.java
@@ -69,8 +69,8 @@
  * the media router implementation lives here.
  */
 /* package */ final class GlobalMediaRouter
-        implements SystemMediaRouteProvider.SyncCallback,
-        RegisteredMediaRouteProviderWatcher.Callback {
+        implements PlatformMediaRouter1RouteProvider.SyncCallback,
+                RegisteredMediaRouteProviderWatcher.Callback {
 
     static final String TAG = "GlobalMediaRouter";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -118,7 +118,7 @@
     private boolean mTransferReceiverDeclared;
     private boolean mUseMediaRouter2ForSystemRouting;
     private MediaRoute2Provider mMr2Provider;
-    private SystemMediaRouteProvider mSystemProvider;
+    private PlatformMediaRouter1RouteProvider mPlatformMediaRouter1RouteProvider;
     private DisplayManagerCompat mDisplayManager;
     private MediaRouterActiveScanThrottlingHelper mActiveScanThrottlingHelper;
     private MediaRouterParams mRouterParams;
@@ -169,17 +169,19 @@
                         ? new MediaRoute2Provider(mApplicationContext, new Mr2ProviderCallback())
                         : null;
 
-        // Add the system media route provider for interoperating with
-        // the framework media router.  This one is special and receives
-        // synchronization messages from the media router.
-        mSystemProvider = SystemMediaRouteProvider.obtain(mApplicationContext, this);
+        // Add the platform media router 1 route provider for interoperating with the framework
+        // android.media.MediaRouter. This one is special and receives synchronization messages
+        // from the media router.
+        mPlatformMediaRouter1RouteProvider =
+                PlatformMediaRouter1RouteProvider.obtain(mApplicationContext, this);
         start();
     }
 
     private void start() {
         mActiveScanThrottlingHelper =
                 new MediaRouterActiveScanThrottlingHelper(this::updateDiscoveryRequest);
-        addProvider(mSystemProvider, /* treatRouteDescriptorIdsAsUnique= */ true);
+        addProvider(
+                mPlatformMediaRouter1RouteProvider, /* treatRouteDescriptorIdsAsUnique= */ true);
         if (mMr2Provider != null) {
             addProvider(mMr2Provider, /* treatRouteDescriptorIdsAsUnique= */ true);
         }
@@ -715,7 +717,8 @@
         boolean selectedRouteDescriptorChanged = false;
         if (providerDescriptor != null
                 && (providerDescriptor.isValid()
-                || providerDescriptor == mSystemProvider.getDescriptor())) {
+                        || providerDescriptor
+                                == mPlatformMediaRouter1RouteProvider.getDescriptor())) {
             final List<MediaRouteDescriptor> routeDescriptors = providerDescriptor.getRoutes();
             // Updating route group's contents requires all member routes' information.
             // Add the groups to the lists and update them later.
@@ -723,9 +726,9 @@
             List<Pair<MediaRouter.RouteInfo, MediaRouteDescriptor>> updatedGroups =
                     new ArrayList<>();
             for (MediaRouteDescriptor routeDescriptor : routeDescriptors) {
-                // SystemMediaRouteProvider may have invalid routes
+                // PlatformMediaRouter1RouteProvider may have invalid routes
                 if (routeDescriptor == null || !routeDescriptor.isValid()) {
-                    Log.w(TAG, "Ignoring invalid system route descriptor: " + routeDescriptor);
+                    Log.w(TAG, "Ignoring invalid route descriptor: " + routeDescriptor);
                     continue;
                 }
                 final String id = routeDescriptor.getId();
@@ -968,14 +971,14 @@
     }
 
     private boolean isSystemLiveAudioOnlyRoute(MediaRouter.RouteInfo route) {
-        return route.getProviderInstance() == mSystemProvider
+        return route.getProviderInstance() == mPlatformMediaRouter1RouteProvider
                 && route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
                 && !route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
     }
 
     private boolean isSystemDefaultRoute(MediaRouter.RouteInfo route) {
-        return route.getProviderInstance() == mSystemProvider
-                && route.mDescriptorId.equals(SystemMediaRouteProvider.DEFAULT_ROUTE_ID);
+        return route.getProviderInstance() == mPlatformMediaRouter1RouteProvider
+                && route.mDescriptorId.equals(PlatformMediaRouter1RouteProvider.DEFAULT_ROUTE_ID);
     }
 
     /* package */ void selectRouteInternal(
@@ -1163,10 +1166,10 @@
             };
 
     @Override
-    public void onSystemRouteSelectedByDescriptorId(@NonNull String id) {
+    public void onPlatformRouteSelectedByDescriptorId(@NonNull String id) {
         // System route is selected, do not sync the route we selected before.
         mCallbackHandler.removeMessages(CallbackHandler.MSG_ROUTE_SELECTED);
-        MediaRouter.ProviderInfo provider = findProviderInfo(mSystemProvider);
+        MediaRouter.ProviderInfo provider = findProviderInfo(mPlatformMediaRouter1RouteProvider);
         if (provider != null) {
             MediaRouter.RouteInfo route = provider.findRouteByDescriptorId(id);
             if (route != null) {
@@ -1517,8 +1520,8 @@
                 updateSelectedRouteIfNeeded(true);
             }
 
-            // Synchronize state with the system media router.
-            syncWithSystemProvider(what, obj);
+            // Synchronize state with the platform media router.
+            syncWithPlatformMediaRouter1RouteProvider(what, obj);
 
             // Invoke all registered callbacks.
             // Build a list of callbacks before invoking them in case callbacks
@@ -1543,25 +1546,28 @@
 
         // Using Pair<RouteInfo, RouteInfo>
         @SuppressWarnings({"unchecked"})
-        private void syncWithSystemProvider(int what, Object obj) {
+        private void syncWithPlatformMediaRouter1RouteProvider(int what, Object obj) {
             switch (what) {
                 case MSG_ROUTE_ADDED:
-                    mSystemProvider.onSyncRouteAdded((MediaRouter.RouteInfo) obj);
+                    mPlatformMediaRouter1RouteProvider.onSyncRouteAdded(
+                            (MediaRouter.RouteInfo) obj);
                     break;
                 case MSG_ROUTE_REMOVED:
-                    mSystemProvider.onSyncRouteRemoved((MediaRouter.RouteInfo) obj);
+                    mPlatformMediaRouter1RouteProvider.onSyncRouteRemoved(
+                            (MediaRouter.RouteInfo) obj);
                     break;
                 case MSG_ROUTE_CHANGED:
-                    mSystemProvider.onSyncRouteChanged((MediaRouter.RouteInfo) obj);
+                    mPlatformMediaRouter1RouteProvider.onSyncRouteChanged(
+                            (MediaRouter.RouteInfo) obj);
                     break;
                 case MSG_ROUTE_SELECTED: {
                     MediaRouter.RouteInfo selectedRoute =
                             ((Pair<MediaRouter.RouteInfo, MediaRouter.RouteInfo>) obj).second;
-                    mSystemProvider.onSyncRouteSelected(selectedRoute);
+                    mPlatformMediaRouter1RouteProvider.onSyncRouteSelected(selectedRoute);
                     // TODO(b/166794092): Remove this nullness check
                     if (mDefaultRoute != null && selectedRoute.isDefaultOrBluetooth()) {
                         for (MediaRouter.RouteInfo prevGroupRoute : mDynamicGroupRoutes) {
-                            mSystemProvider.onSyncRouteRemoved(prevGroupRoute);
+                            mPlatformMediaRouter1RouteProvider.onSyncRouteRemoved(prevGroupRoute);
                         }
                         mDynamicGroupRoutes.clear();
                     }
@@ -1571,8 +1577,8 @@
                     MediaRouter.RouteInfo groupRoute =
                             ((Pair<MediaRouter.RouteInfo, MediaRouter.RouteInfo>) obj).second;
                     mDynamicGroupRoutes.add(groupRoute);
-                    mSystemProvider.onSyncRouteAdded(groupRoute);
-                    mSystemProvider.onSyncRouteSelected(groupRoute);
+                    mPlatformMediaRouter1RouteProvider.onSyncRouteAdded(groupRoute);
+                    mPlatformMediaRouter1RouteProvider.onSyncRouteSelected(groupRoute);
                     break;
                 }
             }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouterUtils.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouterUtils.java
index 010daa8..daa8fbd 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouterUtils.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouterUtils.java
@@ -65,14 +65,14 @@
 
     /**
      * This proxy callback class provides a mechanism for {@link
-     * SystemMediaRouteProvider.JellybeanMr2Impl} to circumvent the fact that it cannot extend
-     * {@link android.media.MediaRouter.Callback}. This is because {@link
+     * PlatformMediaRouter1RouteProvider.JellybeanMr2Impl} to circumvent the fact that it cannot
+     * extend {@link android.media.MediaRouter.Callback}. This is because {@link
      * android.media.MediaRouter.Callback} is an abstract class (rather than an interface), and a
      * class cannot extend more than one class. Instead, {@link
-     * SystemMediaRouteProvider.JellybeanMr2Impl} implements the {@link Callback} interface and
-     * references an instance of this proxy class that wraps the {@link
-     * SystemMediaRouteProvider.JellybeanMr2Impl} instance, to use where {@link MediaRouter} expects
-     * an instance of {@link android.media.MediaRouter.Callback}.
+     * PlatformMediaRouter1RouteProvider.JellybeanMr2Impl} implements the {@link Callback} interface
+     * and references an instance of this proxy class that wraps the {@link
+     * PlatformMediaRouter1RouteProvider.JellybeanMr2Impl} instance, to use where {@link
+     * MediaRouter} expects an instance of {@link android.media.MediaRouter.Callback}.
      */
     static class CallbackProxy<T extends Callback> extends android.media.MediaRouter.Callback {
         protected final T mCallback;
@@ -140,14 +140,14 @@
 
     /**
      * This proxy callback class provides a mechanism for {@link
-     * SystemMediaRouteProvider.JellybeanMr2Impl} to circumvent the fact that it cannot extend
-     * {@link android.media.MediaRouter.VolumeCallback}. This is because {@link
+     * PlatformMediaRouter1RouteProvider.JellybeanMr2Impl} to circumvent the fact that it cannot
+     * extend {@link android.media.MediaRouter.VolumeCallback}. This is because {@link
      * android.media.MediaRouter.VolumeCallback} is an abstract class (rather than an interface),
      * and a class cannot extend more than one class. Instead, {@link
-     * SystemMediaRouteProvider.JellybeanMr2Impl} implements the {@link VolumeCallback} interface
-     * and references an instance of this proxy class that wraps the {@link
-     * SystemMediaRouteProvider.JellybeanMr2Impl} instance, to use where {@link MediaRouter} expects
-     * an instance of {@link android.media.MediaRouter.VolumeCallback}.
+     * PlatformMediaRouter1RouteProvider.JellybeanMr2Impl} implements the {@link VolumeCallback}
+     * interface and references an instance of this proxy class that wraps the {@link
+     * PlatformMediaRouter1RouteProvider.JellybeanMr2Impl} instance, to use where {@link
+     * MediaRouter} expects an instance of {@link android.media.MediaRouter.VolumeCallback}.
      */
     static class VolumeCallbackProxy<T extends VolumeCallback>
             extends android.media.MediaRouter.VolumeCallback {
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/PlatformMediaRouter1RouteProvider.java
similarity index 96%
rename from mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java
rename to mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/PlatformMediaRouter1RouteProvider.java
index 2d3bdfb..ea8dc73 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/SystemMediaRouteProvider.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/PlatformMediaRouter1RouteProvider.java
@@ -35,12 +35,11 @@
 import java.util.Locale;
 
 /**
- * Provides routes for built-in system destinations such as the local display
- * and speaker.  On Jellybean and newer platform releases, queries the framework
- * MediaRouter for framework-provided routes and registers non-framework-provided
- * routes as user routes.
+ * Provides routes for built-in system destinations such as the local display and speaker. it
+ * queries the framework {@link android.media.MediaRouter} for framework-provided routes and
+ * registers non-framework-provided routes as user routes.
  */
-abstract class SystemMediaRouteProvider extends MediaRouteProvider {
+abstract class PlatformMediaRouter1RouteProvider extends MediaRouteProvider {
 
     public static final String TAG = "AxSysMediaRouteProvider";
     public static final String PACKAGE_NAME = "android";
@@ -53,12 +52,13 @@
     public static final int ALL_ROUTE_TYPES =
             ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO | ROUTE_TYPE_USER;
 
-    protected SystemMediaRouteProvider(Context context) {
+    protected PlatformMediaRouter1RouteProvider(Context context) {
         super(context, new ProviderMetadata(new ComponentName(PACKAGE_NAME,
-                SystemMediaRouteProvider.class.getName())));
+                PlatformMediaRouter1RouteProvider.class.getName())));
     }
 
-    public static SystemMediaRouteProvider obtain(Context context, SyncCallback syncCallback) {
+    public static PlatformMediaRouter1RouteProvider obtain(
+            Context context, SyncCallback syncCallback) {
         if (Build.VERSION.SDK_INT >= 24) {
             return new Api24Impl(context, syncCallback);
         }
@@ -97,11 +97,11 @@
      * Callbacks into the media router to synchronize state with the framework media router.
      */
     public interface SyncCallback {
-        void onSystemRouteSelectedByDescriptorId(@NonNull String id);
+        void onPlatformRouteSelectedByDescriptorId(@NonNull String id);
     }
 
     /** Jellybean MR2 implementation. */
-    private static class JellybeanMr2Impl extends SystemMediaRouteProvider
+    private static class JellybeanMr2Impl extends PlatformMediaRouter1RouteProvider
             implements MediaRouterUtils.Callback, MediaRouterUtils.VolumeCallback {
 
         private static final ArrayList<IntentFilter> LIVE_AUDIO_CONTROL_FILTERS;
@@ -314,7 +314,7 @@
                 int index = findSystemRouteRecord(route);
                 if (index >= 0) {
                     SystemRouteRecord record = mSystemRouteRecords.get(index);
-                    mSyncCallback.onSystemRouteSelectedByDescriptorId(record.mRouteDescriptorId);
+                    mSyncCallback.onPlatformRouteSelectedByDescriptorId(record.mRouteDescriptorId);
                 }
             }
         }
@@ -516,7 +516,7 @@
             builder.setVolume(record.mRoute.getVolume());
             builder.setVolumeMax(record.mRoute.getVolumeMax());
             builder.setVolumeHandling(record.mRoute.getVolumeHandling());
-            builder.setIsSystemRoute(true);
+            builder.setIsSystemRoute((supportedTypes & ROUTE_TYPE_USER) == 0);
 
             if (!record.mRoute.isEnabled()) {
                 builder.setEnabled(false);
@@ -652,7 +652,7 @@
      */
     @RequiresApi(24)
     private static class Api24Impl extends JellybeanMr2Impl {
-        public Api24Impl(Context context, SyncCallback syncCallback) {
+        /* package */ Api24Impl(Context context, SyncCallback syncCallback) {
             super(context, syncCallback);
         }
 
diff --git a/mediarouter/mediarouter/src/main/res/values-ca/strings.xml b/mediarouter/mediarouter/src/main/res/values-ca/strings.xml
index 6744047..a02305f 100644
--- a/mediarouter/mediarouter/src/main/res/values-ca/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ca/strings.xml
@@ -33,7 +33,7 @@
     <string name="mr_controller_stop" msgid="5497722768305745508">"Atura"</string>
     <string name="mr_controller_expand_group" msgid="4521419834052044261">"Desplega"</string>
     <string name="mr_controller_collapse_group" msgid="2585048604188129749">"Replega"</string>
-    <string name="mr_controller_album_art" msgid="3330502667672708728">"Imatge de l\'àlbum"</string>
+    <string name="mr_controller_album_art" msgid="3330502667672708728">"Coberta de l\'àlbum"</string>
     <string name="mr_controller_volume_slider" msgid="2955862765169128170">"Control lliscant de volum"</string>
     <string name="mr_controller_no_media_selected" msgid="5495452265246139458">"No hi ha contingut multimèdia seleccionat"</string>
     <string name="mr_controller_no_info_available" msgid="855271725131981086">"No hi ha informació disponible"</string>
diff --git a/mediarouter/mediarouter/src/main/res/values-fa/strings.xml b/mediarouter/mediarouter/src/main/res/values-fa/strings.xml
index b27a5dc..d13e45f 100644
--- a/mediarouter/mediarouter/src/main/res/values-fa/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-fa/strings.xml
@@ -33,7 +33,7 @@
     <string name="mr_controller_stop" msgid="5497722768305745508">"متوقف کردن"</string>
     <string name="mr_controller_expand_group" msgid="4521419834052044261">"بزرگ کردن"</string>
     <string name="mr_controller_collapse_group" msgid="2585048604188129749">"کوچک کردن"</string>
-    <string name="mr_controller_album_art" msgid="3330502667672708728">"عکس روی جلد آلبوم"</string>
+    <string name="mr_controller_album_art" msgid="3330502667672708728">"جلد آلبوم"</string>
     <string name="mr_controller_volume_slider" msgid="2955862765169128170">"لغزنده میزان صدا"</string>
     <string name="mr_controller_no_media_selected" msgid="5495452265246139458">"رسانه‌ای انتخاب نشده است"</string>
     <string name="mr_controller_no_info_available" msgid="855271725131981086">"اطلاعاتی در دسترس نیست"</string>
diff --git a/mediarouter/mediarouter/src/main/res/values-fr/strings.xml b/mediarouter/mediarouter/src/main/res/values-fr/strings.xml
index 754f775..dc37209 100644
--- a/mediarouter/mediarouter/src/main/res/values-fr/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-fr/strings.xml
@@ -33,7 +33,7 @@
     <string name="mr_controller_stop" msgid="5497722768305745508">"Arrêt"</string>
     <string name="mr_controller_expand_group" msgid="4521419834052044261">"Développer"</string>
     <string name="mr_controller_collapse_group" msgid="2585048604188129749">"Réduire"</string>
-    <string name="mr_controller_album_art" msgid="3330502667672708728">"Image de l\'album"</string>
+    <string name="mr_controller_album_art" msgid="3330502667672708728">"Pochette de l\'album"</string>
     <string name="mr_controller_volume_slider" msgid="2955862765169128170">"Curseur de volume"</string>
     <string name="mr_controller_no_media_selected" msgid="5495452265246139458">"Aucun contenu multimédia sélectionné"</string>
     <string name="mr_controller_no_info_available" msgid="855271725131981086">"Aucune information disponible"</string>
diff --git a/metrics/metrics-benchmark/src/androidTest/java/androidx/metrics/performance/benchmark/JankStatsBenchmark.kt b/metrics/metrics-benchmark/src/androidTest/java/androidx/metrics/performance/benchmark/JankStatsBenchmark.kt
index 3749d2b..3048ad2 100644
--- a/metrics/metrics-benchmark/src/androidTest/java/androidx/metrics/performance/benchmark/JankStatsBenchmark.kt
+++ b/metrics/metrics-benchmark/src/androidTest/java/androidx/metrics/performance/benchmark/JankStatsBenchmark.kt
@@ -114,7 +114,6 @@
         }
     }
 
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
     @Test
     fun getFrameData() {
         metricsStateHolder.state?.putState("Activity", "activity")
@@ -166,7 +165,6 @@
         }
     }
 
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
     @Test
     fun logFrameData() {
         metricsStateHolder.state?.putState("Activity", "activity")
diff --git a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt
index b107f1f..28b77ce 100644
--- a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt
+++ b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt
@@ -4,10 +4,8 @@
 import android.graphics.Canvas
 import android.graphics.Color
 import android.graphics.Paint
-import android.os.Build
 import android.util.AttributeSet
 import android.view.View
-import androidx.annotation.RequiresApi
 import androidx.metrics.performance.PerformanceMetricsState
 
 class DelayedView(context: Context?, attrs: AttributeSet?) :
@@ -23,7 +21,6 @@
        textPaint.textSize = 50f
     }
 
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
     override fun onDraw(canvas: Canvas) {
         repetitions++
         if (delayMs > 0) {
@@ -54,11 +51,7 @@
             }
         }
         if (repetitions < maxReps) {
-            if (Build.VERSION.SDK_INT >= 16) {
-                postInvalidateOnAnimation()
-            } else {
-                postInvalidate()
-            }
+            postInvalidateOnAnimation()
         }
     }
 }
diff --git a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
index 58b7ba0..18928bb 100644
--- a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
+++ b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
@@ -15,12 +15,9 @@
  */
 package androidx.metrics.performance.test
 
-import android.os.Build
 import android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
-import android.os.Build.VERSION_CODES.JELLY_BEAN
 import android.util.Log
 import android.view.Choreographer
-import androidx.annotation.RequiresApi
 import androidx.metrics.performance.FrameData
 import androidx.metrics.performance.FrameDataApi24
 import androidx.metrics.performance.FrameDataApi31
@@ -57,8 +54,6 @@
     private lateinit var delayedView: DelayedView
     private lateinit var latchedListener: LatchedListener
 
-    private var frameInit: FrameInitCompat
-
     private val NUM_FRAMES = 10
 
     /**
@@ -67,14 +62,6 @@
      */
     private val MIN_JANK_NS = 100000000
 
-    init {
-        if (Build.VERSION.SDK_INT >= 16) {
-            frameInit = FrameInit16(this)
-        } else {
-            frameInit = FrameInitCompat(this)
-        }
-    }
-
     @Rule
     @JvmField
     var delayedActivityRule: ActivityScenarioRule<DelayedActivity> =
@@ -172,12 +159,11 @@
         assertNotEquals(frameData31, frameData31A)
     }
 
-    @SdkSuppress(minSdkVersion = JELLY_BEAN)
     @Test
     fun testNoJank() {
         val frameDelay = 0
 
-        frameInit.initFramePipeline()
+        initFramePipeline()
 
         runDelayTest(frameDelay, NUM_FRAMES, latchedListener)
         assertEquals("numJankFrames should equal 0", 0, latchedListener.numJankFrames)
@@ -194,13 +180,12 @@
         )
     }
 
-    @SdkSuppress(minSdkVersion = JELLY_BEAN)
     @Test
     fun testMultipleListeners() {
         var secondListenerLatch = CountDownLatch(0)
         val frameDelay = 0
 
-        frameInit.initFramePipeline()
+        initFramePipeline()
 
         var numSecondListenerCalls = 0
         val secondListenerStates = mutableListOf<StateInfo>()
@@ -264,12 +249,11 @@
         runDelayTest(frameDelay, NUM_FRAMES * 100, latchedListener)
     }
 
-    @SdkSuppress(minSdkVersion = JELLY_BEAN)
     @Test
     fun testRegularJank() {
         val frameDelay = 100
 
-        frameInit.initFramePipeline()
+        initFramePipeline()
 
         runDelayTest(frameDelay, NUM_FRAMES, latchedListener)
 
@@ -289,12 +273,11 @@
         )
     }
 
-    @SdkSuppress(minSdkVersion = JELLY_BEAN)
     @Test
     fun testFrameStates() {
         val frameDelay = 0
 
-        frameInit.initFramePipeline()
+        initFramePipeline()
 
         resetFrameStateData()
 
@@ -379,7 +362,7 @@
     )
 
     /**
-     * Utility function (embedded in a class because it uses version-specific APIs) which
+     * Utility function which
      * is used by tests which require the frame pipeline to be empty when they
      * start. When the activity first starts, there are usually a couple of frames drawn.
      * Depending on when those frames are drawn relative to when the JankStats object and
@@ -389,31 +372,24 @@
      * begins, so that any data used by the test will only land on frames after the test begins
      * instead of these old activity-creation frames.
      */
-    open class FrameInitCompat(val jankStatsTest: JankStatsTest) {
-        open fun initFramePipeline() {}
-    }
-
-    @RequiresApi(16)
-    class FrameInit16(jankStatsTest: JankStatsTest) : FrameInitCompat(jankStatsTest) {
-        override fun initFramePipeline() {
-            val latch = CountDownLatch(10)
-            var numFrames = 10
-            val callback: Choreographer.FrameCallback = object : Choreographer.FrameCallback {
-                override fun doFrame(frameTimeNanos: Long) {
-                    --numFrames
-                    latch.countDown()
-                    if (numFrames > 0) {
-                        Choreographer.getInstance().postFrameCallback(this)
-                    }
+     private fun initFramePipeline() {
+        val latch = CountDownLatch(10)
+        var numFrames = 10
+        val callback: Choreographer.FrameCallback = object : Choreographer.FrameCallback {
+            override fun doFrame(frameTimeNanos: Long) {
+                --numFrames
+                latch.countDown()
+                if (numFrames > 0) {
+                    Choreographer.getInstance().postFrameCallback(this)
                 }
             }
-            jankStatsTest.delayedActivityRule.getScenario().onActivity {
-                Choreographer.getInstance().postFrameCallback(callback)
-            }
-            latch.await(5, TimeUnit.SECONDS)
-
-            jankStatsTest.latchedListener.reset()
         }
+        delayedActivityRule.getScenario().onActivity {
+            Choreographer.getInstance().postFrameCallback(callback)
+        }
+        latch.await(5, TimeUnit.SECONDS)
+
+        latchedListener.reset()
     }
 
     /**
@@ -433,10 +409,9 @@
         runDelayTest(0, NUM_FRAMES, latchedListener)
     }
 
-    @SdkSuppress(minSdkVersion = JELLY_BEAN)
     @Test
     fun testComplexFrameStateData() {
-        frameInit.initFramePipeline()
+        initFramePipeline()
 
         // perFrameStateData is a structure for testing which holds information about the
         // states that should be added or removed on every frame. This functionality is
diff --git a/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStats.kt b/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStats.kt
index 9b13051..567ae1b 100644
--- a/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStats.kt
+++ b/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStats.kt
@@ -103,11 +103,8 @@
                 Build.VERSION.SDK_INT >= 22 -> {
                     JankStatsApi22Impl(this, decorView)
                 }
-                Build.VERSION.SDK_INT >= 16 -> {
-                    JankStatsApi16Impl(this, decorView)
-                }
                 else -> {
-                    JankStatsBaseImpl(this)
+                    JankStatsApi16Impl(this, decorView)
                 }
             }
         implementation.setupFrameTimer(true)
diff --git a/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt b/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt
index 920fdb7..c2999cf6 100644
--- a/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt
+++ b/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt
@@ -29,7 +29,6 @@
  * Subclass of JankStatsBaseImpl records frame timing data for API 16 and later,
  * using Choreographer (which was introduced in API 16).
  */
-@RequiresApi(16)
 internal open class JankStatsApi16Impl(
     jankStats: JankStats,
     view: View
diff --git a/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsInternalsForTesting.kt b/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsInternalsForTesting.kt
index b4f5083..2030fa6 100644
--- a/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsInternalsForTesting.kt
+++ b/metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsInternalsForTesting.kt
@@ -35,7 +35,6 @@
         performanceMetricsState.removeStateNow(stateName)
     }
 
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
     fun getFrameData(): FrameData? {
         when (impl) {
             is JankStatsApi16Impl -> {
@@ -55,7 +54,6 @@
         return null
     }
 
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
     fun logFrameData(frameData: FrameData) {
         jankStats.logFrameData(frameData)
     }
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt
index c0b072a..937c4c8 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavGraphTest.kt
@@ -97,6 +97,34 @@
             .isFalse()
     }
 
+    @Test
+    fun graphEqualsId() {
+        val graph = NavGraph(navGraphNavigator)
+        graph += navigator.createDestination().apply { id = DESTINATION_ID }
+        graph += navigator.createDestination().apply { id = SECOND_DESTINATION_ID }
+        val other = NavGraph(navGraphNavigator)
+        other += navigator.createDestination().apply { id = DESTINATION_ID }
+        other += navigator.createDestination().apply { id = SECOND_DESTINATION_ID }
+
+        assertWithMessage("Graphs should be equal")
+            .that(graph)
+            .isEqualTo(other)
+    }
+
+    @Test
+    fun graphNotEqualsId() {
+        val graph = NavGraph(navGraphNavigator)
+        graph += navigator.createDestination().apply { id = DESTINATION_ID }
+        graph += navigator.createDestination().apply { id = SECOND_DESTINATION_ID }
+        val other = NavGraph(navGraphNavigator)
+        other += navigator.createDestination().apply { id = DESTINATION_ID }
+        other += navigator.createDestination().apply { id = 3 }
+
+        assertWithMessage("Graphs should not be equal")
+            .that(graph)
+            .isNotEqualTo(other)
+    }
+
     @Test(expected = IllegalArgumentException::class)
     fun getIllegalArgumentException() {
         val graph = NavGraph(navGraphNavigator)
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt
index f4b21df..1e1020e 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraph.kt
@@ -384,7 +384,7 @@
         return super.equals(other) &&
             nodes.size == other.nodes.size &&
             startDestinationId == other.startDestinationId &&
-            nodes.valueIterator().asSequence().all { it == nodes.get(it.id) }
+            nodes.valueIterator().asSequence().all { it == other.nodes.get(it.id) }
     }
 
     override fun hashCode(): Int {
diff --git a/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/Stubs.kt b/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/Stubs.kt
index 6ab5a6b..28c7915 100644
--- a/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/Stubs.kt
+++ b/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/Stubs.kt
@@ -21,7 +21,7 @@
 internal val NAV_BACK_STACK_ENTRY = bytecodeStub(
     filename = "NavBackStackEntry.kt",
     filepath = "androidx/navigation",
-    checksum = 0x6920c3ac,
+    checksum = 0xfef36ae,
     source = """
     package androidx.navigation
 
@@ -29,27 +29,28 @@
 """,
     """
     META-INF/main.kotlin_module:
-    H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AJcTFnZyfq5dakZhbkJMqxBzvXaLE
-    oMUAAMRK5d0sAAAA
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuOSSMxLKcrPTKnQS87PLcgvTtUr
+    Ks0rycxNFeIKSs1NzU1KLfIu4RLl4gZK66VWJOYW5KQKsYWkFpd4lygxaDEA
+    ALrkMh5XAAAA
     """,
     """
     androidx/navigation/NavBackStackEntry.class:
-    H4sIAAAAAAAAAI2Ru04CQRSG/zPAoisKKiqosTNeCleMncZEjCYkiIkYGqqB
-    3eBwmU12hw12PItvYGViYYilD2U8u9rZOMWX8/9nMucyn19v7wBOsU3YldoN
-    fOVOHC0j1ZNG+dppyKgqu4OmYVxrEzxlQYRCX0bSGUrdc+46fa9rskgRrHOl
-    lbkgpPYPWjlkYNlII0tIm0cVEvbq/6pwRliuD3wzVNq59Yx0pZHsiVGU4lYp
-    RoZAA7YmKlbHHLkVws5satuiJGxR4Gg2Lc2mJ+KYqpmPZ0sURHzrhPgFFP/U
-    PBoYbvPKdz1Cvq601xiPOl7wIDtDdlbqflcOWzJQsf417aY/DrrejYpF+X6s
-    jRp5LRUqzl5q7ZtkvBAVCN5CfLjpeCnMDVZOonmWw1fMvXAgUGJaiZlGmZn7
-    uYB52El+M+E6tpIvIyxwLtdGqobFGpaYyMco1LCMlTYoxCqKnA9hh1gLYX0D
-    +QLjIO8BAAA=
+    H4sIAAAAAAAA/41Ru0oDQRQ9d5JsdI2axKjx2YmPwk3EThGMKCysCipprCbZ
+    RSePWdidhNjlW/wDK8FCgqUfJd5d7WxsDudxh/uYz6+3dwCH2CBsSe1HofJH
+    jpZD9SCNCrVzJYcN2e7eGoZzbaKnPIhQ7MihdHpSPzjXrU7QNnlkCNax0sqc
+    EDI7u80CcrBsZJEnZM2jignb3r86HBFKXjc0PaWdy8BIXxrJnugPMzwqJTCd
+    AAjUZX+kElVj5tcJm5OxbYuqsEWR2WRcnYwPRI0auY9nSxRFUnVAydvKn8b7
+    XcOznoV+QJj3lA6uBv1WEN3JVo+dshe2Za8pI5XoX9O+DQdRO7hQiVi5GWij
+    +kFTxYrTU61Dk+4Yow7Bp/gdOrkMY5WVk2ogt/eKqRcmAiuMVmpmscpY+CnA
+    NOw0X0txGevpvxFmOCvcI+Ni1sWci3kUmaLkooyFe1CMChY5j2HHWIphfQMn
+    9fXa9AEAAA==
     """
 )
 
 internal val NAV_CONTROLLER = bytecodeStub(
     filename = "NavController.kt",
     filepath = "androidx/navigation",
-    checksum = 0xa6eda16e,
+    checksum = 0xeb9f76f4,
     source = """
     package androidx.navigation
 
@@ -59,32 +60,33 @@
 """,
     """
     META-INF/main.kotlin_module:
-    H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AJcTFnZyfq5dakZhbkJMqxBzvXaLE
-    oMUAAMRK5d0sAAAA
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgUuOSSMxLKcrPTKnQS87PLcgvTtUr
+    Ks0rycxNFeIKSs1NzU1KLfIu4RLl4gZK66VWJOYW5KQKsYWkFpd4lygxaDEA
+    ALrkMh5XAAAA
     """,
     """
     androidx/navigation/NavController.class:
-    H4sIAAAAAAAAAI1SW08TQRT+Ztru4oJlQbkrioDclAXikzVGIZqU1GrEkBie
-    pttJmXY7m+xOG3zjt/gL9AmjiSE++qOMZ8pGrGhkkz1nzjnf+WbO5fuPz18B
-    PMA6w5zQ9SRW9aNAi65qCKNiHVRFdyfWJomjSCYuGIPfFF0RREI3gpe1pgyN
-    ixyD80hpZR4z5JZX9odQgOMhD5chbw5VyjBf+S97iWGkIc22CFt7hsQzCrxj
-    KC1Xzm/cM4nSjdLKv9j6k0v23jhpBE1paolQOg2E1rHpwdOgGptqJ4oIVUji
-    jpEDKDLMtmITKR00u+1AaSMTLaKgrO29qQpTFz7DWHgow1aW/kokoi0JyLD0
-    +1PPmlP6y+OpP6O45mEE1xkWL1WJi3EPE7afoxcJqW+V7NUvpBF1YQT5eLub
-    o9EyKwoMrEWuI2WtDTrVNxkenh6Pe3ySe9w/Pfb4AO8Z9ugXJ0+Pt/gG2y58
-    e+9wn+8W/dw038hvOX6BtGMZthixY+nSo/D7pr3eMrQcO3FdMgxXlJbVTrsm
-    kzeiFklbZRyKaF8kytqZc+Z1RxvVlmXdVaki19PzYTIs/Bn9NZg+mLcXd5JQ
-    PleWcSrL2b/Ah01wWmD7caqS9tnWSlZAmtmWrp5g4GMvvEzS6TnzWCE5dAbA
-    FXikRzBInlwveZvQnHRxbXT4E8a+YOLtCSY/9LE4lGlZxs+QGYs9FTFF8dUM
-    d5X0Gv0uywyOez15F/dJPyHvNFHNHCBXxo0ybpLErBW3yriNuQOwFHcwfwA3
-    hZdiIYWTYjDFYooimT8B9qxp7xsEAAA=
+    H4sIAAAAAAAA/41SW08TQRT+ZtruwoJlQbkrioDclAXikzVGIZrU1GrEkBie
+    pttJmXY7m+xOG3zjt/gL9AmjiSE++qOMZ8pGrGhkkz3X73wzc875/uPzVwD3
+    ETDMC11PYlU/CrToqoYwKtZBVXR3Y22SOIpk4oIx+E3RFUEkdCN4WWvK0LjI
+    MTgPlVbmEUNuZXV/GAU4HvJwGfLmUKUMC5X/spcYRhvS7IiwtWdIPKXEO4bS
+    SuX8xD2TKN0orf6Lrb+4ZM+Nk0bQlKaWCKXTQGgdmx48DaqxqXaiiFCFJO4Y
+    OYAiw1wrNpHSQbPbDpQ2MtEiCsranpuqMHXhM4yHhzJsZeWvRCLakoAMy79f
+    9aw5pb9cnvozhqseRnGNYelSL3Ex4WHS9nPsIiH1rZLd+oU0oi6MoBhvd3M0
+    WmbFoBVgYC2KHynrbZJV32J4cHo84fEp7nH/9NjjA7znWNMvTp0eb/NNtlP4
+    9t7hPn9e9HMzfDO/7fgF0o5l2GaWd/nS8/D7Rr7RMrQhu3FdMoxUlJbVTrsm
+    kzeiFkn71DgU0b5IlPWz4OzrjjaqLcu6q1JFoSfnE2VY/DP7azp9MG8v7iSh
+    fKYs43RWs3+BD1vgtMX24/RKWmqSK+QFtpekC2snGPjYS6+SdHrBPNZIDp8B
+    MAiP9CiGKJLrFe8QmpMuro+NfML4F0y+PcHUhz4Whyoty8QZMmOxVhHTlF/P
+    cFdI36XfZZnDca8nl7FB+jFFZ4hq9gC5Mq6XcaOMOdwkE7fKmMftA7AUC1g8
+    gJvCS7GUwkkxlOJOiiK5PwElc7kHIAQAAA==
     """
 )
 
 internal val NAV_GRAPH_BUILDER = bytecodeStub(
     filename = "NavGraphBuilder.kt",
     filepath = "androidx/navigation",
-    checksum = 0xf26bfe8b,
+    checksum = 0xced68271,
     source = """
     package androidx.navigation
 
@@ -92,28 +94,28 @@
 """,
     """
     META-INF/main.kotlin_module:
-    H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AZc0lnZiXUpSfmVKhl5dYlpmeWJKZ
-    n6eXnJ9bkF+cKiTol1jmXpRYkOFUmpmTklrkXSLECRTyyC8u8S5RYtBiAAA0
-    5BaVVQAAAA==
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuaSTsxLKcrPTKnQy0ssy0xPLMnM
+    z9NLzs8tyC9OFRL0SyxzL0osyHAqzcxJSS3yLhHiBAp55BeXeJdwiXJxAxXq
+    pVYk5hbkpAqxhaSChJUYtBgARVljGmwAAAA=
     """,
     """
     androidx/navigation/NavGraphBuilder.class:
-    H4sIAAAAAAAAAI1RTUsCURQ996ljTVajfWlFmwiqRaPRrggqKAQzqHDT6ukM
-    +nJ8EzNPcelv6R+0ClqEtOxHRXemVq16i8M951zu1/v8ensHcIRNwrbUXhQq
-    b+xqOVJdaVSo3aYcXUXyqXc+VIHnR3kQwXmUI+kGUnfdm/aj3zF5ZAjWidLK
-    nBIyu3utAnKwbGSRJ2RNT8WEncY/6h8Tio1+aAKl3WvfSE8ayZoYjDI8JiWQ
-    I1CfpbFKWJUjr0bYmk5sW5SFLRyOppPydHIoqnSe+3i2hCOSrEPiCij96XjQ
-    NzziRej5hMWG0n5zOGj70b1sB6yUGmFHBi0ZqYT/ivZdOIw6/qVKSOV2qI0a
-    +C0VK3bPtA5NulqMGgRfIHk8cnIQxjVmbsp5k/1XzLxwIFBmtFIxiwpj4ScB
-    s7BTfz3FVWykn0WYY6/wgEwd83UsMGIxAaeOIkoPoBhLWGY/hh1jJYb1DRVj
-    VoXpAQAA
+    H4sIAAAAAAAA/41Ru04CQRQ9d4BFVhTEF/hqjIlauGrsNCZioiFBTNTQUA3s
+    BkaWWbM7EEu+xT+wMrEwxNKPMt5dqaxsTs7jzp07d76+3z8AnGCTsC21GwbK
+    fXa0HKmuNCrQTkOOrkP51KsOle96YRZEKD7KkXR8qbvObfvR65gsUgTrTGll
+    zgmp3b1mHhlYNtLIEtKmpyLCTv0f/U8JC/V+YHylnRvPSFcayZ4YjFI8JsWQ
+    iwEE6rP/rGJ1yMw9ImxNxrYtysIWRWaTcXkyPhaHVM18vliiKOKqY4rPlv5c
+    e9A3POdl4HqEQl1przEctL3wQbZ9dkr1oCP9pgxVrKemfR8Mw453pWJRuRtq
+    owZeU0WK0wutA5O8L8IRBK9hOnK8FcYyKyfRQGb/DTOvTAQqjFZiprHGmP8t
+    QA52kq8nuIqN5McIs5zlW0jVMFfDfA0FFJlioYYSFlugCEtY5jyCHWElgvUD
+    nsoUQO4BAAA=
     """
 )
 
 internal val NAV_GRAPH_COMPOSABLE = bytecodeStub(
     filename = "NavGraphBuilder.kt",
     filepath = "androidx/navigation/compose",
-    checksum = 0x6920624a,
+    checksum = 0xc3b35ff,
     source = """
     package androidx.navigation.compose
 
@@ -129,37 +131,37 @@
 """,
     """
     META-INF/main.kotlin_module:
-    H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AZc0lnZiXUpSfmVKhl5dYlpmeWJKZ
-    n6eXnJ9bkF+cKiTol1jmXpRYkOFUmpmTklrkXSLECRTyyC8u8S7hEuXiBirU
-    S61IzC3ISRViC0kFCSsxaDEAAFP1RV1sAAAA
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuaSTsxLKcrPTKnQy0ssy0xPLMnM
+    z9NLzs8tyC9OFRL0SyxzL0osyHAqzcxJSS3yLhHiBAp55BeXeJdwiXJxAxXq
+    pVYk5hbkpAqxhaSChJUYtBgARVljGmwAAAA=
     """,
     """
     androidx/navigation/compose/NavGraphBuilderKt.class:
-    H4sIAAAAAAAAAL1VS1MTQRD+ZvMkoiYbBQKKqCgvcUN8XGJRJZRaKSM+ohzk
-    NNmsYfKYpXYmKbxx9WT5F/wH3iwPFuXRH2XZkwRIMBZcdFPb09PT/X090z2b
-    n7++fQdwF/cZlrmsBL6o7DqSt0WVa+FLx/WbO77ynA3efhLwne21lmhUvOCp
-    joExJGu8zZ0Gl1XnebnmuWQNMSS6Qbzc8BjezheH4R7DyxePkEo6ELKaL9Z9
-    3RDSqbWbzruWdE2Ych73tJX8wibDp38E/mD5b7hr3K2XNIlHUgfvD3HeSKHz
-    q52crhf9oOrUPF0OuCBQLqWveZdgw9cbrUYjzxB9oLeFWo1jhGG6LxkhtRdI
-    3nAK0mSqhKtiOMNw0d323Hov/gUPeNMjR4a5+eLxGgzZ7sLmKM7iXAKjOM8Q
-    CfyW9uJIMcRcnwiljiNN1Zw1Oc32V+/Gqc6Xwf6Tk2HmpBJSqxyhMnz879Uc
-    xP2zlrFydy2OqcPj6c84dRDzzNO8wjWnLVnNdoiuFDMiwsDqRrHIviuMliWt
-    ssLwYX/vZmJ/L2ElrYQ1YXXVc51hwjp6451xcim5vzdpZdmilbVy0WSI9HBu
-    PBmZTNth28rGOpJloz8+R614nNxHhngnet7WgPcZk1COUcZUxd52+ks0d8qr
-    MNAsB5+NoCW1aHrO+mFPkd/0Ac2jXeo9RXAHfK/f7xgH+1hpbtc1Q3jdr1BH
-    ni8K6W20mmUveN3tUbvou7yxyQNh5j3jSElUJdetgPTZV90sCrItlKDlw/vz
-    8OhuUi+W/Fbgeo+Fic/0Yja7EX2OWIGFMMxjIYMIogjBodlLmpsKpxftxFck
-    l2yb5C37AskvHecsyag5ZiQIBJjpuuMixjpwaaQwTutGS2OCInKduBjuGFuI
-    luKms/pkhn4n8F8awj86wH95CP9UH//k3/kt+usw8jbu0ficrNN0Ile2ECpg
-    poCrJHGtgOuYLeAGbm6BKcxhfgujChGFBYUxhVRHSSssKiwp3FLIKEwpLP8G
-    Q1+Sp54GAAA=
+    H4sIAAAAAAAA/71UTVMTQRB9s4EkBNRkI8qHIgrIl7ABvw6xqFIKrJQxqCAH
+    OU02axiSzFI7kxTcuHqy/Av+A2+WB4vy6I+y7N0kJIFQcNFKpadn5vV7PdM9
+    +/vPj58AHuEpwwKXBc8VhQNL8pooci1cadluZd9VjpXjtZce3999URXlguO9
+    0hEwhvger3GrzGXR2sjvOTathhhi9SCeLzsMH2ay3XhP8aWzLaZN7QlZTGdL
+    ri4Lae3VKtbHqrT9MGWtN7yl9Ow2w5d/RP5s4TzeF9wubWoya1J7hyc876XQ
+    6ZUgp4ms6xWtPUfnPS6IlEvpal4XyLk6Vy2X0wzhZ3pXqJUo+hjG2pIRUjue
+    5GUrI/1MlbBVBP0Mg/auY5ca8W+4xysOARmmZ7Kna9DluLPbA7iCqzEM4BpD
+    r+dWtRNFgiFiuyQodRRJquakn9Nke/WmLnW/DOZZTYbxi0pIrdJiZfj836vZ
+    yXu2lpF8fS+K0ZPrac840Yx57Whe4JrTkYxKLURPivmmzzdgYCXfMWjzQPhe
+    irzCEsOn46P7seOjmBE3YsaQUXevBsOQ0fpHg3FkPn58NGKk2JyRMpbD8RD5
+    Pcs3470jSbPHNFKRwLJU+NfXsBGNEryvCzrWQBsd6H4/oWXm52o2z9Rep+lL
+    voeOjml+O7yq1KLiWKsnjUW4sabM2gE1oCK6pt7W4b4PME/VZ7GkGXpW3QK1
+    5bWskE6uWsk73la9Uc2sa/PyNveEP28s9m2KouS66pE/+a6eRUbWhBK0ffKI
+    nrceKDXkplv1bGdd+PHDjZjtekQbEEsw0OMXl8Zh9CKMEFI0e0tzv8LJOTP2
+    HfF50yT7wLxO9lsAXiIb9q8ZMSyTP16HYxA3ArokErhJ+76XxBBFPAziIvSR
+    prUQbUWDnmrZYfpdoH+ri/5Ah/7tLvqjbfoj5+sbeBxYC09o3KDVMbqROzsI
+    ZTCewd0M7mEig0lMZXAf0ztgCjOY3cGAQq/CnMINhUTgJBXmFR4oLCgMK4wq
+    LP4F8P5Vs6MGAAA=
     """
 )
 
 internal val NAV_HOST = bytecodeStub(
     filename = "NavHost.kt",
     filepath = "androidx/navigation/compose",
-    checksum = 0x72aa34d0,
+    checksum = 0x6aac9b28,
     source = """
     package androidx.navigation.compose
 
@@ -169,25 +171,25 @@
 """,
     """
     META-INF/main.kotlin_module:
-    H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3AZc0lnZiXUpSfmVKhl5dYlpmeWJKZ
-    n6eXnJ9bkF+cKiTol1jmXpRYkOFUmpmTklrkXSLECRTyyC8u8S5RYtBiAAA0
-    5BaVVQAAAA==
+    H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgsuaSTsxLKcrPTKnQy0ssy0xPLMnM
+    z9NLzs8tyC9OFRL0SyxzL0osyHAqzcxJSS3yLhHiBAp55BeXeJdwiXJxAxXq
+    pVYk5hbkpAqxhaSChJUYtBgARVljGmwAAAA=
     """,
     """
     androidx/navigation/compose/NavHostKt.class:
-    H4sIAAAAAAAAAJVSy24TMRQ9nrxDH0lKXwFKoS19AZNWsApCKhWFqCEgUrLp
-    ypmY1MnErmY8Udn1W/gDdogFqljyUYg7k6SNVCRgpDn3+vjch33989e37wCe
-    4CHDGlctT8vWma14X7a5kVrZju6dal/YNd5/rX1zaFJgDLkO73Pb5aptv212
-    hENsjCE1FDE83aheKerGk6pdrna1caWyO/2e/TFQTpjetw+G3k55s8HQ+f+4
-    Z4+qf+qbWnnl8dOTF4F0W8K7zPJBSVN+HhVbqWqvbXeEaXpcUkqulDZ8kL6m
-    TS1w3TJDwtOBEWlkGJbGOpHKCE9x166osE1fOn4KNxhmnRPhdIfh77jHe4KE
-    DOvjJxvcWfn6WTcbE5jEVBYTmKb7bA6aTyPPULiuZlj+26Uy5EeSN8LwFjec
-    OKvXj9HUWQgJBtYNHYv4Mxl6JfJaOwyHF+fF7MV51spZAzMVmQVr9BfXcySx
-    Smw3mbPIxnbnc/HiTCFesErJCFkp8eNz0kqnwpS7jGrSQYYNjXe59k9DpBGM
-    gl+eGUG3rtUoy9GnU0GC7PANPu7SM4zv65ZgmK5KJWpBrym8I950RdiDdrjb
-    4J4M10MyU5dtxU3gkb/6PlBG9kRF9aUvaftylHtXr4Sq1XXgOeJAhvGLw5jG
-    IGJMiB1YiCP8SIYEkohhjVZ7xFtkJ7cK2a/IbRcKhF/CYeABYZLkE4Tr5M8N
-    hMhgJko0iTxu0v5GpE5hM+QsItJRlXREb0W4im2y+8TOUu25Y8QqmK9ggRCL
-    FRRxq4LbuHMM5mMJd4+R9pHwsewjE2Hexz0f932s/AYz8VZoLwQAAA==
+    H4sIAAAAAAAA/5VSS2/TQBD+1nmHPhKXvgK0hbb0RXFawSkIqVQUrIaAaMml
+    p42zpJs468peR+XW38I/4IY4oIojPwoxdpI2UpGAg7+Znf1m5vPM/vz17TuA
+    J9hmWOWq6XuyeW4p3pMtrqWnLMfrnnmBsGq899oL9KHOgDEU2rzHLZerlvW2
+    0RYORRMMmQGJ4el69ZpxpH2pWpVqx9OuVFa717U+hsqJygfWwcDbqWzUGdr/
+    n/dsu/on3STllc/PTl+E0m0K/6rKByV15XncbLnq+S2rLXTD55JKcqU8zfvl
+    a56uha5bYUj5XqhFFjmGhRElUmnhK+5atopkBtIJMrjFMO2cCqczSH/Hfd4V
+    RGRYG/2z/swqN/91oz6GcUzkMYZJmmejLz6LIoN5k82w9LehMhSHlDdC8ybX
+    nGJGt5egrbMIchGAgXUix6DLcxl5ZfKaOwyHlxel/OVF3igYfTMRmzlj+JXW
+    CkQxymw3XTDIJnZnC8nSlJk0jXI6RlZO/ficNrKZqOQui7qZQ1WjUlf/aZO0
+    h2Hyy3MtaPSeGlY5/nQmiJAfPMTHHXqLyX2vKRgmq1KJWthtCP+YN1wRafAc
+    7ta5L6PzIJg7ki3FdeiTv/I+VFp2ha16MpB0fbXPveunQt2OvNB3xIGM8ucH
+    OfV+xggROzCQRH/a80ghjQQe0mmP4gbZ8U0z/xWFLdMk/BItA2uEaaKPEa6T
+    P9MnIoepuNA4irhN9xsxO4PNKGZQIBt3ycbhrRhX8YjsPkWnqffMCRI2Zm3M
+    2aSlZOMO7tq4h4UTsACLWDpBNkAqwP0AuRiLAR4EWA6w8hvNMdYWNAQAAA==
     """
 )
diff --git a/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/UnrememberedGetBackStackEntryDetectorTest.kt b/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/UnrememberedGetBackStackEntryDetectorTest.kt
index b33210d..4874559 100644
--- a/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/UnrememberedGetBackStackEntryDetectorTest.kt
+++ b/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/UnrememberedGetBackStackEntryDetectorTest.kt
@@ -193,7 +193,8 @@
             ),
             Stubs.Composable,
             Stubs.Remember,
-            NAV_CONTROLLER
+            NAV_CONTROLLER,
+            NAV_BACK_STACK_ENTRY
         )
             .run()
             .expect(
@@ -368,7 +369,8 @@
             ),
             Stubs.Composable,
             Stubs.Remember,
-            NAV_CONTROLLER
+            NAV_CONTROLLER,
+            NAV_BACK_STACK_ENTRY
         )
             .run()
             .expectClean()
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
index e04dfa4..1ac6d52 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
@@ -44,7 +44,6 @@
 import androidx.test.ext.truth.os.BundleSubject.assertThat
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.TestNavigator
 import androidx.testutils.test
 import com.google.common.truth.Truth.assertThat
@@ -1605,7 +1604,6 @@
 
     @LargeTest
     @Test
-    @SdkSuppress(minSdkVersion = 17)
     fun testNavigateViaImplicitDeepLink() {
         val intent = Intent(
             Intent.ACTION_VIEW,
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
index c4df050..2bc9065 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
@@ -52,7 +52,6 @@
 import androidx.test.ext.truth.os.BundleSubject.assertThat
 import androidx.test.filters.LargeTest
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.TestNavigator
 import androidx.testutils.test
 import androidx.testutils.withActivity
@@ -1025,7 +1024,6 @@
 
     @LargeTest
     @Test
-    @SdkSuppress(minSdkVersion = 17)
     fun testNavigateViaImplicitDeepLink() {
         val intent = Intent(
             Intent.ACTION_VIEW,
@@ -1119,7 +1117,6 @@
 
     @LargeTest
     @Test
-    @SdkSuppress(minSdkVersion = 17)
     fun testExplicitDeepLinkNavigateUpOffOtherTaskStack() {
         val navDeepLinkBuilder = NavDeepLinkBuilder(
             ApplicationProvider.getApplicationContext()
@@ -1492,7 +1489,6 @@
 
     @LargeTest
     @Test
-    @SdkSuppress(minSdkVersion = 17)
     fun testExplicitDeepLinkSeparateNavGraph() {
         val navDeepLinkBuilder = NavDeepLinkBuilder(
             ApplicationProvider.getApplicationContext()
diff --git a/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/PercentRelativeRtlTest.java b/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/PercentRelativeRtlTest.java
index 640be5b..68d01a3 100644
--- a/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/PercentRelativeRtlTest.java
+++ b/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/PercentRelativeRtlTest.java
@@ -161,22 +161,14 @@
 
     @Test
     public void testStartChild() {
-        if (Build.VERSION.SDK_INT == 17) {
-            return;
-        }
+
         final View childToTest = mPercentRelativeLayout.findViewById(R.id.child_start);
 
-        if (Build.VERSION.SDK_INT >= 17) {
-            switchToRtl();
+        switchToRtl();
 
-            final int childRight = childToTest.getRight();
-            assertFuzzyEquals("Child start margin as 5% of the container",
-                    0.05f * mContainerWidth, mContainerWidth - childRight);
-        } else {
-            final int childLeft = childToTest.getLeft();
-            assertFuzzyEquals("Child start margin as 5% of the container",
-                    0.05f * mContainerWidth, childLeft);
-        }
+        final int childRight = childToTest.getRight();
+        assertFuzzyEquals("Child start margin as 5% of the container",
+                0.05f * mContainerWidth, mContainerWidth - childRight);
 
         final int childWidth = childToTest.getWidth();
         final int childHeight = childToTest.getHeight();
@@ -194,23 +186,13 @@
 
     @Test
     public void testBottomChild() {
-        if (Build.VERSION.SDK_INT == 17) {
-            return;
-        }
         final View childToTest = mPercentRelativeLayout.findViewById(R.id.child_bottom);
 
-        if (Build.VERSION.SDK_INT >= 17) {
-            switchToRtl();
+        switchToRtl();
 
-            final int childLeft = childToTest.getLeft();
-            assertFuzzyEquals("Child end margin as 20% of the container",
-                    0.2f * mContainerWidth, childLeft);
-        } else {
-            final int childRight = childToTest.getRight();
-            assertFuzzyEquals("Child end margin as 20% of the container",
-                    0.2f * mContainerWidth, mContainerWidth - childRight);
-        }
-
+        final int childLeft = childToTest.getLeft();
+        assertFuzzyEquals("Child end margin as 20% of the container",
+                0.2f * mContainerWidth, childLeft);
 
         final int childWidth = childToTest.getWidth();
         final int childHeight = childToTest.getHeight();
@@ -228,22 +210,13 @@
 
     @Test
     public void testEndChild() {
-        if (Build.VERSION.SDK_INT == 17) {
-            return;
-        }
         final View childToTest = mPercentRelativeLayout.findViewById(R.id.child_end);
 
-        if (Build.VERSION.SDK_INT >= 17) {
-            switchToRtl();
+        switchToRtl();
 
-            final int childLeft = childToTest.getLeft();
-            assertFuzzyEquals("Child end margin as 5% of the container",
-                    0.05f * mContainerWidth, childLeft);
-        } else {
-            final int childRight = childToTest.getRight();
-            assertFuzzyEquals("Child end margin as 5% of the container",
-                    0.05f * mContainerWidth, mContainerWidth - childRight);
-        }
+        final int childLeft = childToTest.getLeft();
+        assertFuzzyEquals("Child end margin as 5% of the container",
+                0.05f * mContainerWidth, childLeft);
 
         final int childWidth = childToTest.getWidth();
         final int childHeight = childToTest.getHeight();
@@ -261,24 +234,15 @@
 
     @Test
     public void testCenterChild() {
-        if (Build.VERSION.SDK_INT == 17) {
-            return;
-        }
         final View childToTest = mPercentRelativeLayout.findViewById(R.id.child_center);
-
-        boolean supportsRtl = Build.VERSION.SDK_INT >= 17;
-        if (supportsRtl) {
-            switchToRtl();
-        }
+        switchToRtl();
 
         final int childLeft = childToTest.getLeft();
         final int childTop = childToTest.getTop();
         final int childRight = childToTest.getRight();
         final int childBottom = childToTest.getBottom();
 
-        final View leftChild = supportsRtl
-                ? mPercentRelativeLayout.findViewById(R.id.child_end)
-                : mPercentRelativeLayout.findViewById(R.id.child_start);
+        final View leftChild = mPercentRelativeLayout.findViewById(R.id.child_end);
         assertFuzzyEquals("Child left margin as 10% of the container",
                 leftChild.getRight() + 0.1f * mContainerWidth, childLeft);
 
@@ -286,9 +250,8 @@
         assertFuzzyEquals("Child top margin as 10% of the container",
                 topChild.getBottom() + 0.1f * mContainerHeight, childTop);
 
-        final View rightChild = supportsRtl
-                ? mPercentRelativeLayout.findViewById(R.id.child_start)
-                : mPercentRelativeLayout.findViewById(R.id.child_end);
+        final View rightChild = mPercentRelativeLayout.findViewById(R.id.child_start);
+
         assertFuzzyEquals("Child right margin as 10% of the container",
                 rightChild.getLeft() - 0.1f * mContainerWidth, childRight);
 
diff --git a/playground-common/gradle/wrapper/gradle-wrapper.properties b/playground-common/gradle/wrapper/gradle-wrapper.properties
index d55a029..9cac784 100644
--- a/playground-common/gradle/wrapper/gradle-wrapper.properties
+++ b/playground-common/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
-distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/print/print/src/main/java/androidx/print/PrintHelper.java b/print/print/src/main/java/androidx/print/PrintHelper.java
index 01f01f7..6a0aa14 100644
--- a/print/print/src/main/java/androidx/print/PrintHelper.java
+++ b/print/print/src/main/java/androidx/print/PrintHelper.java
@@ -155,7 +155,7 @@
      */
     public static boolean systemSupportsPrint() {
         // Supported on Android 4.4 or later.
-        return Build.VERSION.SDK_INT >= 19;
+        return true;
     }
 
     /**
@@ -233,7 +233,7 @@
      */
     public int getOrientation() {
         // Unset defaults to landscape but might turn image
-        if (Build.VERSION.SDK_INT >= 19 && mOrientation == 0) {
+        if (mOrientation == 0) {
             return ORIENTATION_LANDSCAPE;
         }
         return mOrientation;
@@ -259,7 +259,7 @@
      */
     public void printBitmap(@NonNull final String jobName, @NonNull final Bitmap bitmap,
             @Nullable final OnPrintFinishCallback callback) {
-        if (Build.VERSION.SDK_INT < 19 || bitmap == null) {
+        if (bitmap == null) {
             return;
         }
 
@@ -357,10 +357,6 @@
     public void printBitmap(@NonNull final String jobName, @NonNull final Uri imageFile,
             @Nullable final OnPrintFinishCallback callback)
             throws FileNotFoundException {
-        if (Build.VERSION.SDK_INT < 19) {
-            return;
-        }
-
         PrintDocumentAdapter printDocumentAdapter = new PrintUriAdapter(jobName, imageFile,
                 callback, mScaleMode);
 
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
index 2f31e22..1d50290 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
@@ -22,14 +22,10 @@
 import android.app.sdksandbox.SdkSandboxManager
 import android.content.Context
 import android.os.Binder
-import android.os.Build
 import android.os.Bundle
 import android.os.IBinder
 import android.os.OutcomeReceiver
-import android.os.ext.SdkExtensions.AD_SERVICES
-import androidx.annotation.RequiresExtension
 import androidx.privacysandbox.sdkruntime.client.loader.asTestSdk
-import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -39,8 +35,6 @@
 import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Assert.assertThrows
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -52,23 +46,19 @@
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.Mockito.`when`
 import org.mockito.invocation.InvocationOnMock
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 // TODO(b/249982507) Test should be rewritten to use real SDK in sandbox instead of mocking manager
-// TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-@RequiresExtension(extension = AD_SERVICES, version = 4)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+@SdkSuppress(minSdkVersion = 34)
 class SdkSandboxManagerCompatSandboxedTest {
 
     private lateinit var mContext: Context
 
     @Before
     fun setUp() {
-        assumeTrue("Requires Sandbox API available", isSandboxApiAvailable())
         mContext = Mockito.spy(ApplicationProvider.getApplicationContext<Context>())
     }
 
@@ -171,7 +161,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
     fun startSdkSandboxActivity_whenSandboxAvailable_delegateToPlatform() {
         val sdkSandboxManager = mockSandboxManager(mContext)
         val managerCompat = SdkSandboxManagerCompat.from(mContext)
@@ -222,43 +211,7 @@
     }
 
     @Test
-    fun getSandboxedSdks_whenLoadedSdkListNotAvailable_dontDelegateToSandbox() {
-        assumeFalse("Requires getSandboxedSdks API not available", isAtLeastV5())
-
-        val sdkSandboxManager = mockSandboxManager(mContext)
-        val managerCompat = SdkSandboxManagerCompat.from(mContext)
-
-        managerCompat.getSandboxedSdks()
-
-        verifyZeroInteractions(sdkSandboxManager)
-    }
-
-    @Test
-    fun getSandboxedSdks_whenLoadedSdkListNotAvailable_returnsLocallyLoadedSdkList() {
-        assumeFalse("Requires getSandboxedSdks API not available", isAtLeastV5())
-
-        // SdkSandboxManagerCompat.from require SandboxManager available for AdServices version >= 4
-        mockSandboxManager(mContext)
-        val managerCompat = SdkSandboxManagerCompat.from(mContext)
-
-        val localSdk = runBlocking {
-            managerCompat.loadSdk(
-                TestSdkConfigs.CURRENT.packageName,
-                Bundle()
-            )
-        }
-
-        val sandboxedSdks = managerCompat.getSandboxedSdks()
-
-        assertThat(sandboxedSdks).containsExactly(localSdk)
-    }
-
-    @Test
-    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-    @RequiresExtension(extension = AD_SERVICES, version = 5)
-    fun getSandboxedSdks_whenLoadedSdkListAvailable_returnCombinedLocalAndPlatformResult() {
-        assumeTrue("Requires getSandboxedSdks API available", isAtLeastV5())
-
+    fun getSandboxedSdks_whenSandboxAvailable_returnCombinedLocalAndPlatformResult() {
         val sdkSandboxManager = mockSandboxManager(mContext)
         val sandboxedSdk = SandboxedSdk(Binder())
         `when`(sdkSandboxManager.sandboxedSdks)
@@ -279,11 +232,7 @@
     }
 
     @Test
-    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-    @RequiresExtension(extension = AD_SERVICES, version = 5)
     fun sdkController_getSandboxedSdks_dontIncludeSandboxedSdk() {
-        assumeTrue("Requires getSandboxedSdks API available", isAtLeastV5())
-
         val sdkSandboxManager = mockSandboxManager(mContext)
         val sandboxedSdk = SandboxedSdk(Binder())
         `when`(sdkSandboxManager.sandboxedSdks)
@@ -306,55 +255,46 @@
         assertThat(result).isEqualTo(localSdk.getInterface())
     }
 
-    companion object SandboxApi {
+    private fun mockSandboxManager(spyContext: Context): SdkSandboxManager {
+        val sdkSandboxManager = mock(SdkSandboxManager::class.java)
+        `when`(spyContext.getSystemService(SdkSandboxManager::class.java))
+            .thenReturn(sdkSandboxManager)
+        return sdkSandboxManager
+    }
 
-        private fun isSandboxApiAvailable() =
-            AdServicesInfo.isAtLeastV4()
-
-        private fun isAtLeastV5() =
-            AdServicesInfo.isAtLeastV5()
-
-        private fun mockSandboxManager(spyContext: Context): SdkSandboxManager {
-            val sdkSandboxManager = mock(SdkSandboxManager::class.java)
-            `when`(spyContext.getSystemService(SdkSandboxManager::class.java))
-                .thenReturn(sdkSandboxManager)
-            return sdkSandboxManager
+    private fun setupLoadSdkAnswer(
+        sdkSandboxManager: SdkSandboxManager,
+        sandboxedSdk: SandboxedSdk
+    ) {
+        val answer = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
+            receiver.onResult(sandboxedSdk)
+            null
         }
+        doAnswer(answer)
+            .`when`(sdkSandboxManager).loadSdk(
+                any(),
+                any(),
+                any(),
+                any()
+            )
+    }
 
-        private fun setupLoadSdkAnswer(
-            sdkSandboxManager: SdkSandboxManager,
-            sandboxedSdk: SandboxedSdk
-        ) {
-            val answer = { args: InvocationOnMock ->
-                val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
-                receiver.onResult(sandboxedSdk)
-                null
-            }
-            doAnswer(answer)
-                .`when`(sdkSandboxManager).loadSdk(
-                    any(),
-                    any(),
-                    any(),
-                    any()
-                )
+    private fun setupLoadSdkAnswer(
+        sdkSandboxManager: SdkSandboxManager,
+        loadSdkException: LoadSdkException
+    ) {
+        val answer = { args: InvocationOnMock ->
+            val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
+            receiver.onError(loadSdkException)
+            null
         }
-
-        private fun setupLoadSdkAnswer(
-            sdkSandboxManager: SdkSandboxManager,
-            loadSdkException: LoadSdkException
-        ) {
-            val answer = { args: InvocationOnMock ->
-                val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
-                receiver.onError(loadSdkException)
-                null
-            }
-            doAnswer(answer)
-                .`when`(sdkSandboxManager).loadSdk(
-                    any(),
-                    any(),
-                    any(),
-                    any()
-                )
-        }
+        doAnswer(answer)
+            .`when`(sdkSandboxManager).loadSdk(
+                any(),
+                any(),
+                any(),
+                any()
+            )
     }
 }
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
index 5ee872d..81d35cf 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
@@ -15,18 +15,15 @@
  */
 package androidx.privacysandbox.sdkruntime.client
 
-import android.app.Activity
 import android.content.Context
 import android.content.ContextWrapper
 import android.os.Binder
-import android.os.Build
 import android.os.Bundle
 import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
 import androidx.privacysandbox.sdkruntime.client.activity.SdkActivity
 import androidx.privacysandbox.sdkruntime.client.loader.CatchingSdkActivityHandler
 import androidx.privacysandbox.sdkruntime.client.loader.asTestSdk
 import androidx.privacysandbox.sdkruntime.client.loader.extractSdkProviderFieldValue
-import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_INTERNAL_ERROR
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_SDK_DEFINED_ERROR
@@ -41,13 +38,8 @@
 import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Assert.assertThrows
-import org.junit.Assume.assumeTrue
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mockito
-import org.mockito.Mockito.any
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.verify
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -80,29 +72,8 @@
     }
 
     @Test
-    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
-    fun loadSdk_whenNoLocalSdkExistsAndSandboxNotAvailable_dontDelegateToSandbox() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
-        val managerCompat = SdkSandboxManagerCompat.from(context)
-
-        assertThrows(LoadSdkCompatException::class.java) {
-            runBlocking {
-                managerCompat.loadSdk("sdk-not-exists", Bundle())
-            }
-        }
-
-        verify(context, Mockito.never()).getSystemService(any())
-    }
-
-    @Test
-    fun loadSdk_whenNoLocalSdkExistsAndSandboxNotAvailable_throwsSdkNotFoundException() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
+    @SdkSuppress(maxSdkVersion = 33)
+    fun loadSdk_whenNoLocalSdkExistsAndApiBelow34_throwsSdkNotFoundException() {
         val context = ApplicationProvider.getApplicationContext<Context>()
         val managerCompat = SdkSandboxManagerCompat.from(context)
 
@@ -203,18 +174,11 @@
     }
 
     @Test
-    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
-    fun unloadSdk_whenNoLocalSdkLoadedAndSandboxNotAvailable_dontDelegateToSandbox() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+    @SdkSuppress(maxSdkVersion = 33)
+    fun unloadSdk_whenNoLocalSdkLoadedAndApiBelow34_doesntThrow() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
         val managerCompat = SdkSandboxManagerCompat.from(context)
-
         managerCompat.unloadSdk("sdk-not-loaded")
-
-        verify(context, Mockito.never()).getSystemService(any())
     }
 
     @Test
@@ -268,13 +232,9 @@
     }
 
     @Test
-    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
-    fun addSdkSandboxProcessDeathCallback_whenSandboxNotAvailable_dontDelegateToSandbox() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+    @SdkSuppress(maxSdkVersion = 33)
+    fun addSdkSandboxProcessDeathCallback_whenApiBelow34_doesntThrow() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
         val managerCompat = SdkSandboxManagerCompat.from(context)
 
         managerCompat.addSdkSandboxProcessDeathCallback(Runnable::run, object :
@@ -282,18 +242,12 @@
             override fun onSdkSandboxDied() {
             }
         })
-
-        verify(context, Mockito.never()).getSystemService(any())
     }
 
     @Test
-    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
-    fun removeSdkSandboxProcessDeathCallback_whenSandboxNotAvailable_dontDelegateToSandbox() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+    @SdkSuppress(maxSdkVersion = 33)
+    fun removeSdkSandboxProcessDeathCallback_whenApiBelow34_doesntThrow() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
         val managerCompat = SdkSandboxManagerCompat.from(context)
 
         managerCompat.removeSdkSandboxProcessDeathCallback(object :
@@ -301,39 +255,37 @@
             override fun onSdkSandboxDied() {
             }
         })
-
-        verify(context, Mockito.never()).getSystemService(any())
     }
 
     @Test
-    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
-    fun getSandboxedSdks_whenSandboxNotAvailable_dontDelegateToSandbox() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+    @SdkSuppress(maxSdkVersion = 33)
+    fun getSandboxedSdks_whenApiBelow34_returnsLocallyLoadedSdkList() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
         val managerCompat = SdkSandboxManagerCompat.from(context)
 
-        managerCompat.getSandboxedSdks()
+        val localSdk = runBlocking {
+            managerCompat.loadSdk(
+                TestSdkConfigs.CURRENT.packageName,
+                Bundle()
+            )
+        }
 
-        verify(context, Mockito.never()).getSystemService(any())
+        val sandboxedSdks = managerCompat.getSandboxedSdks()
+
+        assertThat(sandboxedSdks).containsExactly(localSdk)
     }
 
     @Test
-    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
-    fun startSdkSandboxActivity_whenSandboxNotAvailable_dontDelegateToSandbox() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+    @SdkSuppress(maxSdkVersion = 33)
+    fun startSdkSandboxActivity_whenNoHandlerRegisteredAndApiBelow34_doesntThrow() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
         val managerCompat = SdkSandboxManagerCompat.from(context)
 
-        val fromActivitySpy = Mockito.mock(Activity::class.java)
-        managerCompat.startSdkSandboxActivity(fromActivitySpy, Binder())
-
-        verify(context, Mockito.never()).getSystemService(any())
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                managerCompat.startSdkSandboxActivity(this, Binder())
+            }
+        }
     }
 
     @Test
@@ -392,27 +344,4 @@
             anotherLocalSdk.getInterface(),
         )
     }
-
-    @Test
-    fun getSandboxedSdks_whenSandboxNotAvailable_returnsLocallyLoadedSdkList() {
-        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
-        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
-        val context = ApplicationProvider.getApplicationContext<Context>()
-        val managerCompat = SdkSandboxManagerCompat.from(context)
-
-        val localSdk = runBlocking {
-            managerCompat.loadSdk(
-                TestSdkConfigs.CURRENT.packageName,
-                Bundle()
-            )
-        }
-
-        val sandboxedSdks = managerCompat.getSandboxedSdks()
-
-        assertThat(sandboxedSdks).containsExactly(localSdk)
-    }
-
-    private fun isSandboxApiNotAvailable() =
-        !AdServicesInfo.isAtLeastV4()
 }
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
index 7fdaba7..c7e868f 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
@@ -319,6 +319,10 @@
         var sdkActivityHandlers: MutableMap<IBinder, SdkSandboxActivityHandlerCompat> =
             mutableMapOf()
 
+        override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+            throw UnsupportedOperationException("Shouldn't be called")
+        }
+
         override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
             return sandboxedSdksResult
         }
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
index 41bea2f..ee66f50 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
@@ -17,6 +17,7 @@
 
 import android.content.Context
 import android.os.Build
+import android.os.Bundle
 import android.os.IBinder
 import androidx.privacysandbox.sdkruntime.client.TestSdkConfigs
 import androidx.privacysandbox.sdkruntime.client.config.LocalSdkConfig
@@ -158,6 +159,11 @@
     }
 
     private class NoOpImpl : SdkSandboxControllerCompat.SandboxControllerImpl {
+
+        override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+            throw UnsupportedOperationException("NoOp")
+        }
+
         override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
             throw UnsupportedOperationException("NoOp")
         }
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
index a3f2e01..59ee471 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
@@ -24,10 +24,8 @@
 import android.os.Build
 import android.os.Bundle
 import android.os.IBinder
-import android.os.ext.SdkExtensions.AD_SERVICES
 import androidx.annotation.DoNotInline
 import androidx.annotation.RequiresApi
-import androidx.annotation.RequiresExtension
 import androidx.core.os.BuildCompat
 import androidx.core.os.asOutcomeReceiver
 import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
@@ -290,14 +288,14 @@
         )
 
         @DoNotInline
-        fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
+        fun getSandboxedSdks(): List<SandboxedSdkCompat>
 
         fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder)
     }
 
-    @RequiresApi(33)
-    @RequiresExtension(extension = AD_SERVICES, version = 4)
-    private open class ApiAdServicesV4Impl(context: Context) : PlatformApi {
+    @RequiresApi(34)
+    @SuppressLint("NewApi", "ClassVerificationFailure") // until updating checks to requires api 34
+    private open class Api34Impl(context: Context) : PlatformApi {
         protected val sdkSandboxManager = context.getSystemService(
             SdkSandboxManager::class.java
         )
@@ -322,6 +320,12 @@
             sdkSandboxManager.unloadSdk(sdkName)
         }
 
+        override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
+            return sdkSandboxManager
+                .sandboxedSdks
+                .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
+        }
+
         @DoNotInline
         override fun addSdkSandboxProcessDeathCallback(
             callbackExecutor: Executor,
@@ -350,9 +354,7 @@
         }
 
         override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
-            throw UnsupportedOperationException(
-                "This API is only supported for devices run on Android U+"
-            )
+            sdkSandboxManager.startSdkSandboxActivity(fromActivity, sdkActivityToken)
         }
 
         private suspend fun loadSdkInternal(
@@ -379,29 +381,6 @@
         }
     }
 
-    @RequiresApi(33)
-    @RequiresExtension(extension = AD_SERVICES, version = 5)
-    private open class ApiAdServicesV5Impl(
-        context: Context
-    ) : ApiAdServicesV4Impl(context) {
-        @DoNotInline
-        override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
-            return sdkSandboxManager
-                .sandboxedSdks
-                .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
-        }
-    }
-
-    @RequiresExtension(extension = AD_SERVICES, version = 5)
-    @RequiresApi(34)
-    private class ApiAdServicesUDCImpl(
-        context: Context
-    ) : ApiAdServicesV5Impl(context) {
-        override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
-            sdkSandboxManager.startSdkSandboxActivity(fromActivity, sdkActivityToken)
-        }
-    }
-
     private class FailImpl : PlatformApi {
         @DoNotInline
         override suspend fun loadSdk(
@@ -414,6 +393,8 @@
         override fun unloadSdk(sdkName: String) {
         }
 
+        override fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
+
         override fun addSdkSandboxProcessDeathCallback(
             callbackExecutor: Executor,
             callback: SdkSandboxProcessDeathCallbackCompat
@@ -474,14 +455,9 @@
     }
 
     private object PlatformApiFactory {
-        @SuppressLint("NewApi", "ClassVerificationFailure")
         fun create(context: Context): PlatformApi {
             return if (Build.VERSION.SDK_INT >= 34 || AdServicesInfo.isDeveloperPreview()) {
-                ApiAdServicesUDCImpl(context)
-            } else if (AdServicesInfo.isAtLeastV5()) {
-                ApiAdServicesV5Impl(context)
-            } else if (AdServicesInfo.isAtLeastV4()) {
-                ApiAdServicesV4Impl(context)
+                Api34Impl(context)
             } else {
                 FailImpl()
             }
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
index c079804..eb195d6 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
@@ -16,6 +16,7 @@
 
 package androidx.privacysandbox.sdkruntime.client.controller
 
+import android.os.Bundle
 import android.os.IBinder
 import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
 import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
@@ -31,6 +32,9 @@
     private val locallyLoadedSdks: LocallyLoadedSdks,
     private val appOwnedSdkRegistry: AppOwnedSdkRegistry
 ) : SdkSandboxControllerCompat.SandboxControllerImpl {
+    override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+        throw UnsupportedOperationException("Shouldn't be called")
+    }
 
     override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
         return locallyLoadedSdks.getLoadedSdks()
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt b/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt
index e6d4a83..73911a2 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt
@@ -40,12 +40,6 @@
     property public final long version;
   }
 
-  @Deprecated @RequiresExtension(extension=android.os.ext.SdkExtensions.AD_SERVICES, version=4) public final class SandboxedSdkProviderAdapter extends android.app.sdksandbox.SandboxedSdkProvider {
-    ctor @Deprecated public SandboxedSdkProviderAdapter();
-    method @Deprecated public android.view.View getView(android.content.Context windowContext, android.os.Bundle params, int width, int height);
-    method @Deprecated @kotlin.jvm.Throws(exceptionClasses=LoadSdkException::class) public android.app.sdksandbox.SandboxedSdk onLoadSdk(android.os.Bundle params) throws android.app.sdksandbox.LoadSdkException;
-  }
-
   public abstract class SandboxedSdkProviderCompat {
     ctor public SandboxedSdkProviderCompat();
     method public final void attachContext(android.content.Context context);
@@ -77,6 +71,7 @@
     method public static androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat from(android.content.Context context);
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat> getAppOwnedSdkSandboxInterfaces();
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat> getSandboxedSdks();
+    method public suspend Object? loadSdk(String sdkName, android.os.Bundle params, kotlin.coroutines.Continuation<? super androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat>);
     method public android.os.IBinder registerSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
     method public void unregisterSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
     field public static final androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat.Companion Companion;
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt b/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt
index e6d4a83..73911a2 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt
@@ -40,12 +40,6 @@
     property public final long version;
   }
 
-  @Deprecated @RequiresExtension(extension=android.os.ext.SdkExtensions.AD_SERVICES, version=4) public final class SandboxedSdkProviderAdapter extends android.app.sdksandbox.SandboxedSdkProvider {
-    ctor @Deprecated public SandboxedSdkProviderAdapter();
-    method @Deprecated public android.view.View getView(android.content.Context windowContext, android.os.Bundle params, int width, int height);
-    method @Deprecated @kotlin.jvm.Throws(exceptionClasses=LoadSdkException::class) public android.app.sdksandbox.SandboxedSdk onLoadSdk(android.os.Bundle params) throws android.app.sdksandbox.LoadSdkException;
-  }
-
   public abstract class SandboxedSdkProviderCompat {
     ctor public SandboxedSdkProviderCompat();
     method public final void attachContext(android.content.Context context);
@@ -77,6 +71,7 @@
     method public static androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat from(android.content.Context context);
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat> getAppOwnedSdkSandboxInterfaces();
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat> getSandboxedSdks();
+    method public suspend Object? loadSdk(String sdkName, android.os.Bundle params, kotlin.coroutines.Continuation<? super androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat>);
     method public android.os.IBinder registerSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
     method public void unregisterSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
     field public static final androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat.Companion Companion;
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/assets/SandboxedSdkProviderCompatClassName.txt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/assets/SandboxedSdkProviderCompatClassName.txt
deleted file mode 100644
index 3d062e4..0000000
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/assets/SandboxedSdkProviderCompatClassName.txt
+++ /dev/null
@@ -1 +0,0 @@
-androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderAdapterTest$TestOnLoadReturnResultSdkProvider
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapterTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapterTest.kt
deleted file mode 100644
index ba919c3..0000000
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapterTest.kt
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright 2022 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.privacysandbox.sdkruntime.core
-
-import android.app.sdksandbox.LoadSdkException
-import android.content.Context
-import android.os.Binder
-import android.os.Build.VERSION_CODES.TIRAMISU
-import android.os.Bundle
-import android.os.ext.SdkExtensions.AD_SERVICES
-import android.view.View
-import androidx.annotation.RequiresExtension
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SdkSuppress
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import kotlin.reflect.KClass
-import org.junit.Assert.assertThrows
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.mock
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-// TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-@RequiresExtension(extension = AD_SERVICES, version = 4)
-@SdkSuppress(minSdkVersion = TIRAMISU)
-@Suppress("DEPRECATION")
-class SandboxedSdkProviderAdapterTest {
-
-    private lateinit var context: Context
-
-    @Before
-    fun setUp() {
-        assumeTrue("Requires Sandbox API available", isSandboxApiAvailable())
-        context = ApplicationProvider.getApplicationContext()
-    }
-
-    @Test
-    fun testAdapterGetCompatClassNameFromAsset() {
-        val expectedClassName = context.assets
-            .open("SandboxedSdkProviderCompatClassName.txt")
-            .use { inputStream ->
-                inputStream.bufferedReader().readLine()
-            }
-
-        val adapter = SandboxedSdkProviderAdapter()
-        adapter.attachContext(context)
-
-        adapter.onLoadSdk(Bundle())
-
-        val delegate = adapter.extractDelegate<SandboxedSdkProviderCompat>()
-        assertThat(delegate.javaClass.name)
-            .isEqualTo(expectedClassName)
-    }
-
-    @Test
-    fun onLoadSdk_shouldInstantiateDelegateAndAttachContext() {
-        val adapter = createAdapterFor(TestOnLoadReturnResultSdkProvider::class)
-
-        adapter.onLoadSdk(Bundle())
-
-        val delegate = adapter.extractDelegate<TestOnLoadReturnResultSdkProvider>()
-        assertThat(delegate.context)
-            .isSameInstanceAs(context)
-    }
-
-    @Test
-    fun onLoadSdk_shouldDelegateToCompatClassAndReturnResult() {
-        val adapter = createAdapterFor(TestOnLoadReturnResultSdkProvider::class)
-        val params = Bundle()
-
-        val result = adapter.onLoadSdk(params)
-
-        val delegate = adapter.extractDelegate<TestOnLoadReturnResultSdkProvider>()
-        assertThat(delegate.mLastOnLoadSdkBundle)
-            .isSameInstanceAs(params)
-        assertThat(result.getInterface())
-            .isEqualTo(delegate.mResult.getInterface())
-    }
-
-    @Test
-    fun loadSdk_shouldRethrowExceptionFromCompatClass() {
-        val adapter = createAdapterFor(TestOnLoadThrowSdkProvider::class)
-
-        val ex = assertThrows(LoadSdkException::class.java) {
-            adapter.onLoadSdk(Bundle())
-        }
-
-        val delegate = adapter.extractDelegate<TestOnLoadThrowSdkProvider>()
-        assertThat(ex.cause)
-            .isSameInstanceAs(delegate.mError.cause)
-        assertThat(ex.extraInformation)
-            .isSameInstanceAs(delegate.mError.extraInformation)
-    }
-
-    @Test
-    fun loadSdk_shouldThrowIfCompatClassNotExists() {
-        val adapter = createAdapterFor("NOTEXISTS")
-
-        assertThrows(ClassNotFoundException::class.java) {
-            adapter.onLoadSdk(Bundle())
-        }
-    }
-
-    @Test
-    fun beforeUnloadSdk_shouldDelegateToCompatProvider() {
-        val adapter = createAdapterFor(TestOnBeforeUnloadDelegateSdkProvider::class)
-
-        adapter.beforeUnloadSdk()
-
-        val delegate = adapter.extractDelegate<TestOnBeforeUnloadDelegateSdkProvider>()
-        assertThat(delegate.mBeforeUnloadSdkCalled)
-            .isTrue()
-    }
-
-    @Test
-    fun getView_shouldDelegateToCompatProviderAndReturnResult() {
-        val adapter = createAdapterFor(TestGetViewSdkProvider::class)
-        val windowContext = mock(Context::class.java)
-        val params = Bundle()
-        val width = 1
-        val height = 2
-
-        val result = adapter.getView(windowContext, params, width, height)
-
-        val delegate = adapter.extractDelegate<TestGetViewSdkProvider>()
-        assertThat(result)
-            .isSameInstanceAs(delegate.mView)
-        assertThat(delegate.mLastWindowContext)
-            .isSameInstanceAs(windowContext)
-        assertThat(delegate.mLastParams)
-            .isSameInstanceAs(params)
-        assertThat(delegate.mLastWidth)
-            .isSameInstanceAs(width)
-        assertThat(delegate.mLastHeigh)
-            .isSameInstanceAs(height)
-    }
-
-    private fun createAdapterFor(
-        clazz: KClass<out SandboxedSdkProviderCompat>
-    ): SandboxedSdkProviderAdapter = createAdapterFor(clazz.java.name)
-
-    private fun createAdapterFor(delegateClassName: String): SandboxedSdkProviderAdapter {
-        val adapter = SandboxedSdkProviderAdapter(
-            object : SandboxedSdkProviderAdapter.CompatClassNameProvider {
-                override fun getCompatProviderClassName(context: Context): String {
-                    return delegateClassName
-                }
-            })
-        adapter.attachContext(context)
-        return adapter
-    }
-
-    private inline fun <reified T : SandboxedSdkProviderCompat>
-        SandboxedSdkProviderAdapter.extractDelegate(): T = delegate as T
-
-    class TestOnLoadReturnResultSdkProvider : SandboxedSdkProviderCompat() {
-        var mResult = SandboxedSdkCompat(Binder())
-        var mLastOnLoadSdkBundle: Bundle? = null
-
-        override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
-            mLastOnLoadSdkBundle = params
-            return mResult
-        }
-
-        override fun getView(
-            windowContext: Context,
-            params: Bundle,
-            width: Int,
-            height: Int
-        ): View {
-            throw RuntimeException("Not implemented")
-        }
-    }
-
-    class TestOnLoadThrowSdkProvider : SandboxedSdkProviderCompat() {
-        var mError = LoadSdkCompatException(RuntimeException(), Bundle())
-
-        @Throws(LoadSdkCompatException::class)
-        override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
-            throw mError
-        }
-
-        override fun getView(
-            windowContext: Context,
-            params: Bundle,
-            width: Int,
-            height: Int
-        ): View {
-            throw RuntimeException("Stub!")
-        }
-    }
-
-    class TestOnBeforeUnloadDelegateSdkProvider : SandboxedSdkProviderCompat() {
-        var mBeforeUnloadSdkCalled = false
-
-        override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
-            throw RuntimeException("Not implemented")
-        }
-
-        override fun beforeUnloadSdk() {
-            mBeforeUnloadSdkCalled = true
-        }
-
-        override fun getView(
-            windowContext: Context,
-            params: Bundle,
-            width: Int,
-            height: Int
-        ): View {
-            throw RuntimeException("Not implemented")
-        }
-    }
-
-    class TestGetViewSdkProvider : SandboxedSdkProviderCompat() {
-        val mView: View = mock(View::class.java)
-
-        var mLastWindowContext: Context? = null
-        var mLastParams: Bundle? = null
-        var mLastWidth = 0
-        var mLastHeigh = 0
-
-        override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
-            throw RuntimeException("Not implemented")
-        }
-
-        override fun getView(
-            windowContext: Context,
-            params: Bundle,
-            width: Int,
-            height: Int
-        ): View {
-            mLastWindowContext = windowContext
-            mLastParams = params
-            mLastWidth = width
-            mLastHeigh = height
-
-            return mView
-        }
-    }
-
-    private fun isSandboxApiAvailable() =
-        AdServicesInfo.isAtLeastV4()
-}
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt
index c7cc743d..6e1b54f 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt
@@ -20,7 +20,6 @@
 import android.app.sdksandbox.sdkprovider.SdkSandboxController
 import android.content.Context
 import android.os.Binder
-import android.os.Build
 import android.os.ext.SdkExtensions
 import androidx.annotation.RequiresExtension
 import androidx.core.os.BuildCompat
@@ -39,31 +38,11 @@
 import org.mockito.Mockito.`when`
 
 // TODO(b/249982507) Rewrite test to use real SDK in sandbox instead of mocking controller
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+@SdkSuppress(minSdkVersion = 34)
 class SdkSandboxControllerAppOwnedInterfacesTest {
 
     @Test
-    fun getAppOwnedSdkSandboxInterfaces_whenControllerNotAvailable_returnsEmptyList() {
-        assumeFalse(
-            "Requires SandboxController not available",
-            isSandboxControllerAvailable()
-        )
-
-        val context = ApplicationProvider.getApplicationContext<Context>()
-        val controllerCompat = SdkSandboxControllerCompat.from(context)
-
-        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
-        assertThat(appOwnedInterfaces).isEmpty()
-    }
-
-    @Test
-    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
     fun getAppOwnedSdkSandboxInterfaces_whenApiNotAvailable_returnsEmptyList() {
-        assumeTrue(
-            "Requires SandboxController available",
-            isSandboxControllerAvailable()
-        )
         assumeFalse(
             "Requires AppOwnedInterfaces API not available",
             isAppOwnedInterfacesApiAvailable()
@@ -83,7 +62,7 @@
 
     @Test
     @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 8)
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @SdkSuppress(minSdkVersion = 34)
     fun getAppOwnedSdkSandboxInterfaces_whenApiAvailable_delegateToPlatform() {
         assumeTrue(
             "Requires AppOwnedInterfaces API available",
@@ -112,9 +91,6 @@
         assertThat(resultObj.getInterface()).isEqualTo(expectedObj.getInterface())
     }
 
-    private fun isSandboxControllerAvailable() =
-        AdServicesInfo.isAtLeastV5()
-
     private fun isAppOwnedInterfacesApiAvailable() =
         BuildCompat.AD_SERVICES_EXTENSION_INT >= 8 || AdServicesInfo.isDeveloperPreview()
 
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
index 7cbf999..d815735 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
@@ -18,8 +18,10 @@
 
 import android.content.Context
 import android.os.Binder
+import android.os.Bundle
 import android.os.IBinder
 import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
 import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
@@ -28,6 +30,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Assert
 import org.junit.Before
@@ -56,6 +59,29 @@
     }
 
     @Test
+    fun loadSdk_withoutLocalImpl_throwsLoadSdkCompatException() {
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        Assert.assertThrows(LoadSdkCompatException::class.java) {
+            runBlocking {
+                controllerCompat.loadSdk("SDK", Bundle())
+            }
+        }
+    }
+
+    @Test
+    fun loadSdk_withLocalImpl_throwsLoadSdkCompatException() {
+        SdkSandboxControllerCompat.injectLocalImpl(TestStubImpl())
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        Assert.assertThrows(LoadSdkCompatException::class.java) {
+            runBlocking {
+                controllerCompat.loadSdk("SDK", Bundle())
+            }
+        }
+    }
+
+    @Test
     fun getSandboxedSdks_withoutLocalImpl_returnsEmptyList() {
         val controllerCompat = SdkSandboxControllerCompat.from(context)
         val sandboxedSdks = controllerCompat.getSandboxedSdks()
@@ -193,6 +219,11 @@
         private val appOwnedSdks: List<AppOwnedSdkSandboxInterfaceCompat> = emptyList()
     ) : SdkSandboxControllerCompat.SandboxControllerImpl {
         var token: IBinder? = null
+
+        override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+            throw UnsupportedOperationException("Shouldn't be called")
+        }
+
         override fun getSandboxedSdks() = sandboxedSdks
         override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
             appOwnedSdks
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt
index 48748c6f..c8a0ba0f 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt
@@ -23,83 +23,58 @@
 import android.app.sdksandbox.sdkprovider.SdkSandboxController
 import android.content.Context
 import android.os.Binder
-import android.os.Build
 import android.os.Bundle
-import android.os.ext.SdkExtensions
 import android.window.OnBackInvokedDispatcher
-import androidx.annotation.RequiresExtension
 import androidx.lifecycle.Lifecycle
-import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.SdkSuppress
 import androidx.test.internal.runner.junit4.statement.UiThreadStatement
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
 import org.junit.Assert
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
 import org.junit.Test
 import org.mockito.ArgumentCaptor
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.Mockito.`when`
 
 // TODO(b/249982507) Rewrite test to use real SDK in sandbox instead of mocking controller
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
 class SdkSandboxControllerCompatSandboxedTest {
 
     @Test
-    fun controllerAPIs_whenApiNotAvailable_notDelegateToSandbox() {
-        assumeFalse(
-            "Requires SandboxController API not available",
-            isSandboxControllerAvailable()
-        )
-
-        val context = spy(ApplicationProvider.getApplicationContext<Context>())
-        val controllerCompat = SdkSandboxControllerCompat.from(context)
-
-        controllerCompat.getSandboxedSdks()
-        val handlerCompat = object : SdkSandboxActivityHandlerCompat {
-            override fun onActivityCreated(activityHolder: ActivityHolder) {}
-        }
-        Assert.assertThrows(UnsupportedOperationException::class.java) {
-            controllerCompat.registerSdkSandboxActivityHandler(handlerCompat)
-        }
-        Assert.assertThrows(UnsupportedOperationException::class.java) {
-            controllerCompat.unregisterSdkSandboxActivityHandler(handlerCompat)
-        }
-        verifyZeroInteractions(context)
-    }
-
-    @Test
-    fun getSandboxedSdks_whenApiNotAvailable_returnsEmptyList() {
-        assumeFalse(
-            "Requires SandboxController API not available",
-            isSandboxControllerAvailable()
-        )
-
+    @SdkSuppress(maxSdkVersion = 33)
+    fun from_whenApiBelow34_throwUnsupportedOperationException() {
         val context = ApplicationProvider.getApplicationContext<Context>()
-        val controllerCompat = SdkSandboxControllerCompat.from(context)
-
-        val sandboxedSdks = controllerCompat.getSandboxedSdks()
-
-        assertThat(sandboxedSdks).isEmpty()
+        Assert.assertThrows(UnsupportedOperationException::class.java) {
+            SdkSandboxControllerCompat.from(context)
+        }
     }
 
     @Test
-    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
-    fun getSandboxedSdks_whenApiAvailable_returnsListFromPlatformApi() {
-        assumeTrue(
-            "Requires SandboxController API available",
-            isSandboxControllerAvailable()
-        )
+    @SdkSuppress(minSdkVersion = 34)
+    fun loadSdk_withoutLocalImpl_throwsLoadSdkCompatException() {
+        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+        val sdkSandboxController = mock(SdkSandboxController::class.java)
+        doReturn(sdkSandboxController)
+            .`when`(context).getSystemService(SdkSandboxController::class.java)
 
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        Assert.assertThrows(LoadSdkCompatException::class.java) {
+            runBlocking {
+                controllerCompat.loadSdk("SDK", Bundle())
+            }
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 34)
+    fun getSandboxedSdks_withoutLocalImpl_returnsListFromPlatformApi() {
         val context = spy(ApplicationProvider.getApplicationContext<Context>())
         val sdkSandboxController = mock(SdkSandboxController::class.java)
         doReturn(sdkSandboxController)
@@ -118,10 +93,8 @@
     }
 
     @Test
-    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
-    fun registerSdkSandboxHandlerCompat_whenApiAvailable_registerItToPlatform() {
+    @SdkSuppress(minSdkVersion = 34)
+    fun registerSdkSandboxHandlerCompat_withoutLocalImpl_registerItToPlatform() {
         val context = spy(ApplicationProvider.getApplicationContext<Context>())
         val sdkSandboxController = mock(SdkSandboxController::class.java)
         doReturn(sdkSandboxController)
@@ -192,10 +165,8 @@
     }
 
     @Test
-    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
-    fun unregisterSdkSandboxHandlerCompat_whenApiAvailable_unregisterItToPlatform() {
+    @SdkSuppress(minSdkVersion = 34)
+    fun unregisterSdkSandboxHandlerCompat_withoutLocalImpl_unregisterItToPlatform() {
         val context = spy(ApplicationProvider.getApplicationContext<Context>())
         val sdkSandboxController = mock(SdkSandboxController::class.java)
         doReturn(sdkSandboxController)
@@ -223,9 +194,6 @@
         assertThat(unregisteredHandlerCaptor.value).isEqualTo(registeredHandlerCaptor.value)
     }
 
-    private fun isSandboxControllerAvailable() =
-        AdServicesInfo.isAtLeastV5()
-
     // To capture non null arguments.
 
     private fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapter.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapter.kt
index e62fc1d..24771d7 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapter.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/SandboxedSdkProviderAdapter.kt
@@ -23,7 +23,9 @@
 import android.os.Bundle
 import android.os.ext.SdkExtensions.AD_SERVICES
 import android.view.View
+import androidx.annotation.RequiresApi
 import androidx.annotation.RequiresExtension
+import androidx.annotation.RestrictTo
 
 /**
  * Implementation of platform [SandboxedSdkProvider] that delegate to [SandboxedSdkProviderCompat]
@@ -31,6 +33,7 @@
  *
  */
 @SuppressLint("Override") // b/273473397
+@RequiresApi(34)
 @RequiresExtension(extension = AD_SERVICES, version = 4)
 // TODO(b/301437557) Remove after documentation migration to sdkruntime-provider
 @Deprecated(
@@ -38,8 +41,10 @@
     replaceWith = ReplaceWith(
         expression = "SandboxedSdkProviderAdapter",
         imports = arrayOf("androidx.privacysandbox.sdkruntime.provider.SandboxedSdkProviderAdapter")
-    )
+    ),
+    level = DeprecationLevel.HIDDEN
 )
+@RestrictTo(RestrictTo.Scope.LIBRARY) // removing from public API surface
 class SandboxedSdkProviderAdapter internal constructor(
     private val classNameProvider: CompatClassNameProvider
 ) : SandboxedSdkProvider() {
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
index a446171..3d1a408 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
@@ -19,19 +19,20 @@
 import android.app.sdksandbox.sdkprovider.SdkSandboxController
 import android.content.Context
 import android.os.Build
+import android.os.Bundle
 import android.os.IBinder
 import androidx.annotation.Keep
 import androidx.annotation.RestrictTo
 import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
 import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
 import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.impl.LocalImpl
 import androidx.privacysandbox.sdkruntime.core.controller.impl.NoOpImpl
-import androidx.privacysandbox.sdkruntime.core.controller.impl.PlatformImpl
 import androidx.privacysandbox.sdkruntime.core.controller.impl.PlatformUDCImpl
 import org.jetbrains.annotations.TestOnly
 
@@ -54,6 +55,20 @@
 ) {
 
     /**
+     * Load SDK in a SDK sandbox java process or locally.
+     *
+     * The caller may only load SDKs the client app depends on into the SDK sandbox.
+     *
+     * @param sdkName name of the SDK to be loaded.
+     * @param params additional parameters to be passed to the SDK in the form of a [Bundle]
+     *  as agreed between the client and the SDK.
+     * @return [SandboxedSdkCompat] from SDK on a successful run.
+     * @throws [LoadSdkCompatException] on fail.
+     */
+    suspend fun loadSdk(sdkName: String, params: Bundle) =
+        controllerImpl.loadSdk(sdkName, params)
+
+    /**
      * Fetches information about Sdks that are loaded in the sandbox or locally.
      *
      * @return List of [SandboxedSdkCompat] containing all currently loaded sdks
@@ -102,6 +117,9 @@
 
     @RestrictTo(LIBRARY_GROUP)
     interface SandboxControllerImpl {
+
+        suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat
+
         fun getSandboxedSdks(): List<SandboxedSdkCompat>
 
         fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat>
@@ -162,13 +180,10 @@
 
     private object PlatformImplFactory {
         fun create(context: Context): SandboxControllerImpl {
-            if (AdServicesInfo.isAtLeastV5()) {
-                if (Build.VERSION.SDK_INT >= 34 || AdServicesInfo.isDeveloperPreview()) {
-                    return PlatformUDCImpl.from(context)
-                }
-                return PlatformImpl.from(context)
+            if (Build.VERSION.SDK_INT >= 34 || AdServicesInfo.isDeveloperPreview()) {
+                return PlatformUDCImpl.from(context)
             }
-            return NoOpImpl()
+            throw UnsupportedOperationException("SDK should be loaded locally on API below 34")
         }
     }
 }
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
index 2c8beda..f7c1f54 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
@@ -16,8 +16,11 @@
 
 package androidx.privacysandbox.sdkruntime.core.controller.impl
 
+import android.os.Bundle
 import android.os.IBinder
 import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_NOT_FOUND
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
@@ -30,6 +33,14 @@
     private val implFromClient: SdkSandboxControllerCompat.SandboxControllerImpl,
     private val clientVersion: Int
 ) : SdkSandboxControllerCompat.SandboxControllerImpl {
+
+    override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+        throw LoadSdkCompatException(
+            LOAD_SDK_NOT_FOUND,
+            "Not supported for locally loaded SDKs yet"
+        )
+    }
+
     override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
         return implFromClient.getSandboxedSdks()
     }
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
index ab53064..6e0727d 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
@@ -16,8 +16,10 @@
 
 package androidx.privacysandbox.sdkruntime.core.controller.impl
 
+import android.os.Bundle
 import android.os.IBinder
 import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
@@ -26,6 +28,14 @@
  * NoOp implementation for cases when [SdkSandboxControllerCompat] not supported.
  */
 internal class NoOpImpl : SdkSandboxControllerCompat.SandboxControllerImpl {
+
+    override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+        throw LoadSdkCompatException(
+            LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
+            "Loading SDK not supported on this device"
+        )
+    }
+
     override fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
 
     override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt
deleted file mode 100644
index 7b487ec..0000000
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt
+++ /dev/null
@@ -1,68 +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.privacysandbox.sdkruntime.core.controller.impl
-
-import android.app.sdksandbox.sdkprovider.SdkSandboxController
-import android.content.Context
-import android.os.IBinder
-import android.os.ext.SdkExtensions.AD_SERVICES
-import androidx.annotation.RequiresApi
-import androidx.annotation.RequiresExtension
-import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
-import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
-import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
-import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
-
-/**
- * Implementation that delegates to platform [SdkSandboxController].
- */
-@RequiresApi(33)
-@RequiresExtension(extension = AD_SERVICES, version = 5)
-internal open class PlatformImpl(
-    private val controller: SdkSandboxController
-) : SdkSandboxControllerCompat.SandboxControllerImpl {
-
-    private val appOwnedSdkProvider = AppOwnedSdkProvider.create(controller)
-
-    override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
-        return controller
-            .sandboxedSdks
-            .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
-    }
-
-    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
-        appOwnedSdkProvider.getAppOwnedSdkSandboxInterfaces()
-
-    override fun registerSdkSandboxActivityHandler(
-        handlerCompat: SdkSandboxActivityHandlerCompat
-    ): IBinder {
-        throw UnsupportedOperationException("This API only available for devices run on Android U+")
-    }
-
-    override fun unregisterSdkSandboxActivityHandler(
-        handlerCompat: SdkSandboxActivityHandlerCompat
-    ) {
-        throw UnsupportedOperationException("This API only available for devices run on Android U+")
-    }
-
-    companion object {
-        fun from(context: Context): PlatformImpl {
-            val sdkSandboxController = context.getSystemService(SdkSandboxController::class.java)
-            return PlatformImpl(sdkSandboxController)
-        }
-    }
-}
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
index a143ea0..601d474 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
@@ -16,6 +16,7 @@
 
 package androidx.privacysandbox.sdkruntime.core.controller.impl
 
+import android.annotation.SuppressLint
 import android.app.Activity
 import android.app.Application
 import android.app.sdksandbox.sdkprovider.SdkSandboxActivityHandler
@@ -23,27 +24,47 @@
 import android.content.Context
 import android.os.Bundle
 import android.os.IBinder
-import android.os.ext.SdkExtensions
 import androidx.activity.OnBackPressedDispatcher
 import androidx.annotation.RequiresApi
-import androidx.annotation.RequiresExtension
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleRegistry
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
+import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
 import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
 
 /**
  * Implementation that delegates to platform [SdkSandboxController] for Android U.
  */
-@RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
 @RequiresApi(34)
+@SuppressLint("NewApi", "ClassVerificationFailure") // until updating checks to requires api 34
 internal class PlatformUDCImpl(
     private val controller: SdkSandboxController
-) : PlatformImpl(controller) {
+) : SdkSandboxControllerCompat.SandboxControllerImpl {
+
+    private val appOwnedSdkProvider = AppOwnedSdkProvider.create(controller)
 
     private val compatToPlatformMap =
         hashMapOf<SdkSandboxActivityHandlerCompat, SdkSandboxActivityHandler>()
 
+    override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
+        throw LoadSdkCompatException(
+            LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
+            "Loading SDK not supported on this device"
+        )
+    }
+
+    override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
+        return controller
+            .sandboxedSdks
+            .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
+    }
+
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        appOwnedSdkProvider.getAppOwnedSdkSandboxInterfaces()
+
     override fun registerSdkSandboxActivityHandler(
         handlerCompat: SdkSandboxActivityHandlerCompat
     ): IBinder {
@@ -142,7 +163,7 @@
     }
 
     companion object {
-        fun from(context: Context): PlatformImpl {
+        fun from(context: Context): PlatformUDCImpl {
             val sdkSandboxController = context.getSystemService(SdkSandboxController::class.java)
             return PlatformUDCImpl(sdkSandboxController)
         }
diff --git a/privacysandbox/sdkruntime/sdkruntime-provider/api/current.txt b/privacysandbox/sdkruntime/sdkruntime-provider/api/current.txt
index bad8190..00612b5a 100644
--- a/privacysandbox/sdkruntime/sdkruntime-provider/api/current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-provider/api/current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.privacysandbox.sdkruntime.provider {
 
-  @RequiresExtension(extension=android.os.ext.SdkExtensions.AD_SERVICES, version=4) public final class SandboxedSdkProviderAdapter extends android.app.sdksandbox.SandboxedSdkProvider {
+  @RequiresApi(34) public final class SandboxedSdkProviderAdapter extends android.app.sdksandbox.SandboxedSdkProvider {
     ctor public SandboxedSdkProviderAdapter();
     method public android.view.View getView(android.content.Context windowContext, android.os.Bundle params, int width, int height);
     method @kotlin.jvm.Throws(exceptionClasses=LoadSdkException::class) public android.app.sdksandbox.SandboxedSdk onLoadSdk(android.os.Bundle params) throws android.app.sdksandbox.LoadSdkException;
diff --git a/privacysandbox/sdkruntime/sdkruntime-provider/api/restricted_current.txt b/privacysandbox/sdkruntime/sdkruntime-provider/api/restricted_current.txt
index bad8190..00612b5a 100644
--- a/privacysandbox/sdkruntime/sdkruntime-provider/api/restricted_current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-provider/api/restricted_current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.privacysandbox.sdkruntime.provider {
 
-  @RequiresExtension(extension=android.os.ext.SdkExtensions.AD_SERVICES, version=4) public final class SandboxedSdkProviderAdapter extends android.app.sdksandbox.SandboxedSdkProvider {
+  @RequiresApi(34) public final class SandboxedSdkProviderAdapter extends android.app.sdksandbox.SandboxedSdkProvider {
     ctor public SandboxedSdkProviderAdapter();
     method public android.view.View getView(android.content.Context windowContext, android.os.Bundle params, int width, int height);
     method @kotlin.jvm.Throws(exceptionClasses=LoadSdkException::class) public android.app.sdksandbox.SandboxedSdk onLoadSdk(android.os.Bundle params) throws android.app.sdksandbox.LoadSdkException;
diff --git a/privacysandbox/sdkruntime/sdkruntime-provider/src/androidTest/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapterTest.kt b/privacysandbox/sdkruntime/sdkruntime-provider/src/androidTest/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapterTest.kt
index debd913a..5bd11b1 100644
--- a/privacysandbox/sdkruntime/sdkruntime-provider/src/androidTest/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapterTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-provider/src/androidTest/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapterTest.kt
@@ -19,12 +19,8 @@
 import android.app.sdksandbox.LoadSdkException
 import android.content.Context
 import android.os.Binder
-import android.os.Build.VERSION_CODES.TIRAMISU
 import android.os.Bundle
-import android.os.ext.SdkExtensions.AD_SERVICES
 import android.view.View
-import androidx.annotation.RequiresExtension
-import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
@@ -35,7 +31,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.reflect.KClass
 import org.junit.Assert.assertThrows
-import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -43,16 +38,13 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-// TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-@RequiresExtension(extension = AD_SERVICES, version = 4)
-@SdkSuppress(minSdkVersion = TIRAMISU)
+@SdkSuppress(minSdkVersion = 34)
 class SandboxedSdkProviderAdapterTest {
 
     private lateinit var context: Context
 
     @Before
     fun setUp() {
-        assumeTrue("Requires Sandbox API available", isSandboxApiAvailable())
         context = ApplicationProvider.getApplicationContext()
     }
 
@@ -259,7 +251,4 @@
             return mView
         }
     }
-
-    private fun isSandboxApiAvailable() =
-        AdServicesInfo.isAtLeastV4()
 }
diff --git a/privacysandbox/sdkruntime/sdkruntime-provider/src/main/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapter.kt b/privacysandbox/sdkruntime/sdkruntime-provider/src/main/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapter.kt
index 05a6eb0..5c70191 100644
--- a/privacysandbox/sdkruntime/sdkruntime-provider/src/main/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapter.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-provider/src/main/java/androidx/privacysandbox/sdkruntime/provider/SandboxedSdkProviderAdapter.kt
@@ -22,9 +22,8 @@
 import android.app.sdksandbox.SandboxedSdkProvider
 import android.content.Context
 import android.os.Bundle
-import android.os.ext.SdkExtensions.AD_SERVICES
 import android.view.View
-import androidx.annotation.RequiresExtension
+import androidx.annotation.RequiresApi
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
 
@@ -33,8 +32,8 @@
  * Gets compat class name from asset "SandboxedSdkProviderCompatClassName.txt"
  *
  */
-@RequiresExtension(extension = AD_SERVICES, version = 4)
-@SuppressLint("ClassVerificationFailure")
+@RequiresApi(34)
+@SuppressLint("NewApi", "ClassVerificationFailure") // until updating checks to requires api 34
 class SandboxedSdkProviderAdapter internal constructor(
     private val classNameProvider: CompatClassNameProvider
 ) : SandboxedSdkProvider() {
diff --git a/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt b/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt
index a33aaa9..e81928d 100644
--- a/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt
+++ b/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/view/SandboxedSdkView.kt
@@ -99,11 +99,6 @@
 class SandboxedSdkView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
     ViewGroup(context, attrs) {
 
-    // TODO(b/284147223): Remove this logic in V+
-    private val surfaceView = SurfaceView(context).apply {
-        visibility = GONE
-    }
-
     // This will only be invoked when the content view has been set and the window is attached.
     private val surfaceChangedCallback = object : SurfaceHolder.Callback {
         override fun surfaceCreated(p0: SurfaceHolder) {
@@ -226,33 +221,6 @@
         }
     }
 
-    /**
-     * Attaches a temporary [SurfaceView] to the view hierarchy. This [SurfaceView] will be removed
-     * once it has been attached to the window and its host token is non-null.
-     *
-     * TODO(b/284147223): Remove this logic in V+
-     */
-    private fun attachTemporarySurfaceView() {
-        val onSurfaceViewAttachedListener =
-            object : OnAttachStateChangeListener {
-                override fun onViewAttachedToWindow(view: View) {
-                    view.removeOnAttachStateChangeListener(this)
-                    removeSurfaceViewAndOpenSession()
-                }
-
-                override fun onViewDetachedFromWindow(view: View) {
-                }
-            }
-        surfaceView.addOnAttachStateChangeListener(onSurfaceViewAttachedListener)
-        super.addView(surfaceView, 0, generateDefaultLayoutParams())
-    }
-
-    internal fun removeSurfaceViewAndOpenSession() {
-        windowInputToken = CompatImpl.getHostToken(surfaceView)
-        super.removeView(surfaceView)
-        checkClientOpenSession()
-    }
-
     internal fun requestSize(width: Int, height: Int) {
         if (width == this.width && height == this.height) return
         requestedWidth = width
@@ -371,7 +339,7 @@
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
-        attachTemporarySurfaceView()
+        CompatImpl.deriveInputTokenAndOpenSession(context, this)
     }
 
     override fun onDetachedFromWindow() {
@@ -450,6 +418,14 @@
         throw UnsupportedOperationException("Cannot remove a view from SandboxedSdkView")
     }
 
+    private fun addTemporarySurfaceView(surfaceView: SurfaceView) {
+        super.addView(surfaceView, 0, generateDefaultLayoutParams())
+    }
+
+    private fun removeTemporarySurfaceView(surfaceView: SurfaceView) {
+        super.removeView(surfaceView)
+    }
+
     internal class Client(private var sandboxedSdkView: SandboxedSdkView?) :
         SandboxedUiAdapter.SessionClient {
 
@@ -563,12 +539,19 @@
      */
      private object CompatImpl {
 
-        fun getHostToken(surfaceView: SurfaceView): IBinder? {
-            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
-                Api34PlusImpl.getHostToken(surfaceView)
+         fun deriveInputTokenAndOpenSession(
+            context: Context,
+            sandboxedSdkView: SandboxedSdkView
+        ) {
+            // TODO(b/284147223): Remove this logic in V+
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                Api34PlusImpl.attachTemporarySurfaceViewAndOpenSession(
+                    context, sandboxedSdkView)
             } else {
-                // Input token is only needed when provider can be located on a separate process.
-                Binder()
+                // the openSession signature requires a non-null input token, so the session
+                // will not be opened until this is set
+                sandboxedSdkView.windowInputToken = Binder()
+                sandboxedSdkView.checkClientOpenSession()
             }
         }
 
@@ -596,12 +579,6 @@
 
             @JvmStatic
             @DoNotInline
-            fun getHostToken(surfaceView: SurfaceView): IBinder? {
-                return surfaceView.hostToken
-            }
-
-            @JvmStatic
-            @DoNotInline
             fun setClippingBounds(
                 contentView: View?,
                 isAttachedToWindow: Boolean,
@@ -631,6 +608,31 @@
                 reparentSurfaceControlTransaction.merge(reparentClippingBoundsTransaction)
                 attachedSurfaceControl.applyTransactionOnDraw(reparentSurfaceControlTransaction)
             }
+
+            @JvmStatic
+            @DoNotInline
+            fun attachTemporarySurfaceViewAndOpenSession(
+                context: Context,
+                sandboxedSdkView: SandboxedSdkView
+            ) {
+                val surfaceView = SurfaceView(context).apply {
+                    visibility = GONE
+                }
+                val onSurfaceViewAttachedListener =
+                    object : OnAttachStateChangeListener {
+                        override fun onViewAttachedToWindow(view: View) {
+                            view.removeOnAttachStateChangeListener(this)
+                            sandboxedSdkView.windowInputToken = surfaceView.hostToken
+                            sandboxedSdkView.removeTemporarySurfaceView(surfaceView)
+                            sandboxedSdkView.checkClientOpenSession()
+                        }
+
+                        override fun onViewDetachedFromWindow(view: View) {
+                        }
+                    }
+                surfaceView.addOnAttachStateChangeListener(onSurfaceViewAttachedListener)
+                sandboxedSdkView.addTemporarySurfaceView(surfaceView)
+            }
         }
 
         @RequiresApi(Build.VERSION_CODES.Q)
diff --git a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileInstaller.java b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileInstaller.java
index 70f4305..61a098e 100644
--- a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileInstaller.java
+++ b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileInstaller.java
@@ -21,7 +21,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
-import android.os.Build;
 import android.util.Log;
 
 import androidx.annotation.IntDef;
@@ -423,10 +422,6 @@
             @NonNull Executor executor,
             @NonNull DiagnosticsCallback diagnostics
     ) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
-            result(executor, diagnostics, ProfileInstaller.RESULT_UNSUPPORTED_ART_VERSION, null);
-            return false;
-        }
         File curProfile = new File(new File(PROFILE_BASE_DIR, packageName), PROFILE_FILE);
 
         DeviceProfileWriter deviceProfileWriter = new DeviceProfileWriter(assets, executor,
diff --git a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileTranscoder.java b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileTranscoder.java
index 700a737..adf0f86 100644
--- a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileTranscoder.java
+++ b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileTranscoder.java
@@ -38,7 +38,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -52,7 +51,6 @@
 import java.util.Map;
 import java.util.TreeMap;
 
-@RequiresApi(19)
 class ProfileTranscoder {
     private ProfileTranscoder() {
     }
@@ -219,7 +217,7 @@
      *    (M|dex_map_size)
      *    type_index_diff[dex_map_size]
      * where `M` stands for special encodings indicating missing types (kIsMissingTypesEncoding)
-     * or memamorphic call (kIsMegamorphicEncoding) which both imply `dex_map_size == 0`.
+     * or megamorphic call (kIsMegamorphicEncoding) which both imply `dex_map_size == 0`.
      */
     private static void writeProfileForS(
             @NonNull OutputStream os,
@@ -371,7 +369,7 @@
                 // Method Flags
                 int methodFlags = computeMethodFlags(profile);
                 // Bitmap Contents
-                byte[] bitmapContents = createMethodBitmapRegion(profile);
+                byte[] bitmapContents = createMethodBitmapRegionForS(methodFlags, profile);
                 // Methods with Inline Caches
                 byte[] methodRegionContents = createMethodsWithInlineCaches(profile);
                 // Profile Index
@@ -404,11 +402,12 @@
         }
     }
 
-    private static byte[] createMethodBitmapRegion(
+    private static byte[] createMethodBitmapRegionForS(
+            int methodFlags,
             @NonNull DexProfileData profile
     ) throws IOException {
         try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-            writeMethodBitmap(out, profile);
+            writeMethodBitmapForS(out, methodFlags, profile);
             return out.toByteArray();
         }
     }
@@ -543,8 +542,8 @@
     }
 
     /**
-     * Create compressable body only for V0.1.0 v0.0.9.
-     *
+     * Create compressible body only for V0.1.0 v0.0.9.
+     * <p>
      * For 0.1.0 this will write header/header/header/body/body/body
      * For 0.0.9 this will write header/body/header/body/header/body
      */
@@ -613,6 +612,12 @@
         return roundUpToByte(methodBitmapBits) / SIZEOF_BYTE;
     }
 
+    private static int getMethodBitmapStorageSizeForS(int methodFlags, int numMethodIds) {
+        int bits = Integer.bitCount(methodFlags & ~HOT);
+        int methodBitmapBits = bits * numMethodIds;
+        return roundUpToByte(methodBitmapBits) / SIZEOF_BYTE;
+    }
+
     private static int roundUpToByte(int bits) {
         return (bits + SIZEOF_BYTE - 1) & -SIZEOF_BYTE;
     }
@@ -721,6 +726,34 @@
         }
     }
 
+    private static void writeMethodBitmapForS(
+            @NonNull OutputStream os,
+            int methodFlags,
+            @NonNull DexProfileData dexData
+    ) throws IOException {
+        int methodBitmapStorageSize = getMethodBitmapStorageSizeForS(
+                methodFlags, dexData.numMethodIds
+        );
+        byte[] bitmap = new byte[methodBitmapStorageSize];
+        for (Map.Entry<Integer, Integer> entry : dexData.methods.entrySet()) {
+            int methodIndex = entry.getKey();
+            int flagValue = entry.getValue();
+
+            if ((flagValue & methodFlags) == 0) {
+                continue;
+            }
+
+            if ((flagValue & STARTUP) != 0) {
+                setMethodBitmapBit(bitmap, STARTUP, methodIndex, dexData);
+            }
+
+            if ((flagValue & POST_STARTUP) != 0) {
+                setMethodBitmapBit(bitmap, POST_STARTUP, methodIndex, dexData);
+            }
+        }
+        os.write(bitmap);
+    }
+
     /**
      * Writes the methods flags as a bitmap to the output stream.
      * @param os the destination OutputStream to write to
diff --git a/profileinstaller/profileinstaller/src/test/java/androidx/profileinstaller/ProfileTranscoderTests.java b/profileinstaller/profileinstaller/src/test/java/androidx/profileinstaller/ProfileTranscoderTests.java
index 23a4c10..a5e9240 100644
--- a/profileinstaller/profileinstaller/src/test/java/androidx/profileinstaller/ProfileTranscoderTests.java
+++ b/profileinstaller/profileinstaller/src/test/java/androidx/profileinstaller/ProfileTranscoderTests.java
@@ -65,7 +65,7 @@
     @Test
     public void testTranscodeForN() throws IOException {
         assertGoldenTranscode(
-                testFile("baseline.prof"),
+                testFile("baseline-p.prof"),
                 testFile("baseline-n.prof"),
                 ProfileVersion.V001_N
         );
@@ -74,7 +74,7 @@
     @Test
     public void testTranscodeForO() throws IOException {
         assertGoldenTranscode(
-                testFile("baseline.prof"),
+                testFile("baseline-p.prof"),
                 testFile("baseline-o.prof"),
                 ProfileVersion.V005_O
         );
@@ -83,7 +83,7 @@
     @Test
     public void testTranscodeForO_MR1() throws IOException {
         assertGoldenTranscode(
-                testFile("baseline.prof"),
+                testFile("baseline-p.prof"),
                 testFile("baseline-o-mr1.prof"),
                 ProfileVersion.V009_O_MR1
         );
@@ -92,7 +92,7 @@
     @Test
     public void testTranscodeForP() throws IOException {
         assertGoldenTranscode(
-                testFile("baseline.prof"),
+                testFile("baseline-p.prof"),
                 testFile("baseline-p.prof"),
                 ProfileVersion.V010_P
         );
@@ -110,6 +110,17 @@
     }
 
     @Test
+    public void testTranscodeForS_methodBitmapStorage() throws IOException {
+        assertGoldenTranscodeWithMeta(
+                testFile("katana/baseline-p.prof"),
+                testFile("katana/baseline-s.profm"),
+                testFile("katana/baseline-s.prof"),
+                ProfileVersion.V015_S,
+                "" /* apkName */
+        );
+    }
+
+    @Test
     public void testMultidexTranscodeForO() throws IOException {
         assertGoldenTranscode(
                 testFile("baseline-multidex.prof"),
diff --git a/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-p.prof b/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-p.prof
new file mode 100644
index 0000000..5633b92
--- /dev/null
+++ b/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-p.prof
Binary files differ
diff --git a/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-s.prof b/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-s.prof
new file mode 100644
index 0000000..43ad67e
--- /dev/null
+++ b/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-s.prof
Binary files differ
diff --git a/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-s.profm b/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-s.profm
new file mode 100644
index 0000000..596d8bc
--- /dev/null
+++ b/profileinstaller/profileinstaller/src/test/test-data/katana/baseline-s.profm
Binary files differ
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PoolingContainerRecyclerViewTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PoolingContainerRecyclerViewTest.kt
index 93c19e6..05a9fde 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PoolingContainerRecyclerViewTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PoolingContainerRecyclerViewTest.kt
@@ -17,11 +17,9 @@
 package androidx.recyclerview.widget
 
 import android.content.Context
-import android.os.Build
 import android.view.View
 import android.view.ViewGroup
 import android.widget.LinearLayout
-import androidx.annotation.RequiresApi
 import androidx.customview.poolingcontainer.addPoolingContainerListener
 import androidx.recyclerview.test.awaitScrollIdle
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -428,7 +426,6 @@
     var binds = 0
     var releases = 0
 
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
         val view = View(context)
         view.layoutParams =
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityLifecycleTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityLifecycleTest.java
index 2e6e604..3d5e3c6 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityLifecycleTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityLifecycleTest.java
@@ -229,9 +229,7 @@
                     AccessibilityNodeInfo info = recyclerView.getChildAt(i)
                             .createAccessibilityNodeInfo();
                     assertTrue("custom delegate sets isChecked", info.isChecked());
-                    if (Build.VERSION.SDK_INT >= 19) {
-                        assertNotNull(info.getCollectionItemInfo());
-                    }
+                    assertNotNull(info.getCollectionItemInfo());
                     children.add(view);
                 }
             }
@@ -254,9 +252,7 @@
                     assertTrue(children.contains(view));
                     AccessibilityNodeInfo info = view.createAccessibilityNodeInfo();
                     assertTrue("custom delegate sets isChecked", info.isChecked());
-                    if (Build.VERSION.SDK_INT >= 19) {
-                        assertNotNull(info.getCollectionItemInfo());
-                    }
+                    assertNotNull(info.getCollectionItemInfo());
                 }
             }
         });
@@ -307,9 +303,7 @@
                     assertEquals(i, recyclerView.getChildAdapterPosition(view));
                     assertTrue(accessibiltyDelegateIsItemDelegate(recyclerView, view));
                     AccessibilityNodeInfo info = view.createAccessibilityNodeInfo();
-                    if (Build.VERSION.SDK_INT >= 19) {
-                        assertNotNull(info.getCollectionItemInfo());
-                    }
+                    assertNotNull(info.getCollectionItemInfo());
                 }
             }
         });
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java
index a6d44ad..69ee2cf 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
-import android.os.Build;
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
@@ -52,8 +51,6 @@
 @SmallTest
 @RunWith(Parameterized.class)
 public class RecyclerViewAccessibilityTest extends BaseRecyclerViewInstrumentationTest {
-    private static final boolean SUPPORTS_COLLECTION_INFO =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
     private final boolean mVerticalScrollBefore;
     private final boolean mHorizontalScrollBefore;
     private final boolean mVerticalScrollAfter;
@@ -164,16 +161,14 @@
                 (info.getActions() & AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD) != 0);
         assertEquals(mHorizontalScrollAfter || mVerticalScrollAfter,
                 (info.getActions() & AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD) != 0);
-        if (SUPPORTS_COLLECTION_INFO) {
-            final AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo = info
-                    .getCollectionInfo();
-            assertNotNull(collectionInfo);
-            if (recyclerView.getLayoutManager().canScrollVertically()) {
-                assertEquals(adapter.getItemCount(), collectionInfo.getRowCount());
-            }
-            if (recyclerView.getLayoutManager().canScrollHorizontally()) {
-                assertEquals(adapter.getItemCount(), collectionInfo.getColumnCount());
-            }
+        final AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo = info
+                .getCollectionInfo();
+        assertNotNull(collectionInfo);
+        if (recyclerView.getLayoutManager().canScrollVertically()) {
+            assertEquals(adapter.getItemCount(), collectionInfo.getRowCount());
+        }
+        if (recyclerView.getLayoutManager().canScrollHorizontally()) {
+            assertEquals(adapter.getItemCount(), collectionInfo.getColumnCount());
         }
 
         final AccessibilityEvent event = AccessibilityEvent.obtain();
@@ -188,31 +183,29 @@
         assertEquals(event.getItemCount(), adapter.getItemCount());
 
         getInstrumentation().waitForIdleSync();
-        if (SUPPORTS_COLLECTION_INFO) {
-            for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
-                final View view = mRecyclerView.getChildAt(i);
-                final AccessibilityNodeInfoCompat childInfo = AccessibilityNodeInfoCompat.obtain();
-                mActivityRule.runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        delegateCompat.getItemDelegate().
-                                onInitializeAccessibilityNodeInfo(view, childInfo);
-                    }
-                });
-                final AccessibilityNodeInfoCompat.CollectionItemInfoCompat collectionItemInfo =
-                        childInfo.getCollectionItemInfo();
-                assertNotNull(collectionItemInfo);
-                if (recyclerView.getLayoutManager().canScrollHorizontally()) {
-                    assertEquals(i, collectionItemInfo.getColumnIndex());
-                } else {
-                    assertEquals(0, collectionItemInfo.getColumnIndex());
+        for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
+            final View view = mRecyclerView.getChildAt(i);
+            final AccessibilityNodeInfoCompat childInfo = AccessibilityNodeInfoCompat.obtain();
+            mActivityRule.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    delegateCompat.getItemDelegate()
+                            .onInitializeAccessibilityNodeInfo(view, childInfo);
                 }
+            });
+            final AccessibilityNodeInfoCompat.CollectionItemInfoCompat collectionItemInfo =
+                    childInfo.getCollectionItemInfo();
+            assertNotNull(collectionItemInfo);
+            if (recyclerView.getLayoutManager().canScrollHorizontally()) {
+                assertEquals(i, collectionItemInfo.getColumnIndex());
+            } else {
+                assertEquals(0, collectionItemInfo.getColumnIndex());
+            }
 
-                if (recyclerView.getLayoutManager().canScrollVertically()) {
-                    assertEquals(i, collectionItemInfo.getRowIndex());
-                } else {
-                    assertEquals(0, collectionItemInfo.getRowIndex());
-                }
+            if (recyclerView.getLayoutManager().canScrollVertically()) {
+                assertEquals(i, collectionItemInfo.getRowIndex());
+            } else {
+                assertEquals(0, collectionItemInfo.getRowIndex());
             }
         }
 
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java
index c19f539..741bb69 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewLayoutTest.java
@@ -53,7 +53,6 @@
 import android.graphics.Color;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -841,8 +840,7 @@
             public View onFocusSearchFailed(View focused, int direction,
                     RecyclerView.Recycler recycler,
                     RecyclerView.State state) {
-                int expectedDir = Build.VERSION.SDK_INT <= 15 ? View.FOCUS_DOWN :
-                        View.FOCUS_FORWARD;
+                int expectedDir = View.FOCUS_FORWARD;
                 assertEquals(expectedDir, direction);
                 assertEquals(1, getChildCount());
                 View child0 = getChildAt(0);
diff --git a/resourceinspection/OWNERS b/resourceinspection/OWNERS
deleted file mode 100644
index 9878e82..0000000
--- a/resourceinspection/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
[email protected]
diff --git a/room/benchmark/src/androidTest/java/androidx/room/benchmark/AmbiguousColumnResolverBenchmark.kt b/room/benchmark/src/androidTest/java/androidx/room/benchmark/AmbiguousColumnResolverBenchmark.kt
index a60af6b..09770b8 100644
--- a/room/benchmark/src/androidTest/java/androidx/room/benchmark/AmbiguousColumnResolverBenchmark.kt
+++ b/room/benchmark/src/androidTest/java/androidx/room/benchmark/AmbiguousColumnResolverBenchmark.kt
@@ -16,12 +16,10 @@
 
 package androidx.room.benchmark
 
-import android.os.Build
 import androidx.benchmark.junit4.BenchmarkRule
 import androidx.benchmark.junit4.measureRepeated
 import androidx.room.AmbiguousColumnResolver
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.generateAllEnumerations
 import kotlin.random.Random
 import org.junit.Assert.assertArrayEquals
@@ -32,7 +30,6 @@
 
 @LargeTest
 @RunWith(Parameterized::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
 class AmbiguousColumnResolverBenchmark(
     private val numOfColumns: Int,
     private val numOfTables: Int,
diff --git a/room/benchmark/src/androidTest/java/androidx/room/benchmark/InvalidationTrackerBenchmark.kt b/room/benchmark/src/androidTest/java/androidx/room/benchmark/InvalidationTrackerBenchmark.kt
index 2d19f32..62de81d 100644
--- a/room/benchmark/src/androidTest/java/androidx/room/benchmark/InvalidationTrackerBenchmark.kt
+++ b/room/benchmark/src/androidTest/java/androidx/room/benchmark/InvalidationTrackerBenchmark.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.benchmark
 
-import android.os.Build
 import androidx.benchmark.junit4.BenchmarkRule
 import androidx.benchmark.junit4.measureRepeated
 import androidx.room.Dao
@@ -30,7 +29,6 @@
 import androidx.room.RoomDatabase
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.generateAllEnumerations
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
@@ -42,7 +40,6 @@
 
 @LargeTest
 @RunWith(Parameterized::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN) // TODO Fix me for API 15 - b/120098504
 class InvalidationTrackerBenchmark(private val sampleSize: Int, private val mode: Mode) {
 
     @get:Rule
diff --git a/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt b/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt
index 53c9fe0..b0ba110 100644
--- a/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt
+++ b/room/benchmark/src/androidTest/java/androidx/room/benchmark/RelationBenchmark.kt
@@ -16,7 +16,6 @@
 
 package androidx.room.benchmark
 
-import android.os.Build
 import androidx.benchmark.junit4.BenchmarkRule
 import androidx.benchmark.junit4.measureRepeated
 import androidx.room.Dao
@@ -32,7 +31,6 @@
 import androidx.room.RoomWarnings
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.generateAllEnumerations
 import org.junit.Assert
 import org.junit.Assert.assertEquals
@@ -44,7 +42,6 @@
 
 @LargeTest
 @RunWith(Parameterized::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
 class RelationBenchmark(private val parentSampleSize: Int, private val childSampleSize: Int) {
 
     @get:Rule
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/AutoMigrationTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/AutoMigrationTest.kt
index 186154a..7e2e54b 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/AutoMigrationTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/AutoMigrationTest.kt
@@ -16,13 +16,11 @@
 package androidx.room.integration.kotlintestapp.migration
 
 import android.database.sqlite.SQLiteConstraintException
-import android.os.Build
 import androidx.kruth.assertThat
 import androidx.room.testing.MigrationTestHelper
 import androidx.room.util.TableInfo.Companion.read
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import org.junit.Rule
 import org.junit.Test
@@ -33,7 +31,6 @@
  */
 @RunWith(AndroidJUnit4::class)
 @LargeTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN) // Due to FTS table migrations
 class AutoMigrationTest {
     @JvmField
     @Rule
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/WriteAheadLoggingKotlinTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/WriteAheadLoggingKotlinTest.kt
index 277f983..5c412ca 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/WriteAheadLoggingKotlinTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/WriteAheadLoggingKotlinTest.kt
@@ -28,7 +28,6 @@
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import java.util.concurrent.TimeUnit
 import junit.framework.TestCase.assertEquals
@@ -48,7 +47,6 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 16)
 class WriteAheadLoggingKotlinTest {
     @get:Rule
     val countingTaskExecutorRule = CountingTaskExecutorRule()
diff --git a/room/integration-tests/testapp/build.gradle b/room/integration-tests/testapp/build.gradle
index 55d6608..d2f0759 100644
--- a/room/integration-tests/testapp/build.gradle
+++ b/room/integration-tests/testapp/build.gradle
@@ -75,6 +75,9 @@
         }
     }
     compileOptions {
+        // For testing Java records
+        sourceCompatibility JavaVersion.VERSION_17
+        targetCompatibility JavaVersion.VERSION_17
         coreLibraryDesugaringEnabled true
     }
     namespace "androidx.room.integration.testapp"
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/TestDatabase.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/TestDatabase.java
index 4d4e446..79f7b5c 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/TestDatabase.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/TestDatabase.java
@@ -28,6 +28,7 @@
 import androidx.room.integration.testapp.dao.PetDao;
 import androidx.room.integration.testapp.dao.ProductDao;
 import androidx.room.integration.testapp.dao.RawDao;
+import androidx.room.integration.testapp.dao.RecordEntityDao;
 import androidx.room.integration.testapp.dao.RobotsDao;
 import androidx.room.integration.testapp.dao.SchoolDao;
 import androidx.room.integration.testapp.dao.SpecificDogDao;
@@ -46,6 +47,7 @@
 import androidx.room.integration.testapp.vo.PetCouple;
 import androidx.room.integration.testapp.vo.PetWithUser;
 import androidx.room.integration.testapp.vo.Product;
+import androidx.room.integration.testapp.vo.RecordEntity;
 import androidx.room.integration.testapp.vo.Robot;
 import androidx.room.integration.testapp.vo.RoomLibraryPojo;
 import androidx.room.integration.testapp.vo.School;
@@ -60,7 +62,8 @@
 
 @Database(entities = {User.class, Pet.class, School.class, PetCouple.class, Toy.class,
         BlobEntity.class, Product.class, FunnyNamedEntity.class, House.class,
-        FriendsJunction.class, Hivemind.class, Robot.class, RoomLibraryPojo.class},
+        FriendsJunction.class, Hivemind.class, Robot.class, RoomLibraryPojo.class,
+        RecordEntity.class},
         views = {PetWithUser.class},
         version = 1, exportSchema = false)
 @TypeConverters(TestDatabase.Converters.class)
@@ -81,6 +84,7 @@
     public abstract UserHouseDao getUserHouseDao();
     public abstract RobotsDao getRobotsDao();
     public abstract LibraryItemDao getLibraryItemDao();
+    public abstract RecordEntityDao getRecordEntityDao();
 
     @SuppressWarnings("unused")
     public static class Converters {
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/RecordEntityDao.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/RecordEntityDao.java
new file mode 100644
index 0000000..6a6cc70
--- /dev/null
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/dao/RecordEntityDao.java
@@ -0,0 +1,34 @@
+/*
+ * 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.room.integration.testapp.dao;
+
+import androidx.room.Dao;
+import androidx.room.Insert;
+import androidx.room.Query;
+import androidx.room.integration.testapp.vo.RecordEntity;
+
+import java.util.List;
+
+@Dao
+public interface RecordEntityDao {
+
+    @Query("SELECT * FROM RecordEntity")
+    List<RecordEntity> getAll();
+
+    @Insert
+    void insert(RecordEntity item);
+}
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/ClearAllTablesTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/ClearAllTablesTest.java
index 4066106..c9e08d5 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/ClearAllTablesTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/ClearAllTablesTest.java
@@ -42,7 +42,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -198,7 +197,6 @@
 
     @Test
     @MediumTest
-    @SdkSuppress(minSdkVersion = 16)
     public void clearsDataFromDiskWal() throws IOException {
         clearsDataFromDisk(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING);
     }
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/PojoTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/PojoTest.java
index 873556a..2af75eb 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/PojoTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/PojoTest.java
@@ -23,17 +23,18 @@
 
 import androidx.room.Room;
 import androidx.room.integration.testapp.TestDatabase;
+import androidx.room.integration.testapp.dao.RecordEntityDao;
 import androidx.room.integration.testapp.dao.UserDao;
 import androidx.room.integration.testapp.database.ProductDao;
 import androidx.room.integration.testapp.database.Review;
 import androidx.room.integration.testapp.database.SampleDatabase;
 import androidx.room.integration.testapp.vo.AvgWeightByAge;
+import androidx.room.integration.testapp.vo.RecordEntity;
 import androidx.room.integration.testapp.vo.User;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -43,17 +44,13 @@
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class PojoTest {
-    private UserDao mUserDao;
-
-    @Before
-    public void createDb() {
-        Context context = ApplicationProvider.getApplicationContext();
-        TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
-        mUserDao = db.getUserDao();
-    }
 
     @Test
     public void weightsByAge() {
+        Context context = ApplicationProvider.getApplicationContext();
+        TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
+        UserDao userDao = db.getUserDao();
+
         User[] users = TestUtil.createUsersArray(3, 5, 7, 10);
         users[0].setAge(10);
         users[0].setWeight(20);
@@ -67,8 +64,8 @@
         users[3].setAge(35);
         users[3].setWeight(55);
 
-        mUserDao.insertAll(users);
-        assertThat(mUserDao.weightByAge(), is(
+        userDao.insertAll(users);
+        assertThat(userDao.weightByAge(), is(
                 Arrays.asList(
                         new AvgWeightByAge(35, 55),
                         new AvgWeightByAge(10, 25),
@@ -87,4 +84,15 @@
         assertThat(result.size(), is(1));
         db.close();
     }
+
+    @Test
+    public void recordEntity() {
+        Context context = ApplicationProvider.getApplicationContext();
+        TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
+        RecordEntityDao recordDao = db.getRecordEntityDao();
+        recordDao.insert(new RecordEntity(1, "I am a RECORD"));
+        List<RecordEntity> result = recordDao.getAll();
+        assertThat(result.size(), is(1));
+        assertThat(result.get(0).data(), is("I am a RECORD"));
+    }
 }
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/WriteAheadLoggingTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/WriteAheadLoggingTest.java
index 28be1c6..5acb92a 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/WriteAheadLoggingTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/WriteAheadLoggingTest.java
@@ -46,7 +46,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.After;
@@ -70,7 +69,6 @@
 @RunWith(AndroidJUnit4.class)
 @FlakyTest(bugId = 241095868)
 @LargeTest
-@SdkSuppress(minSdkVersion = 16)
 public class WriteAheadLoggingTest {
 
     private static final String DATABASE_NAME = "wal.db";
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/RecordEntity.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/RecordEntity.java
new file mode 100644
index 0000000..3a1f149
--- /dev/null
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/vo/RecordEntity.java
@@ -0,0 +1,26 @@
+/*
+ * 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.room.integration.testapp.vo;
+
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+@Entity
+public record RecordEntity(
+        @PrimaryKey long id,
+        String data
+) {}
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt
index 2e7bc22..a7a4b8d 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt
@@ -49,6 +49,8 @@
                     config = params.config
                 ).also { processor = it }
             }
+
+            fun isProcessorInitialized() = this::processor.isInitialized
         }
         val args = TestCompilationArguments(
             sources = params.sources,
@@ -62,6 +64,23 @@
             workingDir = workingDir,
             arguments = args
         )
+        if (!processorProvider.isProcessorInitialized()) {
+            // KSP did not completely run, report diagnostic messages those with an exception.
+            val exceptionMsg = buildString {
+                append("KSP did not completely run!")
+                if (result.diagnostics.isNotEmpty()) {
+                    appendLine()
+                    appendLine("--- Diagnostic messages:")
+                    result.diagnostics.values.flatten().forEach {
+                        appendLine("${it.kind}: ${it.msg}")
+                    }
+                    append("--- End of Diagnostic messages")
+                } else {
+                    append(" No diagnostic messages...")
+                }
+            }
+            error(exceptionMsg)
+        }
         return KotlinCompilationResult(
             testRunner = this,
             processor = processorProvider.processor,
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
index 98883ca..307b910 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
@@ -144,6 +144,11 @@
     fun isCompanionObject(): Boolean
 
     /**
+     * Returns `true` if this [XTypeElement] is a Java record class (i.e. [java.lang.Record]).
+     */
+    fun isRecordClass(): Boolean
+
+    /**
      * Fields declared in this type
      *  includes all instance/static fields in this
      */
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/AnnotationMirrorExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/AnnotationMirrorExt.kt
new file mode 100644
index 0000000..244390e
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/AnnotationMirrorExt.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.room.compiler.processing.javac
+
+import com.google.auto.common.MoreElements
+import com.google.auto.common.MoreTypes
+import java.lang.annotation.Repeatable
+import javax.lang.model.element.AnnotationMirror
+import javax.lang.model.type.TypeKind
+import javax.lang.model.util.ElementFilter
+
+/** Returns true if the given [AnnotationMirror] represents a repeatable annotation. */
+internal fun AnnotationMirror.isRepeatable(): Boolean {
+    try {
+        val valueType =
+            ElementFilter.methodsIn(MoreTypes.asTypeElement(annotationType).enclosedElements)
+                .singleOrNull { it.simpleName.toString() == "value" }
+                ?.returnType
+
+        // The contract of a repeatable annotation requires that the container annotation have a
+        // single "default" method that returns an array typed with the repeatable annotation type.
+        if (valueType == null || valueType.kind != TypeKind.ARRAY) {
+            return false
+        }
+        val componentType = MoreTypes.asArray(valueType).componentType
+        if (componentType.kind != TypeKind.DECLARED) {
+            return false
+        }
+        val componentElement = MoreTypes.asDeclared(componentType).asElement()
+
+        // Ideally we would read the value of the Repeatable annotation to get the container class
+        // type and check that it matches "this" type. However, there seems to be a KSP bug where
+        // the value of Repeatable is not present so the best we can do is check that all the nested
+        // members are annotated with repeatable.
+        // https://github.com/google/ksp/issues/358
+        return MoreElements.isAnnotationPresent(componentElement, Repeatable::class.java) ||
+            // The java and kotlin versions of Repeatable are not interchangeable.
+            // https://github.com/google/ksp/issues/459 asks whether the built in type
+            // mapper should convert them, but it may not be possible because there are
+            // differences to how they work (eg different parameters).
+            MoreElements.isAnnotationPresent(
+                componentElement, kotlin.annotation.Repeatable::class.java
+            )
+    } catch (t: Throwable) {
+        // TODO(b/314160063): Turbine can throw when getting enclosed elements. Remove this once
+        // we have a better way to work around Turbine exception.
+        return false
+    }
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt
index 0cb2cff..80e9569 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt
@@ -70,7 +70,16 @@
     override fun getAllAnnotations(): List<XAnnotation> {
         return element.annotationMirrors.map { mirror -> JavacAnnotation(env, mirror) }
             .flatMap { annotation ->
-                annotation.unwrapRepeatedAnnotationsFromContainer() ?: listOf(annotation)
+                // TODO(b/313473892): Checking if an annotation needs to be unwrapped can be
+                //  expensive with the XProcessing API, especially if we don't really care about
+                //  annotation values, so do a quick check on the AnnotationMirror first to decide
+                //  if its repeatable. Remove this once we've optimized the general solution in
+                //  unwrapRepeatedAnnotationsFromContainer()
+                if (annotation.mirror.isRepeatable()) {
+                    annotation.unwrapRepeatedAnnotationsFromContainer() ?: listOf(annotation)
+                } else {
+                    listOf(annotation)
+                }
             }
     }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt
index 2d66b79..fc22ded 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacType.kt
@@ -62,13 +62,12 @@
     }
 
     override val typeElement by lazy {
-        val element = try {
-            MoreTypes.asTypeElement(typeMirror)
-        } catch (notAnElement: IllegalArgumentException) {
-            null
-        }
-        element?.let {
-            env.wrapTypeElement(it)
+        env.delegate.typeUtils.asElement(typeMirror)?.let {
+            if (MoreElements.isType(it)) {
+                env.wrapTypeElement(MoreElements.asType(it))
+            } else {
+                null
+            }
         }
     }
 
@@ -112,7 +111,16 @@
             JavacKmAnnotation(env, it)
         } ?: typeMirror.annotationMirrors.map { mirror -> JavacAnnotation(env, mirror) }
             .flatMap { annotation ->
-                annotation.unwrapRepeatedAnnotationsFromContainer() ?: listOf(annotation)
+                // TODO(b/313473892): Checking if an annotation needs to be unwrapped can be
+                //  expensive with the XProcessing API, especially if we don't really care about
+                //  annotation values, so do a quick check on the AnnotationMirror first to decide
+                //  if its repeatable. Remove this once we've optimized the general solution in
+                //  unwrapRepeatedAnnotationsFromContainer()
+                if (annotation.mirror.isRepeatable()) {
+                    annotation.unwrapRepeatedAnnotationsFromContainer() ?: listOf(annotation)
+                } else {
+                    listOf(annotation)
+                }
             }
     }
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
index f404202..33e3c00 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
@@ -158,6 +158,10 @@
         return kotlinMetadata?.isInterface() ?: (element.kind == ElementKind.INTERFACE)
     }
 
+    override fun isRecordClass(): Boolean {
+        return element.kind == ElementKind.RECORD
+    }
+
     override fun findPrimaryConstructor(): JavacConstructorElement? {
         val primarySignature = kotlinMetadata?.primaryConstructorSignature ?: return null
         return getConstructors().firstOrNull {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index 9d4aba5..b2b8de4 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -251,6 +251,12 @@
         return !isInterface() && !declaration.isOpen()
     }
 
+    override fun isRecordClass(): Boolean {
+        // Need to also check super type since @JvmRecord is @Retention(SOURCE)
+        return hasAnnotation(JvmRecord::class) ||
+            superClass?.isTypeOf(java.lang.Record::class) == true
+    }
+
     override fun getDeclaredFields(): List<XFieldElement> {
         return _declaredFields
     }
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index 5633347..d4d0197 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -32,6 +32,8 @@
 import androidx.room.compiler.processing.util.getDeclaredMethodByJvmName
 import androidx.room.compiler.processing.util.getField
 import androidx.room.compiler.processing.util.getMethodByJvmName
+import androidx.room.compiler.processing.util.runJavaProcessorTest
+import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
 import com.squareup.kotlinpoet.INT
 import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
@@ -2415,6 +2417,61 @@
         }
     }
 
+    @Test
+    fun isRecordClass() {
+        val javaSrc = Source.java(
+            "JavaRecord",
+            """
+            public record JavaRecord(String name) { }
+            """.trimIndent()
+        )
+        val kotlinSrc = Source.kotlin(
+            "KotlinRecord.kt",
+            """
+            @JvmRecord
+            data class KotlinRecord(val name: String)
+            """.trimIndent()
+        )
+        val handler: (XTestInvocation) -> Unit = {
+            val javaElement = it.processingEnv.requireTypeElement("JavaRecord")
+            assertThat(javaElement.isRecordClass())
+            if (it.isKsp) {
+                val kotlinElement = it.processingEnv.requireTypeElement("KotlinRecord")
+                assertThat(kotlinElement.isRecordClass())
+            }
+        }
+        // Run only javac and KSP tests as @JvmRecord is broken with KAPT (KT-44706)
+        if (isPreCompiled) {
+            val compiled = compileFiles(
+                sources = listOf(javaSrc, kotlinSrc),
+                kotlincArguments = listOf("-jvm-target=16")
+            )
+            runJavaProcessorTest(
+                sources = listOf(
+                    Source.java("PlaceholderJava", "public class PlaceholderJava {}")
+                ),
+                classpath = compiled,
+                handler = handler
+            )
+            runKspTest(
+                sources = listOf(Source.kotlin("placeholder.kt", "class PlaceholderKotlin")),
+                kotlincArguments = listOf("-jvm-target=16"),
+                classpath = compiled,
+                handler = handler
+            )
+        } else {
+            runJavaProcessorTest(
+                sources = listOf(javaSrc),
+                handler = handler
+            )
+            runKspTest(
+                sources = listOf(javaSrc, kotlinSrc),
+                kotlincArguments = listOf("-jvm-target=16"),
+                handler = handler
+            )
+        }
+    }
+
     /**
      * it is good to exclude methods coming from Object when testing as they differ between KSP
      * and KAPT but irrelevant for Room.
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt
index 42a63d5..d7fb0fa 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt
@@ -17,7 +17,7 @@
 package androidx.room.ext
 
 import androidx.room.compiler.processing.XElement
-import androidx.room.compiler.processing.XFieldElement
+import androidx.room.compiler.processing.XExecutableParameterElement
 import androidx.room.compiler.processing.XTypeElement
 import kotlin.contracts.contract
 
@@ -28,11 +28,17 @@
     return this.hasAnnotation(androidx.room.Entity::class)
 }
 
-fun XTypeElement.getValueClassUnderlyingProperty(): XFieldElement {
+fun XTypeElement.getValueClassUnderlyingElement(): XExecutableParameterElement {
     check(this.isValueClass()) {
         "Can't get value class property, type element '$this' is not a value class"
     }
-    return this.getDeclaredFields().single()
+    // Kotlin states:
+    // * Primary constructor is required for value class
+    // * Value class must have exactly one primary constructor parameter
+    // * Value class primary constructor must only have final read-only (val) property parameter
+    return checkNotNull(this.findPrimaryConstructor()) {
+        "Couldn't find primary constructor for value class."
+    }.parameters.single()
 }
 
 /**
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
index 05c36d0..824889d 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
@@ -961,19 +961,25 @@
 
     private class DefaultDelegate(private val context: Context) : Delegate {
         override fun onPreProcess(element: XTypeElement) {
-            // Check that certain Room annotations with @Target(METHOD) are not used in the POJO
-            // since it is not annotated with AutoValue.
-            element.getAllMethods()
-                .filter { it.hasAnyAnnotation(*TARGET_METHOD_ANNOTATIONS) }
-                .forEach { method ->
-                    val annotationName = TARGET_METHOD_ANNOTATIONS
-                        .first { method.hasAnnotation(it) }
-                        .java.simpleName
-                    context.logger.e(
-                        method,
-                        ProcessorErrors.invalidAnnotationTarget(annotationName, method.kindName())
-                    )
-                }
+            // If POJO is not a record then check that certain Room annotations with @Target(METHOD)
+            // are not used since the POJO is not annotated with AutoValue where Room column
+            // annotations are allowed in methods.
+            if (!element.isRecordClass()) {
+                element.getAllMethods()
+                    .filter { it.hasAnyAnnotation(*TARGET_METHOD_ANNOTATIONS) }
+                    .forEach { method ->
+                        val annotationName = TARGET_METHOD_ANNOTATIONS
+                            .first { columnAnnotation -> method.hasAnnotation(columnAnnotation) }
+                            .java.simpleName
+                        context.logger.e(
+                            method,
+                            ProcessorErrors.invalidAnnotationTarget(
+                                annotationName,
+                                method.kindName()
+                            )
+                        )
+                    }
+            }
         }
 
         override fun findConstructors(element: XTypeElement) = element.getConstructors().filterNot {
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
index 614b818..f398487 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
@@ -28,7 +28,7 @@
 import androidx.room.ext.CollectionTypeNames.LONG_SPARSE_ARRAY
 import androidx.room.ext.CommonTypeNames
 import androidx.room.ext.GuavaTypeNames
-import androidx.room.ext.getValueClassUnderlyingProperty
+import androidx.room.ext.getValueClassUnderlyingElement
 import androidx.room.ext.isByteBuffer
 import androidx.room.ext.isEntityElement
 import androidx.room.ext.isNotByte
@@ -380,7 +380,7 @@
         val typeElement = type.typeElement
         if (typeElement?.isValueClass() == true) {
             // Extract the type value of the Value class element
-            val underlyingProperty = typeElement.getValueClassUnderlyingProperty()
+            val underlyingProperty = typeElement.getValueClassUnderlyingElement()
             val underlyingTypeColumnAdapter = findColumnTypeAdapter(
                 // Find an adapter for the non-null underlying type, nullability will be handled
                 // by the value class adapter.
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
index 1c19e7f..ec688de 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
@@ -20,9 +20,11 @@
 import androidx.room.compiler.codegen.XClassName
 import androidx.room.compiler.codegen.XTypeName
 import androidx.room.compiler.processing.XMethodElement
+import androidx.room.compiler.processing.XProcessingEnvConfig
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.compiler.processing.util.compileFiles
+import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.compiler.processing.util.runProcessorTest
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -216,6 +218,36 @@
         }
     }
 
+    @Test
+    fun valueClassUnderlyingProperty() {
+        val src = Source.kotlin(
+            "Subject.kt",
+            """
+            package foo
+            class Subject {
+              fun makeULong(): ULong {
+                TODO()
+              }
+            }
+            """.trimIndent()
+        )
+        runKspTest(
+            sources = listOf(src),
+            config = XProcessingEnvConfig.DEFAULT.copy(
+                excludeMethodsWithInvalidJvmSourceNames = false
+            )
+        ) { invocation ->
+            val subject = invocation.processingEnv.requireTypeElement("foo.Subject")
+            val returnType = subject.getDeclaredMethods()
+                .single { it.name == "makeULong" }
+                .returnType
+            val prop = checkNotNull(returnType.typeElement).getValueClassUnderlyingElement()
+            assertThat(prop.name).isEqualTo("data")
+            assertThat(prop.type)
+                .isEqualTo(invocation.processingEnv.requireType(XTypeName.PRIMITIVE_LONG))
+        }
+    }
+
     @Suppress("NAME_SHADOWING") // intentional
     private fun runTest(
         sources: List<Source> = emptyList(),
diff --git a/room/room-guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java b/room/room-guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java
index 653a6b9..8ae5983 100644
--- a/room/room-guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java
+++ b/room/room-guava/src/androidTest/java/androidx/room/guava/GuavaRoomTest.java
@@ -25,7 +25,6 @@
 import androidx.room.InvalidationTracker;
 import androidx.room.RoomDatabase;
 import androidx.sqlite.db.SupportSQLiteOpenHelper;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -38,7 +37,6 @@
 public class GuavaRoomTest {
 
     @Test
-    @SdkSuppress(minSdkVersion = 16)
     public void queryIsCancelled() {
         Executor executor = runnable -> { /* nothing to do */ };
 
diff --git a/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt b/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
index c3e1e03..2566a42 100644
--- a/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
+++ b/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
@@ -20,7 +20,6 @@
 import android.os.CancellationSignal
 import androidx.kruth.assertThat
 import androidx.sqlite.db.SupportSQLiteOpenHelper
-import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import java.util.concurrent.Callable
 import java.util.concurrent.CountDownLatch
@@ -38,7 +37,6 @@
 import org.junit.Test
 
 @SmallTest
-@SdkSuppress(minSdkVersion = 16)
 class CoroutineRoomCancellationTest {
 
     @OptIn(ExperimentalCoroutinesApi::class)
diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle
index 46af5ba..a31d80b 100644
--- a/room/room-runtime/build.gradle
+++ b/room/room-runtime/build.gradle
@@ -14,22 +14,31 @@
  * limitations under the License.
  */
 
+import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import androidx.build.Publish
 
 plugins {
     id("AndroidXPlugin")
     id("com.android.library")
-    id("kotlin-android")
     id("androidx.stableaidl")
 }
 
 android {
+    sourceSets {
+        main {
+            // Align AGP main source set root with KMP
+            root = 'src/androidMain'
+        }
+    }
+    defaultConfig {
+        multiDexEnabled true
+    }
     buildFeatures {
         aidl = true
     }
     buildTypes.all {
         consumerProguardFiles "proguard-rules.pro"
-
         stableAidl {
             version 1
         }
@@ -37,44 +46,77 @@
     namespace "androidx.room"
 }
 
+androidXMultiplatform {
+    mac()
+    linux()
+    ios()
+    android()
+
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
+    sourceSets {
+        commonMain {
+            dependencies {
+                api(libs.kotlinStdlib)
+                api(project(":room:room-common"))
+                api(projectOrArtifact(":annotation:annotation"))
+                implementation("androidx.annotation:annotation-experimental:1.1.0-rc01")
+            }
+        }
+        commonTest {
+            dependencies {
+                implementation(libs.kotlinTest)
+                implementation(project(":kruth:kruth"))
+            }
+        }
+        androidMain {
+            dependsOn(commonMain)
+            dependencies {
+                api(project(":sqlite:sqlite-framework"))
+                api(project(":sqlite:sqlite"))
+                implementation("androidx.arch.core:core-runtime:2.2.0")
+                compileOnly("androidx.collection:collection:1.2.0")
+                compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
+                compileOnly("androidx.paging:paging-common:2.0.0")
+            }
+        }
+        androidUnitTest {
+            dependsOn(commonTest)
+            dependencies {
+                implementation("androidx.arch.core:core-testing:2.2.0")
+                implementation(libs.junit)
+                implementation(libs.mockitoCore4)
+                implementation(libs.mockitoKotlin4)
+                implementation("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
+                implementation(libs.testRunner) // Needed for @FlakyTest and @Ignore
+            }
+        }
+
+        androidInstrumentedTest {
+            dependsOn(commonTest)
+            dependencies {
+                implementation(libs.junit)
+                implementation(libs.testExtJunit)
+                implementation(libs.testCore)
+                implementation(libs.testRunner)
+                implementation(libs.espressoCore)
+                implementation(libs.mockitoCore)
+                implementation(libs.dexmakerMockito)
+                implementation(project(":internal-testutils-truth")) // for assertThrows
+                implementation(project(":kruth:kruth"))
+                implementation("androidx.arch.core:core-testing:2.2.0")
+            }
+        }
+    }
+}
+
 dependencies {
-    api(project(":room:room-common"))
-    api(project(":sqlite:sqlite-framework"))
-    api(project(":sqlite:sqlite"))
-    implementation("androidx.arch.core:core-runtime:2.2.0")
-    compileOnly("androidx.collection:collection:1.2.0")
-    compileOnly("androidx.paging:paging-common:2.0.0")
-    compileOnly("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
-    implementation("androidx.annotation:annotation-experimental:1.1.0-rc01")
-    compileOnly libs.kotlinStdlib // Due to :annotation-experimental
     lintChecks(project(":room:room-runtime-lint"))
-
-    testImplementation("androidx.arch.core:core-testing:2.2.0")
-    testImplementation(libs.junit)
-    testImplementation(libs.mockitoCore4)
-    testImplementation(libs.mockitoKotlin4)
-    testImplementation("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
-    testImplementation(libs.kotlinStdlib)
-    testImplementation(libs.kotlinTest)
-    testImplementation(project(":kruth:kruth"))
-    testImplementation(libs.testRunner) // Needed for @FlakyTest and @Ignore
-
-    androidTestImplementation(libs.junit)
-    androidTestImplementation(libs.testExtJunit)
-    androidTestImplementation(libs.testCore)
-    androidTestImplementation(libs.testRunner)
-    androidTestImplementation(libs.espressoCore)
-    androidTestImplementation(libs.kotlinStdlib)
-    androidTestImplementation(libs.mockitoCore, excludes.bytebuddy) // DexMaker has it"s own MockMaker
-    androidTestImplementation(libs.dexmakerMockito, excludes.bytebuddy) // DexMaker has it"s own MockMaker
-    androidTestImplementation(project(":internal-testutils-truth")) // for assertThrows
-    androidTestImplementation(project(":kruth:kruth"))
-    androidTestImplementation("androidx.arch.core:core-testing:2.2.0")
-
 }
 
 androidx {
     name = "Room-Runtime"
+    type = LibraryType.PUBLISHED_LIBRARY
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Room-Runtime"
diff --git a/room/room-runtime/lint-baseline.xml b/room/room-runtime/lint-baseline.xml
index 56845b1d9..1f6fbf3 100644
--- a/room/room-runtime/lint-baseline.xml
+++ b/room/room-runtime/lint-baseline.xml
@@ -259,7 +259,7 @@
         errorLine1="            SupportSQLiteCompat.Api29Impl.setNotificationUris(delegate, cr, uris)"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -268,7 +268,7 @@
         errorLine1="            SupportSQLiteCompat.Api29Impl.setNotificationUris(delegate, cr, uris)"
         errorLine2="                                                              ~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -277,7 +277,7 @@
         errorLine1="            SupportSQLiteCompat.Api29Impl.setNotificationUris(delegate, cr, uris)"
         errorLine2="                                                                        ~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -286,7 +286,7 @@
         errorLine1="            SupportSQLiteCompat.Api29Impl.setNotificationUris(delegate, cr, uris)"
         errorLine2="                                                                            ~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -295,7 +295,7 @@
         errorLine1="            return SupportSQLiteCompat.Api19Impl.getNotificationUri(delegate)"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -304,7 +304,7 @@
         errorLine1="            return SupportSQLiteCompat.Api19Impl.getNotificationUri(delegate)"
         errorLine2="                                                                    ~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -313,7 +313,7 @@
         errorLine1="            return SupportSQLiteCompat.Api29Impl.getNotificationUris(delegate)"
         errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -322,7 +322,7 @@
         errorLine1="            return SupportSQLiteCompat.Api29Impl.getNotificationUris(delegate)"
         errorLine2="                                                                     ~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -331,7 +331,7 @@
         errorLine1="            SupportSQLiteCompat.Api23Impl.setExtras(delegate, extras)"
         errorLine2="                                          ~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -340,7 +340,7 @@
         errorLine1="            SupportSQLiteCompat.Api23Impl.setExtras(delegate, extras)"
         errorLine2="                                                    ~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -349,7 +349,7 @@
         errorLine1="            SupportSQLiteCompat.Api23Impl.setExtras(delegate, extras)"
         errorLine2="                                                              ~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -385,7 +385,7 @@
         errorLine1="        val copyLock = ProcessLock("
         errorLine2="                       ~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/SQLiteCopyOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -394,7 +394,7 @@
         errorLine1="            name,"
         errorLine2="            ~~~~">
         <location
-            file="src/main/java/androidx/room/SQLiteCopyOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -403,7 +403,7 @@
         errorLine1="            context.filesDir,"
         errorLine2="            ~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/SQLiteCopyOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -412,7 +412,7 @@
         errorLine1="            copyLock.lock()"
         errorLine2="                     ~~~~">
         <location
-            file="src/main/java/androidx/room/SQLiteCopyOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -421,7 +421,7 @@
         errorLine1="            copyLock.unlock()"
         errorLine2="                     ~~~~~~">
         <location
-            file="src/main/java/androidx/room/SQLiteCopyOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -430,7 +430,7 @@
         errorLine1="        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -439,7 +439,7 @@
         errorLine1="                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -448,7 +448,7 @@
         errorLine1="        @get:RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -457,7 +457,7 @@
         errorLine1="                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {"
         errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt"/>
     </issue>
 
     <issue
@@ -466,7 +466,7 @@
         errorLine1="    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/util/CursorUtil.kt"/>
+            file="src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt"/>
     </issue>
 
     <issue
@@ -475,7 +475,7 @@
         errorLine1="            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &amp;&amp;"
         errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/InvalidationTracker.kt"/>
+            file="src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt"/>
     </issue>
 
     <issue
@@ -484,7 +484,7 @@
         errorLine1="    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/room/SQLiteCopyOpenHelper.kt"/>
+            file="src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt"/>
     </issue>
 
 </issues>
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoCloserTest.kt
similarity index 96%
rename from room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoCloserTest.kt
index 17bcb4b..1513ee6 100644
--- a/room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt
+++ b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoCloserTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.room
 
+import android.annotation.SuppressLint
 import androidx.arch.core.executor.ArchTaskExecutor
 import androidx.arch.core.executor.testing.CountingTaskExecutorRule
 import androidx.kruth.assertThat
@@ -90,6 +91,7 @@
         assertThat(countingTaskExecutorRule.isIdle).isTrue()
     }
 
+    @SuppressLint("BanThreadSleep")
     @Ignore("b/283959848")
     @Test
     public fun refCountsCounted() {
@@ -116,6 +118,7 @@
         countingTaskExecutorRule.drainTasks(10, TimeUnit.MILLISECONDS)
     }
 
+    @SuppressLint("BanThreadSleep")
     @Ignore // b/271325600
     @Test
     public fun executeRefCountingFunctionPropagatesFailure() {
@@ -133,6 +136,7 @@
         countingTaskExecutorRule.drainTasks(10, TimeUnit.MILLISECONDS)
     }
 
+    @SuppressLint("BanThreadSleep")
     @Test
     @FlakyTest(bugId = 182343970)
     public fun dbNotClosedWithRefCountIncremented() {
@@ -150,6 +154,7 @@
         assertThat(autoCloser.delegateDatabase).isNull()
     }
 
+    @SuppressLint("BanThreadSleep")
     @FlakyTest(bugId = 189775887)
     @Test
     public fun getDelegatedDatabaseReturnsUnwrappedDatabase() {
@@ -176,6 +181,7 @@
         countingTaskExecutorRule.drainTasks(10, TimeUnit.MILLISECONDS)
     }
 
+    @SuppressLint("BanThreadSleep")
     @Test
     public fun refCountStaysIncrementedWhenErrorIsEncountered() {
         callback.throwOnOpen = true
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
similarity index 85%
rename from room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
index db6a259..93a3f73 100644
--- a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
+++ b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.room
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.os.Build
-import android.os.Build.VERSION_CODES.JELLY_BEAN
 import androidx.annotation.RequiresApi
 import androidx.sqlite.db.SupportSQLiteDatabase
 import androidx.sqlite.db.SupportSQLiteOpenHelper
@@ -52,6 +52,7 @@
         )
     }
 
+    @SuppressLint("BanThreadSleep")
     @RequiresApi(Build.VERSION_CODES.N)
     @Test
     public fun testCallbacksCalled() {
@@ -87,28 +88,16 @@
 
         autoClosingRoomOpenHelper.writableDatabase
 
-        if (android.os.Build.VERSION.SDK_INT < JELLY_BEAN) {
-            // onConfigure does not exist before JELLY_BEAN
-            // onCreate + onOpen
-            assertEquals(2, callbackCount.get())
-        } else {
-            // onConfigure + onCreate + onOpen
-            assertEquals(3, callbackCount.get())
-        }
+        // onConfigure + onCreate + onOpen
+        assertEquals(3, callbackCount.get())
 
         Thread.sleep(100)
 
         autoClosingRoomOpenHelper.writableDatabase
 
         // onCreate won't be called the second time.
-        if (android.os.Build.VERSION.SDK_INT < JELLY_BEAN) {
-            // onConfigure does not exist before JELLY_BEAN
-            // onCreate + onOpen + onOpen
-            assertEquals(3, callbackCount.get())
-        } else {
-            // onConfigure + onCreate + onOpen + onConfigure + onOpen
-            assertEquals(5, callbackCount.get())
-        }
+        // onConfigure + onCreate + onOpen + onConfigure + onOpen
+        assertEquals(5, callbackCount.get())
     }
 
     @RequiresApi(Build.VERSION_CODES.N)
@@ -118,16 +107,19 @@
             getAutoClosingRoomOpenHelperFactory()
 
         val refCountCheckingCallback = object : SupportSQLiteOpenHelper.Callback(1) {
+            @SuppressLint("BanThreadSleep")
             override fun onCreate(db: SupportSQLiteDatabase) {
                 Thread.sleep(100)
                 db.execSQL("create table user (idk int)")
             }
 
+            @SuppressLint("BanThreadSleep")
             override fun onConfigure(db: SupportSQLiteDatabase) {
                 Thread.sleep(100)
                 db.setMaximumSize(100000)
             }
 
+            @SuppressLint("BanThreadSleep")
             override fun onOpen(db: SupportSQLiteDatabase) {
                 Thread.sleep(100)
                 db.execSQL("select * from user")
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoClosingRoomOpenHelperTest.kt
similarity index 97%
rename from room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoClosingRoomOpenHelperTest.kt
index e212492..8621c189 100644
--- a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
+++ b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/AutoClosingRoomOpenHelperTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.room
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.database.Cursor
 import android.database.sqlite.SQLiteException
@@ -27,7 +28,6 @@
 import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.FlakyTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.assertThrows
 import java.io.IOException
 import java.util.concurrent.Executors
@@ -117,9 +117,9 @@
         assertThat(autoClosingRoomOpenHelper.autoCloser.refCountForTest).isEqualTo(0)
     }
 
+    @SuppressLint("BanThreadSleep")
     @RequiresApi(Build.VERSION_CODES.N)
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
     fun enableWriteAheadLogging_onOpenHelper() {
         val autoClosingRoomOpenHelper = getAutoClosingRoomOpenHelper()
 
@@ -145,6 +145,7 @@
         }
     }
 
+    @SuppressLint("BanThreadSleep")
     @RequiresApi(Build.VERSION_CODES.N)
     @FlakyTest(bugId = 190607416)
     @Test
@@ -176,6 +177,7 @@
         assertThat(countingCallback.onCreateCalls).isEqualTo(1)
     }
 
+    @SuppressLint("BanThreadSleep")
     @Ignore // b/266993269
     @RequiresApi(Build.VERSION_CODES.N)
     @Test
@@ -192,6 +194,7 @@
         assertThat(autoClosingRoomOpenHelper.autoCloser.refCountForTest).isEqualTo(0)
     }
 
+    @SuppressLint("BanThreadSleep")
     @RequiresApi(Build.VERSION_CODES.N)
     @Test
     fun testStatementReturnedByCompileStatement_reOpensDatabase() {
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/RoomOpenHelperTest.java b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/RoomOpenHelperTest.java
similarity index 100%
rename from room/room-runtime/src/androidTest/java/androidx/room/RoomOpenHelperTest.java
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/RoomOpenHelperTest.java
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/migration/TableInfoTest.java b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/migration/TableInfoTest.java
similarity index 100%
rename from room/room-runtime/src/androidTest/java/androidx/room/migration/TableInfoTest.java
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/migration/TableInfoTest.java
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/migration/ViewInfoTest.java b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/migration/ViewInfoTest.java
similarity index 100%
rename from room/room-runtime/src/androidTest/java/androidx/room/migration/ViewInfoTest.java
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/migration/ViewInfoTest.java
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/util/DBUtilTest.java b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/util/DBUtilTest.java
similarity index 100%
rename from room/room-runtime/src/androidTest/java/androidx/room/util/DBUtilTest.java
rename to room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/util/DBUtilTest.java
diff --git a/room/room-runtime/src/main/AndroidManifest.xml b/room/room-runtime/src/androidMain/AndroidManifest.xml
similarity index 100%
rename from room/room-runtime/src/main/AndroidManifest.xml
rename to room/room-runtime/src/androidMain/AndroidManifest.xml
diff --git a/room/room-runtime/src/main/java/androidx/room/paging/LimitOffsetDataSource.java b/room/room-runtime/src/androidMain/java/androidx/room/paging/LimitOffsetDataSource.java
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/paging/LimitOffsetDataSource.java
rename to room/room-runtime/src/androidMain/java/androidx/room/paging/LimitOffsetDataSource.java
diff --git a/room/room-runtime/src/main/java/androidx/room/AutoCloser.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/AutoCloser.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/AutoCloser.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/AutoCloser.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt
similarity index 96%
rename from room/room-runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt
index 0b47d27..2d29e36 100644
--- a/room/room-runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelper.android.kt
@@ -356,12 +356,9 @@
             }
         }
 
-        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
         override fun setForeignKeyConstraintsEnabled(enabled: Boolean) {
             autoCloser.executeRefCountingFunction<Any?> { db: SupportSQLiteDatabase ->
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-                    db.setForeignKeyConstraintsEnabled(enabled)
-                }
+                db.setForeignKeyConstraintsEnabled(enabled)
                 null
             }
         }
@@ -380,13 +377,9 @@
             )
         }
 
-        @get:RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
         override val isWriteAheadLoggingEnabled: Boolean
             get() = autoCloser.executeRefCountingFunction { db: SupportSQLiteDatabase ->
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-                    return@executeRefCountingFunction db.isWriteAheadLoggingEnabled
-                }
-                false
+                return@executeRefCountingFunction db.isWriteAheadLoggingEnabled
             }
 
         override val attachedDbs: List<Pair<String, String>>?
diff --git a/room/room-runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelperFactory.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelperFactory.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelperFactory.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/AutoClosingRoomOpenHelperFactory.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/DatabaseConfiguration.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/DatabaseConfiguration.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/DatabaseConfiguration.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/DatabaseConfiguration.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/DelegatingOpenHelper.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/DelegatingOpenHelper.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/DelegatingOpenHelper.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/DelegatingOpenHelper.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/EntityDeletionOrUpdateAdapter.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/EntityDeletionOrUpdateAdapter.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/EntityDeletionOrUpdateAdapter.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/EntityDeletionOrUpdateAdapter.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/EntityInsertionAdapter.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/EntityInsertionAdapter.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/EntityInsertionAdapter.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/EntityInsertionAdapter.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/EntityUpsertionAdapter.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/EntityUpsertionAdapter.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/EntityUpsertionAdapter.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/EntityUpsertionAdapter.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/ExperimentalRoomApi.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/ExperimentalRoomApi.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/ExperimentalRoomApi.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/ExperimentalRoomApi.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/InvalidationLiveDataContainer.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationLiveDataContainer.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/InvalidationLiveDataContainer.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationLiveDataContainer.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt
similarity index 98%
rename from room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt
index 38067b7..5c2e38d 100644
--- a/room/room-runtime/src/main/java/androidx/room/InvalidationTracker.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt
@@ -19,7 +19,6 @@
 import android.content.Context
 import android.content.Intent
 import android.database.sqlite.SQLiteException
-import android.os.Build
 import android.util.Log
 import androidx.annotation.GuardedBy
 import androidx.annotation.RestrictTo
@@ -827,9 +826,7 @@
         ) = "`room_table_modification_trigger_${tableName}_$triggerType`"
 
         internal fun beginTransactionInternal(database: SupportSQLiteDatabase) {
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
-                database.isWriteAheadLoggingEnabled
-            ) {
+            if (database.isWriteAheadLoggingEnabled) {
                 database.beginTransactionNonExclusive()
             } else {
                 database.beginTransaction()
diff --git a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/MultiInstanceInvalidationClient.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/MultiInstanceInvalidationClient.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/MultiInstanceInvalidationService.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/MultiInstanceInvalidationService.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorDatabase.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorDatabase.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/QueryInterceptorDatabase.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorDatabase.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorOpenHelper.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorOpenHelper.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelperFactory.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorOpenHelperFactory.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelperFactory.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorOpenHelperFactory.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorProgram.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorProgram.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/QueryInterceptorProgram.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorProgram.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorStatement.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorStatement.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/QueryInterceptorStatement.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/QueryInterceptorStatement.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/RelationUtil.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RelationUtil.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/RelationUtil.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/RelationUtil.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/Room.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/Room.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/Room.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/Room.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomDatabase.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/RoomDatabase.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomOpenHelper.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomOpenHelper.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/RoomOpenHelper.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/RoomOpenHelper.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomSQLiteQuery.android.kt
similarity index 98%
rename from room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/RoomSQLiteQuery.android.kt
index 9a2e832b..1e797b3 100644
--- a/room/room-runtime/src/main/java/androidx/room/RoomSQLiteQuery.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomSQLiteQuery.android.kt
@@ -15,6 +15,7 @@
  */
 package androidx.room
 
+import android.annotation.SuppressLint
 import androidx.annotation.IntDef
 import androidx.annotation.RestrictTo
 import androidx.annotation.VisibleForTesting
@@ -30,6 +31,7 @@
  * Because it is relatively a big object, they are pooled and must be released after each use.
  *
  */
+@SuppressLint("WrongConstant")
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
 class RoomSQLiteQuery private constructor(
     @field:VisibleForTesting val capacity: Int
diff --git a/room/room-runtime/src/main/java/androidx/room/RoomTrackingLiveData.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomTrackingLiveData.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/RoomTrackingLiveData.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/RoomTrackingLiveData.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt
similarity index 96%
rename from room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt
index 3672ab0..883fe26 100644
--- a/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelper.android.kt
@@ -16,9 +16,7 @@
 package androidx.room
 
 import android.content.Context
-import android.os.Build
 import android.util.Log
-import androidx.annotation.RequiresApi
 import androidx.room.Room.LOG_TAG
 import androidx.room.util.copy
 import androidx.room.util.readVersion
@@ -31,9 +29,6 @@
 import java.io.FileOutputStream
 import java.io.IOException
 import java.io.InputStream
-import java.lang.Exception
-import java.lang.IllegalStateException
-import java.lang.RuntimeException
 import java.nio.channels.Channels
 import java.nio.channels.ReadableByteChannel
 import java.util.concurrent.Callable
@@ -57,7 +52,6 @@
     override val databaseName: String?
         get() = delegate.databaseName
 
-    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
     override fun setWriteAheadLoggingEnabled(enabled: Boolean) {
         delegate.setWriteAheadLoggingEnabled(enabled)
     }
diff --git a/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelperFactory.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelperFactory.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelperFactory.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/SQLiteCopyOpenHelperFactory.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/SharedSQLiteStatement.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/SharedSQLiteStatement.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/SharedSQLiteStatement.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/SharedSQLiteStatement.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/TransactionExecutor.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/TransactionExecutor.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/TransactionExecutor.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/TransactionExecutor.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/UUIDUtil.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/UUIDUtil.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/UUIDUtil.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/UUIDUtil.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/migration/AutoMigrationSpec.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/AutoMigrationSpec.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/migration/AutoMigrationSpec.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/migration/AutoMigrationSpec.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/migration/Migration.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/migration/Migration.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/migration/Migration.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/migration/Migration.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/package-info.java b/room/room-runtime/src/androidMain/kotlin/androidx/room/package-info.java
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/package-info.java
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/package-info.java
diff --git a/room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/CursorUtil.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/DBUtil.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/DBUtil.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/DBUtil.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/DBUtil.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/FileUtil.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/FileUtil.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/FileUtil.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/FileUtil.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/FtsTableInfo.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/FtsTableInfo.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/FtsTableInfo.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/FtsTableInfo.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/StringUtil.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/StringUtil.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/StringUtil.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/StringUtil.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/TableInfo.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/TableInfo.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/TableInfo.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/TableInfo.android.kt
diff --git a/room/room-runtime/src/main/java/androidx/room/util/ViewInfo.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/ViewInfo.android.kt
similarity index 100%
rename from room/room-runtime/src/main/java/androidx/room/util/ViewInfo.kt
rename to room/room-runtime/src/androidMain/kotlin/androidx/room/util/ViewInfo.android.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/BuilderTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/BuilderTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/BuilderTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/BuilderTest.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/BuilderTest_TestDatabase_Impl.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/BuilderTest_TestDatabase_Impl.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/BuilderTest_TestDatabase_Impl.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/BuilderTest_TestDatabase_Impl.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/InvalidationLiveDataContainerTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/InvalidationLiveDataContainerTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/InvalidationLiveDataContainerTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/InvalidationLiveDataContainerTest.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/InvalidationTrackerTest.kt
similarity index 98%
rename from room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/InvalidationTrackerTest.kt
index 483589a3d..ac18a3e 100644
--- a/room/room-runtime/src/test/java/androidx/room/InvalidationTrackerTest.kt
+++ b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/InvalidationTrackerTest.kt
@@ -15,8 +15,11 @@
  */
 package androidx.room
 
+import android.annotation.SuppressLint
 import android.database.Cursor
 import android.database.sqlite.SQLiteException
+import android.os.Build
+import androidx.annotation.RequiresApi
 import androidx.arch.core.executor.ArchTaskExecutor
 import androidx.arch.core.executor.JunitTaskExecutorRule
 import androidx.kruth.assertThat
@@ -97,6 +100,7 @@
         reset(mSqliteDb)
     }
 
+    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
     @Before
     fun setLocale() {
         Locale.setDefault(Locale.forLanguageTag("tr-TR"))
@@ -485,6 +489,7 @@
          * Tries to trigger garbage collection by allocating in the heap until an element is
          * available in the given reference queue.
          */
+        @SuppressLint("BanThreadSleep")
         private fun forceGc(queue: ReferenceQueue<Any?>) {
             val continueTriggeringGc = AtomicBoolean(true)
             val t = Thread {
diff --git a/room/room-runtime/src/test/java/androidx/room/ObservedTableTrackerTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/ObservedTableTrackerTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/ObservedTableTrackerTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/ObservedTableTrackerTest.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/RoomSQLiteQueryTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/RoomSQLiteQueryTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/RoomSQLiteQueryTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/RoomSQLiteQueryTest.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/SQLiteCopyOpenHelperTest.kt
similarity index 98%
rename from room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/SQLiteCopyOpenHelperTest.kt
index c3ad6a2..2e4fba7 100644
--- a/room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
+++ b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/SQLiteCopyOpenHelperTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.room
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.content.res.AssetManager
 import android.os.Build
@@ -211,6 +212,7 @@
             onAssetOpen()
             return@thenAnswer object : InputStream() {
                 val delegate by lazy { FileInputStream(copyFromFile) }
+                @SuppressLint("BanThreadSleep")
                 override fun read(): Int {
                     Thread.sleep(10) // simulate slow reading, as if this was a big file
                     return delegate.read()
diff --git a/room/room-runtime/src/test/java/androidx/room/SharedSQLiteStatementTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/SharedSQLiteStatementTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/SharedSQLiteStatementTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/SharedSQLiteStatementTest.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/TransactionExecutorTest.kt
similarity index 96%
rename from room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/TransactionExecutorTest.kt
index 8d6b455..6684cff 100644
--- a/room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt
+++ b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/TransactionExecutorTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.room
 
+import android.annotation.SuppressLint
 import androidx.kruth.assertThat
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.Executors
@@ -71,6 +72,7 @@
         var finish: Long = 0
         var run: Boolean = false
 
+        @SuppressLint("BanThreadSleep")
         override fun run() {
             run = true
             start = System.nanoTime()
diff --git a/room/room-runtime/src/test/java/androidx/room/util/CursorUtilTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/CursorUtilTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/util/CursorUtilTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/CursorUtilTest.kt
diff --git a/room/room-runtime/src/test/java/androidx/room/util/FtsTableInfoTest.java b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/FtsTableInfoTest.java
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/util/FtsTableInfoTest.java
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/FtsTableInfoTest.java
diff --git a/room/room-runtime/src/test/java/androidx/room/util/StringUtilTest.java b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/StringUtilTest.java
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/util/StringUtilTest.java
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/StringUtilTest.java
diff --git a/room/room-runtime/src/test/java/androidx/room/util/UUIDUtilTest.kt b/room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/UUIDUtilTest.kt
similarity index 100%
rename from room/room-runtime/src/test/java/androidx/room/util/UUIDUtilTest.kt
rename to room/room-runtime/src/androidUnitTest/kotlin/androidx/room/util/UUIDUtilTest.kt
diff --git a/room/room-runtime/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/room/room-runtime/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from room/room-runtime/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to room/room-runtime/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/Placeholder.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/Placeholder.kt
new file mode 100644
index 0000000..bad50f2
--- /dev/null
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/Placeholder.kt
@@ -0,0 +1,19 @@
+/*
+ * 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.room
+// empty file to trigger klib creation
+// see: https://youtrack.jetbrains.com/issue/KT-52344
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarDisplayOptions.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarDisplayOptions.java
index 47c07b3..47db7ac 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarDisplayOptions.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarDisplayOptions.java
@@ -76,47 +76,41 @@
     public void onClick(View v) {
         final ActionBar bar = getSupportActionBar();
         int flags = 0;
-        switch (v.getId()) {
-            case R.id.toggle_home_as_up:
-                flags = ActionBar.DISPLAY_HOME_AS_UP;
-                break;
-            case R.id.toggle_show_home:
-                flags = ActionBar.DISPLAY_SHOW_HOME;
-                break;
-            case R.id.toggle_use_logo:
-                flags = ActionBar.DISPLAY_USE_LOGO;
-                break;
-            case R.id.toggle_show_title:
-                flags = ActionBar.DISPLAY_SHOW_TITLE;
-                break;
-            case R.id.toggle_show_custom:
-                flags = ActionBar.DISPLAY_SHOW_CUSTOM;
-                break;
-            case R.id.cycle_custom_gravity: {
-                ActionBar.LayoutParams lp = mCustomViewLayoutParams;
-                int newGravity = 0;
-                switch (lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-                    case Gravity.LEFT:
-                        newGravity = Gravity.CENTER_HORIZONTAL;
-                        break;
-                    case Gravity.CENTER_HORIZONTAL:
-                        newGravity = Gravity.RIGHT;
-                        break;
-                    case Gravity.RIGHT:
-                        newGravity = Gravity.LEFT;
-                        break;
-                }
-                lp.gravity = (lp.gravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) | newGravity;
-                bar.setCustomView(mCustomView, lp);
-                return;
+        int id = v.getId();
+        if (id == R.id.toggle_home_as_up) {
+            flags = ActionBar.DISPLAY_HOME_AS_UP;
+        } else if (id == R.id.toggle_show_home) {
+            flags = ActionBar.DISPLAY_SHOW_HOME;
+        } else if (id == R.id.toggle_use_logo) {
+            flags = ActionBar.DISPLAY_USE_LOGO;
+        } else if (id == R.id.toggle_show_title) {
+            flags = ActionBar.DISPLAY_SHOW_TITLE;
+        } else if (id == R.id.toggle_show_custom) {
+            flags = ActionBar.DISPLAY_SHOW_CUSTOM;
+        } else if (id == R.id.cycle_custom_gravity) {
+            ActionBar.LayoutParams lp = mCustomViewLayoutParams;
+            int newGravity = 0;
+            switch (lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                case Gravity.LEFT:
+                    newGravity = Gravity.CENTER_HORIZONTAL;
+                    break;
+                case Gravity.CENTER_HORIZONTAL:
+                    newGravity = Gravity.RIGHT;
+                    break;
+                case Gravity.RIGHT:
+                    newGravity = Gravity.LEFT;
+                    break;
             }
-            case R.id.toggle_visibility:
-                if (bar.isShowing()) {
-                    bar.hide();
-                } else {
-                    bar.show();
-                }
-                return;
+            lp.gravity = (lp.gravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) | newGravity;
+            bar.setCustomView(mCustomView, lp);
+            return;
+        } else if (id == R.id.toggle_visibility) {
+            if (bar.isShowing()) {
+                bar.hide();
+            } else {
+                bar.show();
+            }
+            return;
         }
 
         int change = bar.getDisplayOptions() ^ flags;
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarUsage.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarUsage.java
index 942b569..e21d40d 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarUsage.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ActionBarUsage.java
@@ -72,11 +72,9 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.action_sort_alpha:
-            case R.id.action_sort_size:
-                onSort(item);
-                break;
+        int itemId = item.getItemId();
+        if (itemId == R.id.action_sort_alpha || itemId == R.id.action_sort_size) {
+            onSort(item);
         }
 
         Toast.makeText(this, "Selected Item: " + item.getTitle(), Toast.LENGTH_SHORT).show();
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ToolbarDisplayOptions.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ToolbarDisplayOptions.java
index ef2f7be..8898417 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ToolbarDisplayOptions.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/app/ToolbarDisplayOptions.java
@@ -76,48 +76,42 @@
     public void onClick(View v) {
         final ActionBar bar = getSupportActionBar();
         int flags = 0;
-        switch (v.getId()) {
-            case R.id.toggle_home_as_up:
-                flags = ActionBar.DISPLAY_HOME_AS_UP;
-                break;
-            case R.id.toggle_show_home:
-                flags = ActionBar.DISPLAY_SHOW_HOME;
-                break;
-            case R.id.toggle_use_logo:
-                flags = ActionBar.DISPLAY_USE_LOGO;
-                getSupportActionBar().setLogo(R.drawable.ic_media_play);
-                break;
-            case R.id.toggle_show_title:
-                flags = ActionBar.DISPLAY_SHOW_TITLE;
-                break;
-            case R.id.toggle_show_custom:
-                flags = ActionBar.DISPLAY_SHOW_CUSTOM;
-                break;
-            case R.id.cycle_custom_gravity: {
-                ActionBar.LayoutParams lp = mCustomViewLayoutParams;
-                int newGravity = 0;
-                switch (lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-                    case Gravity.LEFT:
-                        newGravity = Gravity.CENTER_HORIZONTAL;
-                        break;
-                    case Gravity.CENTER_HORIZONTAL:
-                        newGravity = Gravity.RIGHT;
-                        break;
-                    case Gravity.RIGHT:
-                        newGravity = Gravity.LEFT;
-                        break;
-                }
-                lp.gravity = (lp.gravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) | newGravity;
-                bar.setCustomView(mCustomView, lp);
-                return;
+        int id = v.getId();
+        if (id == R.id.toggle_home_as_up) {
+            flags = ActionBar.DISPLAY_HOME_AS_UP;
+        } else if (id == R.id.toggle_show_home) {
+            flags = ActionBar.DISPLAY_SHOW_HOME;
+        } else if (id == R.id.toggle_use_logo) {
+            flags = ActionBar.DISPLAY_USE_LOGO;
+            getSupportActionBar().setLogo(R.drawable.ic_media_play);
+        } else if (id == R.id.toggle_show_title) {
+            flags = ActionBar.DISPLAY_SHOW_TITLE;
+        } else if (id == R.id.toggle_show_custom) {
+            flags = ActionBar.DISPLAY_SHOW_CUSTOM;
+        } else if (id == R.id.cycle_custom_gravity) {
+            ActionBar.LayoutParams lp = mCustomViewLayoutParams;
+            int newGravity = 0;
+            switch (lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                case Gravity.LEFT:
+                    newGravity = Gravity.CENTER_HORIZONTAL;
+                    break;
+                case Gravity.CENTER_HORIZONTAL:
+                    newGravity = Gravity.RIGHT;
+                    break;
+                case Gravity.RIGHT:
+                    newGravity = Gravity.LEFT;
+                    break;
             }
-            case R.id.toggle_visibility:
-                if (bar.isShowing()) {
-                    bar.hide();
-                } else {
-                    bar.show();
-                }
-                return;
+            lp.gravity = (lp.gravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) | newGravity;
+            bar.setCustomView(mCustomView, lp);
+            return;
+        } else if (id == R.id.toggle_visibility) {
+            if (bar.isShowing()) {
+                bar.hide();
+            } else {
+                bar.show();
+            }
+            return;
         }
 
         int change = bar.getDisplayOptions() ^ flags;
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteActivity.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteActivity.java
index d98583a..3eed2a3 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteActivity.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteActivity.java
@@ -112,27 +112,27 @@
 
         @Override
         public boolean onOptionsItemSelected(MenuItem item) {
-            switch (item.getItemId()) {
-                case R.id.menu_num_colors_8:
-                    mAdapter.setNumColors(8);
-                    item.setChecked(true);
-                    return true;
-                case R.id.menu_num_colors_12:
-                    mAdapter.setNumColors(12);
-                    item.setChecked(true);
-                    return true;
-                case R.id.menu_num_colors_16:
-                    mAdapter.setNumColors(16);
-                    item.setChecked(true);
-                    return true;
-                case R.id.menu_num_colors_24:
-                    mAdapter.setNumColors(24);
-                    item.setChecked(true);
-                    return true;
-                case R.id.menu_num_colors_32:
-                    mAdapter.setNumColors(32);
-                    item.setChecked(true);
-                    return true;
+            int itemId = item.getItemId();
+            if (itemId == R.id.menu_num_colors_8) {
+                mAdapter.setNumColors(8);
+                item.setChecked(true);
+                return true;
+            } else if (itemId == R.id.menu_num_colors_12) {
+                mAdapter.setNumColors(12);
+                item.setChecked(true);
+                return true;
+            } else if (itemId == R.id.menu_num_colors_16) {
+                mAdapter.setNumColors(16);
+                item.setChecked(true);
+                return true;
+            } else if (itemId == R.id.menu_num_colors_24) {
+                mAdapter.setNumColors(24);
+                item.setChecked(true);
+                return true;
+            } else if (itemId == R.id.menu_num_colors_32) {
+                mAdapter.setNumColors(32);
+                item.setChecked(true);
+                return true;
             }
 
             return super.onOptionsItemSelected(item);
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteDetailActivity.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteDetailActivity.java
index bbd39ea..2ad9c3a 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteDetailActivity.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/graphics/PaletteDetailActivity.java
@@ -96,27 +96,27 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.menu_num_colors_8:
-                loadImage(8);
-                item.setChecked(true);
-                return true;
-            case R.id.menu_num_colors_12:
-                loadImage(12);
-                item.setChecked(true);
-                return true;
-            case R.id.menu_num_colors_16:
-                loadImage(16);
-                item.setChecked(true);
-                return true;
-            case R.id.menu_num_colors_24:
-                loadImage(24);
-                item.setChecked(true);
-                return true;
-            case R.id.menu_num_colors_32:
-                loadImage(32);
-                item.setChecked(true);
-                return true;
+        int itemId = item.getItemId();
+        if (itemId == R.id.menu_num_colors_8) {
+            loadImage(8);
+            item.setChecked(true);
+            return true;
+        } else if (itemId == R.id.menu_num_colors_12) {
+            loadImage(12);
+            item.setChecked(true);
+            return true;
+        } else if (itemId == R.id.menu_num_colors_16) {
+            loadImage(16);
+            item.setChecked(true);
+            return true;
+        } else if (itemId == R.id.menu_num_colors_24) {
+            loadImage(24);
+            item.setChecked(true);
+            return true;
+        } else if (itemId == R.id.menu_num_colors_32) {
+            loadImage(32);
+            item.setChecked(true);
+            return true;
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/view/CardViewActivity.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/view/CardViewActivity.java
index 7cd5e7a..4e6ff95 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/view/CardViewActivity.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/view/CardViewActivity.java
@@ -170,21 +170,19 @@
     }
 
     private int getColorId(int id) {
-        switch (id) {
-            case R.id.yellow:
-                return R.color.card_yellow;
-            case R.id.aquatic:
-                return R.color.card_aquatic;
-            case R.id.classic:
-                return R.color.card_classic;
-            case R.id.sunbrite:
-                return R.color.card_sunbrite;
-            case R.id.tropical:
-                return R.color.card_tropical;
-            case R.id.selector:
-                return R.color.card_selector;
-            default:
-                return androidx.cardview.R.color.cardview_light_background;
+        if (id == R.id.yellow) {
+            return R.color.card_yellow;
+        } else if (id == R.id.aquatic) {
+            return R.color.card_aquatic;
+        } else if (id == R.id.classic) {
+            return R.color.card_classic;
+        } else if (id == R.id.sunbrite) {
+            return R.color.card_sunbrite;
+        } else if (id == R.id.tropical) {
+            return R.color.card_tropical;
+        } else if (id == R.id.selector) {
+            return R.color.card_selector;
         }
+        return androidx.cardview.R.color.cardview_light_background;
     }
 }
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/view/SystemUIModes.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/view/SystemUIModes.java
index c39b9c8..debcaed 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/view/SystemUIModes.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/view/SystemUIModes.java
@@ -16,8 +16,6 @@
 
 package com.example.androidx.view;
 
-import static android.os.Build.VERSION.SDK_INT;
-
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.Intent;
@@ -240,15 +238,15 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.show_tabs:
-                getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-                item.setChecked(true);
-                return true;
-            case R.id.hide_tabs:
-                getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-                item.setChecked(true);
-                return true;
+        int itemId = item.getItemId();
+        if (itemId == R.id.show_tabs) {
+            getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+            item.setChecked(true);
+            return true;
+        } else if (itemId == R.id.hide_tabs) {
+            getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+            item.setChecked(true);
+            return true;
         }
         return false;
     }
@@ -332,9 +330,7 @@
             public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                 mode.setTitle("My Action Mode!");
                 mode.setSubtitle(null);
-                if (SDK_INT >= 16) {
-                    mode.setTitleOptionalHint(false);
-                }
+                mode.setTitleOptionalHint(false);
                 menu.add("Sort By Size").setIcon(android.R.drawable.ic_menu_sort_by_size);
                 menu.add("Sort By Alpha").setIcon(android.R.drawable.ic_menu_sort_alphabetically);
                 return true;
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/selection/fancy/FancySelectionDemoActivity.java b/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/selection/fancy/FancySelectionDemoActivity.java
index 15fa441..40d5f95 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/selection/fancy/FancySelectionDemoActivity.java
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/selection/fancy/FancySelectionDemoActivity.java
@@ -252,16 +252,13 @@
         getMenuInflater().inflate(R.menu.selection_demo_actions, menu);
         for (int i = 0; i < menu.size(); i++) {
             MenuItem item = menu.getItem(i);
-            switch (item.getItemId()) {
-                case R.id.option_menu_more_cheese:
-                    item.setChecked(mAdapter.allCheesesEnabled());
-                    break;
-                case R.id.option_menu_grid_layout:
-                    item.setChecked(mAdapter.smallItemLayoutEnabled());
-                    break;
-                case R.id.option_menu_swipe_during_select:
-                    item.setChecked(mSwipeDuringSelectionEnabled);
-                    break;
+            int itemId = item.getItemId();
+            if (itemId == R.id.option_menu_more_cheese) {
+                item.setChecked(mAdapter.allCheesesEnabled());
+            } else if (itemId == R.id.option_menu_grid_layout) {
+                item.setChecked(mAdapter.smallItemLayoutEnabled());
+            } else if (itemId == R.id.option_menu_swipe_during_select) {
+                item.setChecked(mSwipeDuringSelectionEnabled);
             }
         }
         return showMenu;
@@ -277,19 +274,16 @@
     }
 
     private void updateOptionFromMenu(@NonNull MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.option_menu_more_cheese:
-                mAdapter.enableAllCheeses(item.isChecked());
-                mAdapter.refresh();
-                break;
-            case R.id.option_menu_grid_layout:
-                mAdapter.enableSmallItemLayout(item.isChecked());
-                mLayout.setSpanCount(item.isChecked() ? 2 : 1);
-                mAdapter.refresh();
-                break;
-            case R.id.option_menu_swipe_during_select:
-                mSwipeDuringSelectionEnabled = item.isChecked();
-                break;
+        int itemId = item.getItemId();
+        if (itemId == R.id.option_menu_more_cheese) {
+            mAdapter.enableAllCheeses(item.isChecked());
+            mAdapter.refresh();
+        } else if (itemId == R.id.option_menu_grid_layout) {
+            mAdapter.enableSmallItemLayout(item.isChecked());
+            mLayout.setSpanCount(item.isChecked() ? 2 : 1);
+            mAdapter.refresh();
+        } else if (itemId == R.id.option_menu_swipe_during_select) {
+            mSwipeDuringSelectionEnabled = item.isChecked();
         }
     }
 
@@ -315,14 +309,13 @@
 
     @Override
     public boolean onContextItemSelected(@NonNull MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.option_menu_item_eat_single:
-            case R.id.option_menu_item_eat_multiple:
-                toast(this, "Num, num, num...done!");
-                return true;
-            default:
-                return super.onContextItemSelected(item);
+        int itemId = item.getItemId();
+        if (itemId == R.id.option_menu_item_eat_single
+                || itemId == R.id.option_menu_item_eat_multiple) {
+            toast(this, "Num, num, num...done!");
+            return true;
         }
+        return super.onContextItemSelected(item);
     }
 
     @SuppressWarnings("deprecation")
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java
index 9247677..3f11908 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java
@@ -661,9 +661,7 @@
 
             if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
                 mPlayer = Player.create(MainActivity.this, selectedRoute, mMediaSession);
-                if (isPresentationApiSupported()) {
-                    mPlayer.updatePresentation();
-                }
+                mPlayer.updatePresentation();
                 mSessionManager.setPlayer(mPlayer);
             }
             updateUi();
@@ -678,9 +676,7 @@
                 mMediaSession.setActive(false);
                 mSessionManager.stop();
 
-                if (isPresentationApiSupported()) {
-                    mPlayer.updatePresentation();
-                }
+                mPlayer.updatePresentation();
                 mPlayer.release();
             }
         }
@@ -694,9 +690,7 @@
         public void onRoutePresentationDisplayChanged(
                 @NonNull MediaRouter router, @NonNull RouteInfo route) {
             Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
-            if (isPresentationApiSupported()) {
-                mPlayer.updatePresentation();
-            }
+            mPlayer.updatePresentation();
         }
 
         @Override
@@ -713,10 +707,6 @@
         public void onProviderChanged(@NonNull MediaRouter router, @NonNull ProviderInfo provider) {
             Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
         }
-
-        private boolean isPresentationApiSupported() {
-            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
-        }
     }
 
     /**
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRouteUtils.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRouteUtils.java
deleted file mode 100644
index 461350d..0000000
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRouteUtils.java
+++ /dev/null
@@ -1,62 +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 com.example.androidx.mediarouting.activities.systemrouting;
-
-import android.media.MediaRouter;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-
-/**
- * Utils for {@link SystemRouteItem}.
- */
-public final class SystemRouteUtils {
-
-    private SystemRouteUtils() {
-        // Private on purpose.
-    }
-
-    /**
-     * Checks whether {@link MediaRouter.RouteInfo} is a system route or not.
-     */
-    @RequiresApi(16)
-    public static boolean isSystemMediaRouterRoute(@NonNull MediaRouter.RouteInfo routeInfo) {
-        return routeInfo.getClass() == MediaRouter.RouteInfo.class;
-    }
-
-    /**
-     * Converts {@link SystemRoutesSourceItem.Type} to a human-readable string.
-     */
-    @NonNull
-    public static String getDescriptionForSource(@SystemRoutesSourceItem.Type int type) {
-        switch (type) {
-            case SystemRoutesSourceItem.ROUTE_SOURCE_MEDIA_ROUTER:
-                return "Legacy MediaRouter";
-            case SystemRoutesSourceItem.ROUTE_SOURCE_MEDIA_ROUTER2:
-                return "MediaRouter2";
-            case SystemRoutesSourceItem.ROUTE_SOURCE_BLUETOOTH_MANAGER:
-                return "BluetoothManager";
-            case SystemRoutesSourceItem.ROUTE_SOURCE_ANDROIDX_ROUTER:
-                return "AndroidX MediaRouter";
-            case SystemRoutesSourceItem.ROUTE_SOURCE_AUDIO_MANAGER:
-                return "AudioManager";
-            default:
-                throw new IllegalArgumentException("Unknown system route type: " + type);
-        }
-    }
-
-}
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesAdapter.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesAdapter.java
index f1dc42f..aba49a1 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesAdapter.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesAdapter.java
@@ -104,8 +104,7 @@
         }
 
         void bind(SystemRoutesSourceItem systemRoutesSourceItem) {
-            mHeaderTitleTextView.setText(
-                    SystemRouteUtils.getDescriptionForSource(systemRoutesSourceItem.getType()));
+            mHeaderTitleTextView.setText(systemRoutesSourceItem.getSourceName());
         }
     }
 
@@ -150,8 +149,7 @@
                         ((SystemRouteItem) newItem).getId());
             } else if (oldItem instanceof SystemRoutesSourceItem
                     && newItem instanceof SystemRoutesSourceItem) {
-                return ((SystemRoutesSourceItem) oldItem).getType()
-                        == ((SystemRoutesSourceItem) newItem).getType();
+                return oldItem.equals(newItem);
             } else {
                 return false;
             }
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesSourceItem.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesSourceItem.java
index 243cd81..9a5129e 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesSourceItem.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutesSourceItem.java
@@ -16,47 +16,26 @@
 
 package com.example.androidx.mediarouting.activities.systemrouting;
 
-import androidx.annotation.IntDef;
+import android.text.TextUtils;
+
 import androidx.annotation.NonNull;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
  * A model that holds data about a system routes source.
  */
 public final class SystemRoutesSourceItem implements SystemRoutesAdapterItem {
-    public static final int ROUTE_SOURCE_MEDIA_ROUTER = 0;
-    public static final int ROUTE_SOURCE_MEDIA_ROUTER2 = 1;
-    public static final int ROUTE_SOURCE_ANDROIDX_ROUTER = 2;
-    public static final int ROUTE_SOURCE_BLUETOOTH_MANAGER = 3;
-    public static final int ROUTE_SOURCE_AUDIO_MANAGER = 4;
 
-    @IntDef({
-            ROUTE_SOURCE_MEDIA_ROUTER,
-            ROUTE_SOURCE_MEDIA_ROUTER2,
-            ROUTE_SOURCE_ANDROIDX_ROUTER,
-            ROUTE_SOURCE_BLUETOOTH_MANAGER,
-            ROUTE_SOURCE_AUDIO_MANAGER
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {
+    @NonNull private final String mName;
+
+    public SystemRoutesSourceItem(@NonNull String name) {
+        mName = name;
     }
 
-    @Type
-    private final int mType;
-
-    private SystemRoutesSourceItem(@NonNull Builder builder) {
-        mType = builder.mType;
-    }
-
-    /**
-     * Returns a route source item type.
-     * see {@link SystemRoutesSourceItem.Type}
-     */
-    public int getType() {
-        return mType;
+    @NonNull
+    public String getSourceName() {
+        return mName;
     }
 
     @Override
@@ -64,32 +43,11 @@
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         SystemRoutesSourceItem that = (SystemRoutesSourceItem) o;
-        return mType == that.mType;
+        return TextUtils.equals(mName, that.mName);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mType);
-    }
-
-    /**
-     * Helps to construct {@link SystemRoutesSourceItem}.
-     */
-    public static final class Builder {
-
-        @Type
-        private final int mType;
-
-        public Builder(@Type int type) {
-            mType = type;
-        }
-
-        /**
-         * Builds {@link SystemRoutesSourceItem}.
-         */
-        @NonNull
-        public SystemRoutesSourceItem build() {
-            return new SystemRoutesSourceItem(this);
-        }
+        return Objects.hash(mName);
     }
 }
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutingActivity.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutingActivity.java
index 965156a..73d57fe 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutingActivity.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/SystemRoutingActivity.java
@@ -152,9 +152,7 @@
     private void initializeSystemRoutesSources() {
         mSystemRoutesSources.clear();
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            mSystemRoutesSources.add(MediaRouterSystemRoutesSource.create(/* context= */ this));
-        }
+        mSystemRoutesSources.add(MediaRouterSystemRoutesSource.create(/* context= */ this));
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
             mSystemRoutesSources.add(MediaRouter2SystemRoutesSource.create(/* context= */ this));
@@ -162,8 +160,7 @@
 
         mSystemRoutesSources.add(AndroidXMediaRouterSystemRoutesSource.create(/* context= */ this));
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
-                && hasBluetoothPermission()) {
+        if (hasBluetoothPermission()) {
             mSystemRoutesSources.add(
                     BluetoothManagerSystemRoutesSource.create(/* context= */ this));
         }
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AndroidXMediaRouterSystemRoutesSource.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AndroidXMediaRouterSystemRoutesSource.java
index c8b5a0f..7e553ed 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AndroidXMediaRouterSystemRoutesSource.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AndroidXMediaRouterSystemRoutesSource.java
@@ -79,9 +79,7 @@
     @NonNull
     @Override
     public SystemRoutesSourceItem getSourceItem() {
-        return new SystemRoutesSourceItem.Builder(
-                SystemRoutesSourceItem.ROUTE_SOURCE_ANDROIDX_ROUTER)
-                .build();
+        return new SystemRoutesSourceItem(/* name= */ "AndroidX MediaRouter");
     }
 
     @NonNull
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AudioManagerSystemRoutesSource.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AudioManagerSystemRoutesSource.java
index 7d37502..80d6e33 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AudioManagerSystemRoutesSource.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/AudioManagerSystemRoutesSource.java
@@ -80,8 +80,7 @@
     @NonNull
     @Override
     public SystemRoutesSourceItem getSourceItem() {
-        return new SystemRoutesSourceItem.Builder(SystemRoutesSourceItem.ROUTE_SOURCE_AUDIO_MANAGER)
-                .build();
+        return new SystemRoutesSourceItem(/* name= */ "AudioManager");
     }
 
     @NonNull
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/BluetoothManagerSystemRoutesSource.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/BluetoothManagerSystemRoutesSource.java
index d58bd15..96fab5b 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/BluetoothManagerSystemRoutesSource.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/BluetoothManagerSystemRoutesSource.java
@@ -28,10 +28,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.os.Build;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RequiresPermission;
 import androidx.core.content.IntentCompat;
 
@@ -42,7 +40,6 @@
 import java.util.List;
 
 /** Implements {@link SystemRoutesSource} using {@link BluetoothManager}. */
-@RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
 public final class BluetoothManagerSystemRoutesSource extends SystemRoutesSource {
 
     @NonNull
@@ -91,9 +88,7 @@
     @NonNull
     @Override
     public SystemRoutesSourceItem getSourceItem() {
-        return new SystemRoutesSourceItem.Builder(
-                SystemRoutesSourceItem.ROUTE_SOURCE_BLUETOOTH_MANAGER)
-                .build();
+        return new SystemRoutesSourceItem(/* name= */ "BluetoothManager");
     }
 
     @NonNull
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouter2SystemRoutesSource.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouter2SystemRoutesSource.java
index 2fc08fa..5785679 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouter2SystemRoutesSource.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouter2SystemRoutesSource.java
@@ -103,8 +103,7 @@
     @NonNull
     @Override
     public SystemRoutesSourceItem getSourceItem() {
-        return new SystemRoutesSourceItem.Builder(SystemRoutesSourceItem.ROUTE_SOURCE_MEDIA_ROUTER2)
-                .build();
+        return new SystemRoutesSourceItem(/* name= */ "MediaRouter2");
     }
 
     @NonNull
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouterSystemRoutesSource.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouterSystemRoutesSource.java
index 9457823..438ccfc 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouterSystemRoutesSource.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/systemrouting/source/MediaRouterSystemRoutesSource.java
@@ -18,22 +18,16 @@
 
 import android.content.Context;
 import android.media.MediaRouter;
-import android.os.Build;
 
-import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 
 import com.example.androidx.mediarouting.activities.systemrouting.SystemRouteItem;
-import com.example.androidx.mediarouting.activities.systemrouting.SystemRouteUtils;
 import com.example.androidx.mediarouting.activities.systemrouting.SystemRoutesSourceItem;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /** Implements {@link SystemRoutesSource} using {@link MediaRouter}. */
-@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
 public final class MediaRouterSystemRoutesSource extends SystemRoutesSource {
 
     @NonNull
@@ -79,8 +73,7 @@
     @NonNull
     @Override
     public SystemRoutesSourceItem getSourceItem() {
-        return new SystemRoutesSourceItem.Builder(SystemRoutesSourceItem.ROUTE_SOURCE_MEDIA_ROUTER)
-                .build();
+        return new SystemRoutesSourceItem(/* name= */ "Legacy MediaRouter");
     }
 
     @NonNull
@@ -92,12 +85,10 @@
 
         for (int i = 0; i < count; i++) {
             MediaRouter.RouteInfo info = mMediaRouter.getRouteAt(i);
-
-            if (!SystemRouteUtils.isSystemMediaRouterRoute(info)) {
-                continue;
+            if (info.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_LOCAL) {
+                // We are only interested in system routes.
+                out.add(createRouteItemFor(info));
             }
-
-            out.add(createRouteItemFor(info));
         }
 
         return out;
@@ -109,27 +100,11 @@
                 new SystemRouteItem.Builder(/* id= */ routeInfo.getName().toString())
                         .setName(routeInfo.getName().toString());
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-            CharSequence description = Api18Impl.getDescription(routeInfo);
-
-            if (description != null) {
-                builder.setDescription(String.valueOf(description));
-            }
+        CharSequence description = routeInfo.getDescription();
+        if (description != null) {
+            builder.setDescription(String.valueOf(description));
         }
 
         return builder.build();
     }
-
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        @Nullable
-        static CharSequence getDescription(MediaRouter.RouteInfo routeInfo) {
-            return routeInfo.getDescription();
-        }
-    }
 }
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentContextMenuSupport.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentContextMenuSupport.java
index a350afb..2e242b5 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentContextMenuSupport.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentContextMenuSupport.java
@@ -65,13 +65,13 @@
 
         @Override
         public boolean onContextItemSelected(MenuItem item) {
-            switch (item.getItemId()) {
-                case R.id.a_item:
-                    Log.i("ContextMenu", "Item 1a was chosen");
-                    return true;
-                case R.id.b_item:
-                    Log.i("ContextMenu", "Item 1b was chosen");
-                    return true;
+            int itemId = item.getItemId();
+            if (itemId == R.id.a_item) {
+                Log.i("ContextMenu", "Item 1a was chosen");
+                return true;
+            } else if (itemId == R.id.b_item) {
+                Log.i("ContextMenu", "Item 1b was chosen");
+                return true;
             }
             return super.onContextItemSelected(item);
         }
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/graphics/DrawableCompatActivity.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/graphics/DrawableCompatActivity.java
index 47d8d96..6dfd07d1 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/graphics/DrawableCompatActivity.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/graphics/DrawableCompatActivity.java
@@ -54,16 +54,12 @@
         rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(RadioGroup radioGroup, int id) {
-                switch (id) {
-                    case R.id.drawable_compat_no_tint:
-                        clearTint();
-                        break;
-                    case R.id.drawable_compat_color:
-                        setColorTint();
-                        break;
-                    case R.id.drawable_compat_state_list:
-                        setColorStateListTint();
-                        break;
+                if (id == R.id.drawable_compat_no_tint) {
+                    clearTint();
+                } else if (id == R.id.drawable_compat_color) {
+                    setColorTint();
+                } else if (id == R.id.drawable_compat_state_list) {
+                    setColorStateListTint();
                 }
             }
         });
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/QueueFragment.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/QueueFragment.java
index a1246cf..800b54f 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/QueueFragment.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/QueueFragment.java
@@ -255,24 +255,21 @@
         public void onClick(View v) {
             final int state = mPlaybackState == null ?
                     PlaybackStateCompat.STATE_NONE : mPlaybackState.getState();
-            switch (v.getId()) {
-                case R.id.play_pause:
-                    Log.d(TAG, "Play button pressed, in state " + state);
-                    if (state == PlaybackStateCompat.STATE_PAUSED ||
-                            state == PlaybackStateCompat.STATE_STOPPED ||
-                            state == PlaybackStateCompat.STATE_NONE) {
-                        playMedia();
-                    } else if (state == PlaybackStateCompat.STATE_PLAYING) {
-                        pauseMedia();
-                    }
-                    break;
-                case R.id.skip_previous:
-                    Log.d(TAG, "Start button pressed, in state " + state);
-                    skipToPrevious();
-                    break;
-                case R.id.skip_next:
-                    skipToNext();
-                    break;
+            int id = v.getId();
+            if (id == R.id.play_pause) {
+                Log.d(TAG, "Play button pressed, in state " + state);
+                if (state == PlaybackStateCompat.STATE_PAUSED
+                        || state == PlaybackStateCompat.STATE_STOPPED
+                        || state == PlaybackStateCompat.STATE_NONE) {
+                    playMedia();
+                } else if (state == PlaybackStateCompat.STATE_PLAYING) {
+                    pauseMedia();
+                }
+            } else if (id == R.id.skip_previous) {
+                Log.d(TAG, "Start button pressed, in state " + state);
+                skipToPrevious();
+            } else if (id == R.id.skip_next) {
+                skipToNext();
             }
         }
     };
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java
index 423cbfc..adf2b8d 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java
@@ -166,11 +166,10 @@
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         final int id = item.getItemId();
-        switch(id) {
-            case R.id.force_refresh:
-                mSwipeRefreshWidget.setRefreshing(true);
-                refresh();
-                return true;
+        if (id == R.id.force_refresh) {
+            mSwipeRefreshWidget.setRefreshing(true);
+            refresh();
+            return true;
         }
         return false;
     }
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java
index 0133412..af4b870 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java
@@ -73,17 +73,15 @@
 
     @Override
     public void onClick(View v) {
-        switch (v.getId()) {
-            case R.id.show:
-                mBar.show();
-                mShowTime = System.currentTimeMillis();
-                mShowText.setText("Show clicked at " + mShowTime);
-                break;
-            case R.id.hide:
-                mBar.hide();
-                mHideTime = System.currentTimeMillis();
-                mHideText.setText("Hide clicked at " + mHideTime);
-                break;
+        int id = v.getId();
+        if (id == R.id.show) {
+            mBar.show();
+            mShowTime = System.currentTimeMillis();
+            mShowText.setText("Show clicked at " + mShowTime);
+        } else if (id == R.id.hide) {
+            mBar.hide();
+            mHideTime = System.currentTimeMillis();
+            mHideText.setText("Hide clicked at " + mHideTime);
         }
     }
 
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
index 3c84764..6e61388 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
@@ -108,19 +108,19 @@
 
     @Override
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.lock_mode_unlocked:
-                mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_UNLOCKED);
-                return true;
-            case R.id.lock_mode_locked_open:
-                mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_LOCKED_OPEN);
-                return true;
-            case R.id.lock_mode_locked_closed:
-                mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_LOCKED_CLOSED);
-                return true;
-            case R.id.lock_mode_locked:
-                mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_LOCKED);
-                return true;
+        int itemId = item.getItemId();
+        if (itemId == R.id.lock_mode_unlocked) {
+            mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_UNLOCKED);
+            return true;
+        } else if (itemId == R.id.lock_mode_locked_open) {
+            mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_LOCKED_OPEN);
+            return true;
+        } else if (itemId == R.id.lock_mode_locked_closed) {
+            mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_LOCKED_CLOSED);
+            return true;
+        } else if (itemId == R.id.lock_mode_locked) {
+            mSlidingLayout.setLockMode(SlidingPaneLayout.LOCK_MODE_LOCKED);
+            return true;
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java b/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java
index a615a78..d8429a2 100644
--- a/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java
+++ b/samples/SupportContentDemos/src/main/java/com/example/android/support/content/demos/ContentPagerDemoActivity.java
@@ -83,26 +83,14 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-
-        switch (item.getItemId()) {
-            case R.id.action_load:
-                onLoadContent();
-                break;
-            case R.id.action_previous:
-                onLoadPreviousPage();
-                break;
-            case R.id.action_next:
-                onLoadNextPage();
-                break;
-        }
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        int id = item.getItemId();
-
-        //noinspection SimplifiableIfStatement
-        if (id == R.id.action_load) {
+        int itemId = item.getItemId();
+        if (itemId == R.id.action_load) {
+            onLoadContent();
             return true;
+        } else if (itemId == R.id.action_previous) {
+            onLoadPreviousPage();
+        } else if (itemId == R.id.action_next) {
+            onLoadNextPage();
         }
 
         return super.onOptionsItemSelected(item);
diff --git a/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/ChangeImageTransformUsage.java b/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/ChangeImageTransformUsage.java
index a8198d5..c789534 100644
--- a/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/ChangeImageTransformUsage.java
+++ b/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/ChangeImageTransformUsage.java
@@ -52,29 +52,23 @@
             @Override
             public void onClick(View v) {
                 TransitionManager.beginDelayedTransition(mRoot, TRANSITION);
-                switch (v.getId()) {
-                    case R.id.fit_xy:
-                        mPhoto.setScaleType(ImageView.ScaleType.FIT_XY);
-                        break;
-                    case R.id.center:
-                        mPhoto.setScaleType(ImageView.ScaleType.CENTER);
-                        break;
-                    case R.id.center_crop:
-                        mPhoto.setScaleType(ImageView.ScaleType.CENTER_CROP);
-                        break;
-                    case R.id.fit_start:
-                        mPhoto.setScaleType(ImageView.ScaleType.FIT_START);
-                        break;
-                    case R.id.fit_end:
-                        mPhoto.setScaleType(ImageView.ScaleType.FIT_END);
-                        break;
-                    case R.id.matrix:
-                        mPhoto.setScaleType(ImageView.ScaleType.MATRIX);
-                        final Matrix matrix = new Matrix();
-                        matrix.setRotate(45.f);
-                        matrix.postTranslate(200, 10);
-                        mPhoto.setImageMatrix(matrix);
-                        break;
+                int id = v.getId();
+                if (id == R.id.fit_xy) {
+                    mPhoto.setScaleType(ImageView.ScaleType.FIT_XY);
+                } else if (id == R.id.center) {
+                    mPhoto.setScaleType(ImageView.ScaleType.CENTER);
+                } else if (id == R.id.center_crop) {
+                    mPhoto.setScaleType(ImageView.ScaleType.CENTER_CROP);
+                } else if (id == R.id.fit_start) {
+                    mPhoto.setScaleType(ImageView.ScaleType.FIT_START);
+                } else if (id == R.id.fit_end) {
+                    mPhoto.setScaleType(ImageView.ScaleType.FIT_END);
+                } else if (id == R.id.matrix) {
+                    mPhoto.setScaleType(ImageView.ScaleType.MATRIX);
+                    final Matrix matrix = new Matrix();
+                    matrix.setRotate(45.f);
+                    matrix.postTranslate(200, 10);
+                    mPhoto.setImageMatrix(matrix);
                 }
             }
         };
diff --git a/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/SceneUsageBase.java b/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/SceneUsageBase.java
index fa9d9c7..2c40b70 100644
--- a/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/SceneUsageBase.java
+++ b/samples/SupportTransitionDemos/src/main/java/com/example/android/support/transition/widget/SceneUsageBase.java
@@ -59,11 +59,10 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.action_toggle:
-                mCurrentScene = (mCurrentScene + 1) % mScenes.length;
-                go(mScenes[mCurrentScene]);
-                return true;
+        if (item.getItemId() == R.id.action_toggle) {
+            mCurrentScene = (mCurrentScene + 1) % mScenes.length;
+            go(mScenes[mCurrentScene]);
+            return true;
         }
         return false;
     }
diff --git a/security/security-app-authenticator-testing/src/androidTest/java/androidx/security/app/authenticator/TestAppAuthenticatorBuilderTest.java b/security/security-app-authenticator-testing/src/androidTest/java/androidx/security/app/authenticator/TestAppAuthenticatorBuilderTest.java
index 83d27b6..d567ce2 100644
--- a/security/security-app-authenticator-testing/src/androidTest/java/androidx/security/app/authenticator/TestAppAuthenticatorBuilderTest.java
+++ b/security/security-app-authenticator-testing/src/androidTest/java/androidx/security/app/authenticator/TestAppAuthenticatorBuilderTest.java
@@ -294,6 +294,7 @@
     public void callingAppIdentity_packageNotInstalled_returnsUnknownPackage() throws Exception {
         // The TestAppAuthenticator can be configured to treat a package as uninstalled to verify
         // scenarios where the package being queried is not available on the device.
+        final int packageUid = 10001;
         AppAuthenticator appAuthenticatorFromResource =
                 mBuilderFromResource.setPackageNotInstalled(
                         DECLARED_PACKAGE1).setPackageNotInstalled(
@@ -305,20 +306,20 @@
 
         assertEquals(AppAuthenticator.PERMISSION_DENIED_UNKNOWN_PACKAGE,
                 appAuthenticatorFromResource.checkCallingAppIdentity(
-                        DECLARED_PACKAGE1, TEST_PERMISSION));
+                        DECLARED_PACKAGE1, TEST_PERMISSION, packageUid));
         assertEquals(AppAuthenticator.PERMISSION_DENIED_UNKNOWN_PACKAGE,
                 appAuthenticatorFromInputStream.checkCallingAppIdentity(
-                        DECLARED_PACKAGE1, TEST_PERMISSION));
+                        DECLARED_PACKAGE1, TEST_PERMISSION, packageUid));
         assertEquals(AppAuthenticator.SIGNATURE_NO_MATCH,
                 appAuthenticatorFromResource.checkAppIdentity(EXPECTED_IDENTITY_PACKAGE));
         assertEquals(AppAuthenticator.SIGNATURE_NO_MATCH,
                 appAuthenticatorFromInputStream.checkAppIdentity(EXPECTED_IDENTITY_PACKAGE));
         assertThrows(SecurityException.class, () ->
                 appAuthenticatorFromResource.enforceCallingAppIdentity(
-                        DECLARED_PACKAGE1, TEST_PERMISSION));
+                        DECLARED_PACKAGE1, TEST_PERMISSION, packageUid));
         assertThrows(SecurityException.class, () ->
                 appAuthenticatorFromInputStream.enforceCallingAppIdentity(
-                        DECLARED_PACKAGE1, TEST_PERMISSION));
+                        DECLARED_PACKAGE1, TEST_PERMISSION, packageUid));
         assertThrows(SecurityException.class, () ->
                 appAuthenticatorFromResource.enforceAppIdentity(EXPECTED_IDENTITY_PACKAGE));
         assertThrows(SecurityException.class, () ->
diff --git a/security/security-app-authenticator/api/current.txt b/security/security-app-authenticator/api/current.txt
index adb40b6..3a3da2b 100644
--- a/security/security-app-authenticator/api/current.txt
+++ b/security/security-app-authenticator/api/current.txt
@@ -4,11 +4,13 @@
   public class AppAuthenticator {
     method public int checkAppIdentity(String);
     method public int checkCallingAppIdentity(String, String);
+    method public int checkCallingAppIdentity(String, String, int);
     method public int checkCallingAppIdentity(String, String, int, int);
     method public static androidx.security.app.authenticator.AppAuthenticator createFromInputStream(android.content.Context, java.io.InputStream) throws androidx.security.app.authenticator.AppAuthenticatorXmlException, java.io.IOException;
     method public static androidx.security.app.authenticator.AppAuthenticator createFromResource(android.content.Context, @XmlRes int) throws androidx.security.app.authenticator.AppAuthenticatorXmlException, java.io.IOException;
     method public void enforceAppIdentity(String);
     method public void enforceCallingAppIdentity(String, String);
+    method public void enforceCallingAppIdentity(String, String, int);
     method public void enforceCallingAppIdentity(String, String, int, int);
     field public static final int PERMISSION_DENIED_NO_MATCH = -3; // 0xfffffffd
     field public static final int PERMISSION_DENIED_PACKAGE_UID_MISMATCH = -5; // 0xfffffffb
diff --git a/security/security-app-authenticator/api/restricted_current.txt b/security/security-app-authenticator/api/restricted_current.txt
index adb40b6..3a3da2b 100644
--- a/security/security-app-authenticator/api/restricted_current.txt
+++ b/security/security-app-authenticator/api/restricted_current.txt
@@ -4,11 +4,13 @@
   public class AppAuthenticator {
     method public int checkAppIdentity(String);
     method public int checkCallingAppIdentity(String, String);
+    method public int checkCallingAppIdentity(String, String, int);
     method public int checkCallingAppIdentity(String, String, int, int);
     method public static androidx.security.app.authenticator.AppAuthenticator createFromInputStream(android.content.Context, java.io.InputStream) throws androidx.security.app.authenticator.AppAuthenticatorXmlException, java.io.IOException;
     method public static androidx.security.app.authenticator.AppAuthenticator createFromResource(android.content.Context, @XmlRes int) throws androidx.security.app.authenticator.AppAuthenticatorXmlException, java.io.IOException;
     method public void enforceAppIdentity(String);
     method public void enforceCallingAppIdentity(String, String);
+    method public void enforceCallingAppIdentity(String, String, int);
     method public void enforceCallingAppIdentity(String, String, int, int);
     field public static final int PERMISSION_DENIED_NO_MATCH = -3; // 0xfffffffd
     field public static final int PERMISSION_DENIED_PACKAGE_UID_MISMATCH = -5; // 0xfffffffb
diff --git a/security/security-app-authenticator/src/main/java/androidx/security/app/authenticator/AppAuthenticator.java b/security/security-app-authenticator/src/main/java/androidx/security/app/authenticator/AppAuthenticator.java
index b547cff..b926493 100644
--- a/security/security-app-authenticator/src/main/java/androidx/security/app/authenticator/AppAuthenticator.java
+++ b/security/security-app-authenticator/src/main/java/androidx/security/app/authenticator/AppAuthenticator.java
@@ -16,7 +16,12 @@
 
 package androidx.security.app.authenticator;
 
+import static android.os.Process.INVALID_PID;
+import static android.os.Process.INVALID_UID;
+
+import android.app.Activity;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Binder;
@@ -205,10 +210,12 @@
      * Enforces the specified {@code packageName} has the expected signing identity for the
      * provided {@code permission}.
      *
-     * <p>This method should be used when verifying the identity of a calling process of an IPC.
-     * This is the same as calling {@link #enforceCallingAppIdentity(String, String, int, int)} with
-     * the pid and uid returned by {@link Binder#getCallingPid()} and
-     * {@link Binder#getCallingUid()}.
+     * <p>This method should be used for verifying the identity of a package when the UID / PID
+     * is not available. For instance, this should be used within an activity that was started
+     * with {@link Activity#startActivityForResult(Intent, int)} where the package name is
+     * available from {@link Activity#getCallingPackage()}. For instances where the calling
+     * UID is available but the calling PID is not available,
+     * ({@link #checkCallingAppIdentity(String, String, int)} should be preferred.
      *
      * @param packageName the name of the package to be verified
      * @param permission the name of the permission as specified in the XML from which to verify the
@@ -217,15 +224,36 @@
      * for the permission
      */
     public void enforceCallingAppIdentity(@NonNull String packageName, @NonNull String permission) {
-        enforceCallingAppIdentity(packageName, permission,
-                mAppAuthenticatorUtils.getCallingPid(), mAppAuthenticatorUtils.getCallingUid());
+        enforceCallingAppIdentity(packageName, permission, INVALID_PID, INVALID_UID);
+    }
+
+    /**
+     * Enforces the specified {@code packageName} belongs to the provided {@code uid}
+     * and has the expected signing identity for the {@code permission}.
+     *
+     * <p>This method should be used for verifying the identity of a package when the UID is
+     * available but the PID is not. For instance, this should be used within an activity that
+     * is started with {@link android.app.ActivityOptions#setShareIdentityEnabled(boolean)} set to
+     * true; the package name would then be accessible via {@link Activity#getLaunchedFromPackage()}
+     * and the UID from {@link Activity#getLaunchedFromUid()}.
+     *
+     * @param packageName the name of the package to be verified
+     * @param permission the name of the permission as specified in the XML from which to verify the
+     *                   package / signing identity
+     * @param uid the expected uid of the package
+     * @throws SecurityException if the uid does not belong to the specified package, or if the
+     * signing identity of the package does not match that defined for the permission
+     */
+    public void enforceCallingAppIdentity(@NonNull String packageName, @NonNull String permission,
+            int uid) {
+        enforceCallingAppIdentity(packageName, permission, INVALID_PID, uid);
     }
 
     /**
      * Enforces the specified {@code packageName} belongs to the provided {@code pid} / {@code uid}
      * and has the expected signing identity for the {@code permission}.
      *
-     * <p>This method should be used when verifying the identity of a calling process of an IPC.
+     * <p>This method should be used for verifying the identity of a calling process of an IPC.
      *
      * @param packageName the name of the package to be verified
      * @param permission the name of the permission as specified in the XML from which to verify the
@@ -248,10 +276,12 @@
      * Checks the specified {@code packageName} has the expected signing identity for the
      * provided {@code permission}.
      *
-     * <p>This method should be used when verifying the identity of a calling process of an IPC.
-     * This is the same as calling {@link #checkCallingAppIdentity(String, String, int, int)} with
-     * the pid and uid returned by {@link Binder#getCallingPid()} and
-     * {@link Binder#getCallingUid()}.
+     * <p>This method should be used for verifying the identity of a package when the UID / PID
+     * is not available. For instance, this should be used within an activity that was started
+     * with {@link Activity#startActivityForResult(Intent, int)} where the package name is
+     * available from {@link Activity#getCallingPackage()}. For instances where the calling
+     * UID is available but the calling PID is not available,
+     * ({@link #checkCallingAppIdentity(String, String, int)} should be preferred.
      *
      * @param packageName the name of the package to be verified
      * @param permission the name of the permission as specified in the XML from which to verify the
@@ -262,20 +292,46 @@
      *     the expected signing identity for the provided {@code permission},<br>
      *     {@link #PERMISSION_DENIED_UNKNOWN_PACKAGE} if the specified {@code packageName} does not
      *     exist on the device,<br>
-     *     {@link #PERMISSION_DENIED_PACKAGE_UID_MISMATCH} if the uid as returned from
-     *     {@link Binder#getCallingUid()} does not match the uid assigned to the package
      */
     @AppIdentityPermissionResult
     public int checkCallingAppIdentity(@NonNull String packageName, @NonNull String permission) {
-        return checkCallingAppIdentity(packageName, permission,
-                mAppAuthenticatorUtils.getCallingPid(), mAppAuthenticatorUtils.getCallingUid());
+        return checkCallingAppIdentity(packageName, permission, INVALID_PID, INVALID_UID);
     }
 
     /**
-     * Checks the specified {@code packageName} has the expected signing identity for the
-     * provided {@code permission}.
+     * Checks the specified {@code packageName} running under {@code uid} has the expected
+     * signing identity for the provided {@code permission}.
      *
-     * <p>This method should be used when verifying the identity of a calling process of an IPC.
+     * <p>This method should be used for verifying the identity of a package when the UID is
+     * available but the PID is not. For instance, this should be used within an activity that
+     * is started with {@link android.app.ActivityOptions#setShareIdentityEnabled(boolean)} set to
+     * true; the package name would then be accessible via {@link Activity#getLaunchedFromPackage()}
+     * and the UID from {@link Activity#getLaunchedFromUid()}.
+     *
+     * @param packageName the name of the package to be verified
+     * @param permission the name of the permission as specified in the XML from which to verify the
+     *                   package / signing identity
+     * @param uid the expected uid of the package
+     * @return {@link #PERMISSION_GRANTED} if the specified {@code packageName} has the expected
+     * signing identity for the provided {@code permission},<br>
+     *     {@link #PERMISSION_DENIED_NO_MATCH} if the specified {@code packageName} does not have
+     *     the expected signing identity for the provided {@code permission},<br>
+     *     {@link #PERMISSION_DENIED_UNKNOWN_PACKAGE} if the specified {@code packageName} does not
+     *     exist on the device,<br>
+     *     {@link #PERMISSION_DENIED_PACKAGE_UID_MISMATCH} if the specified {@code uid} does not
+     *     match the uid assigned to the package
+     */
+    @AppIdentityPermissionResult
+    public int checkCallingAppIdentity(@NonNull String packageName, @NonNull String permission,
+            int uid) {
+        return checkCallingAppIdentity(packageName, permission, INVALID_PID, uid);
+    }
+
+    /**
+     * Checks the specified {@code packageName} running with {@code pid} and {@code uid} has the
+     * expected signing identity for the provided {@code permission}.
+     *
+     * <p>This method should be used for verifying the identity of a calling process of an IPC.
      *
      * @param packageName the name of the package to be verified
      * @param permission the name of the permission as specified in the XML from which to verify the
@@ -314,18 +370,21 @@
             String permission,
             int pid,
             int uid) {
-        // First verify that the UID of the calling package matches the specified value.
-        int packageUid;
-        try {
-            packageUid = mAppAuthenticatorUtils.getUidForPackage(packageName);
-        } catch (PackageManager.NameNotFoundException e) {
-            return AppAuthenticatorResult.create(PERMISSION_DENIED_UNKNOWN_PACKAGE,
-                    "The app " + packageName + " was not found on the device");
-        }
-        if (packageUid != uid) {
-            return AppAuthenticatorResult.create(PERMISSION_DENIED_PACKAGE_UID_MISMATCH,
-                    "The expected UID, " + uid + ", of the app " + packageName
-                            + " does not match the actual UID, " + packageUid);
+        // If a valid UID is provided, verify that the UID of the calling package matches the
+        // specified value.
+        if (uid != INVALID_UID) {
+            int packageUid;
+            try {
+                packageUid = mAppAuthenticatorUtils.getUidForPackage(packageName);
+            } catch (PackageManager.NameNotFoundException e) {
+                return AppAuthenticatorResult.create(PERMISSION_DENIED_UNKNOWN_PACKAGE,
+                        "The app " + packageName + " was not found on the device");
+            }
+            if (packageUid != uid) {
+                return AppAuthenticatorResult.create(PERMISSION_DENIED_PACKAGE_UID_MISMATCH,
+                        "The expected UID, " + uid + ", of the app " + packageName
+                                + " does not match the actual UID, " + packageUid);
+            }
         }
         if (mAppSignatureVerifier.verifySigningIdentity(packageName, permission)) {
             return AppAuthenticatorResult.create(PERMISSION_GRANTED, null);
diff --git a/security/security-app-authenticator/src/test/java/androidx/security/app/authenticator/AppAuthenticatorTest.java b/security/security-app-authenticator/src/test/java/androidx/security/app/authenticator/AppAuthenticatorTest.java
index 1e89cdf..1ec1ede 100644
--- a/security/security-app-authenticator/src/test/java/androidx/security/app/authenticator/AppAuthenticatorTest.java
+++ b/security/security-app-authenticator/src/test/java/androidx/security/app/authenticator/AppAuthenticatorTest.java
@@ -83,6 +83,7 @@
         // tests, no assertion is required as making it past this statement without a
         // SecurityException indicates the test was successful.
         mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION);
+        mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION, TEST_UID);
         mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION, TEST_PID,
                 TEST_UID);
     }
@@ -99,6 +100,9 @@
                 () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
         assertThrows(SecurityException.class,
                 () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION,
+                        TEST_UID));
+        assertThrows(SecurityException.class,
+                () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION,
                         TEST_PID, TEST_UID));
     }
 
@@ -112,7 +116,8 @@
         when(mMockAppAuthenticatorUtils.getUidForPackage(TEST_PACKAGE)).thenReturn(23456);
 
         assertThrows(SecurityException.class,
-                () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
+                () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION,
+                        TEST_UID));
         assertThrows(SecurityException.class,
                 () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION,
                         TEST_PID, TEST_UID));
@@ -123,13 +128,20 @@
         // If the specified package does not exist on the device then enforceCallingAppIdentity
         // should receive a NameNotFoundException when checking for the UID; this should result
         // in a SecurityException.
+        // true is returned here to ensure the test fails for the expected reason; a return value
+        // of false would still result in a SecurityException thrown by the method under test
+        // since any failures during an enforce call result in this exception. Returning true
+        // allows the method under test to return a successful response if package verification
+        // is incorrectly skipped, allowing the test to ensure that the SecurityException is the
+        // expected result from the package not existing on the system.
         when(mMockAppSignatureVerifier.verifySigningIdentity(TEST_PACKAGE,
                 TEST_PERMISSION)).thenReturn(true);
         when(mMockAppAuthenticatorUtils.getUidForPackage(TEST_PACKAGE)).thenThrow(
                 PackageManager.NameNotFoundException.class);
 
         assertThrows(SecurityException.class,
-                () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
+                () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION,
+                        TEST_UID));
         assertThrows(SecurityException.class,
                 () -> mAppAuthenticator.enforceCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION,
                         TEST_PID, TEST_UID));
@@ -145,6 +157,8 @@
         assertEquals(AppAuthenticator.PERMISSION_GRANTED,
                 mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
         assertEquals(AppAuthenticator.PERMISSION_GRANTED,
+                mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION, TEST_UID));
+        assertEquals(AppAuthenticator.PERMISSION_GRANTED,
                 mAppAuthenticator.checkCallingAppIdentity(
                         TEST_PACKAGE, TEST_PERMISSION, TEST_PID, TEST_UID));
     }
@@ -160,6 +174,8 @@
         assertEquals(AppAuthenticator.PERMISSION_DENIED_NO_MATCH,
                 mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
         assertEquals(AppAuthenticator.PERMISSION_DENIED_NO_MATCH,
+                mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION, TEST_UID));
+        assertEquals(AppAuthenticator.PERMISSION_DENIED_NO_MATCH,
                 mAppAuthenticator.checkCallingAppIdentity(
                         TEST_PACKAGE, TEST_PERMISSION, TEST_PID, TEST_UID));
     }
@@ -174,7 +190,7 @@
         when(mMockAppAuthenticatorUtils.getUidForPackage(TEST_PACKAGE)).thenReturn(23456);
 
         assertEquals(AppAuthenticator.PERMISSION_DENIED_PACKAGE_UID_MISMATCH,
-                mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
+                mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION), TEST_UID);
         assertEquals(AppAuthenticator.PERMISSION_DENIED_PACKAGE_UID_MISMATCH,
                 mAppAuthenticator.checkCallingAppIdentity(
                         TEST_PACKAGE, TEST_PERMISSION, TEST_PID, TEST_UID));
@@ -191,7 +207,7 @@
                 PackageManager.NameNotFoundException.class);
 
         assertEquals(AppAuthenticator.PERMISSION_DENIED_UNKNOWN_PACKAGE,
-                mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION));
+                mAppAuthenticator.checkCallingAppIdentity(TEST_PACKAGE, TEST_PERMISSION, TEST_UID));
         assertEquals(AppAuthenticator.PERMISSION_DENIED_UNKNOWN_PACKAGE,
                 mAppAuthenticator.checkCallingAppIdentity(
                         TEST_PACKAGE, TEST_PERMISSION, TEST_PID, TEST_UID));
diff --git a/settings.gradle b/settings.gradle
index 70d9dd0..3ba7212 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -867,18 +867,18 @@
 includeProject(":room:integration-tests:room-testapp-noappcompat", "room/integration-tests/noappcompattestapp", [BuildType.MAIN])
 includeProject(":room:room-benchmark", "room/benchmark", [BuildType.MAIN])
 includeProject(":room:room-common", [BuildType.MAIN, BuildType.COMPOSE, BuildType.KMP, BuildType.INFRAROGUE])
-includeProject(":room:room-compiler", [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":room:room-compiler-processing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
+includeProject(":room:room-compiler", [BuildType.MAIN, BuildType.COMPOSE, BuildType.KMP])
+includeProject(":room:room-compiler-processing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.KMP])
 includeProject(":room:room-compiler-processing-testing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
 includeProject(":room:room-guava", [BuildType.MAIN])
 includeProject(":room:room-gradle-plugin", [BuildType.MAIN])
 includeProject(":room:room-ktx", [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":room:room-migration", [BuildType.MAIN, BuildType.COMPOSE])
+includeProject(":room:room-migration", [BuildType.MAIN, BuildType.COMPOSE, BuildType.KMP])
 includeProject(":room:room-paging", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":room:room-paging-guava", [BuildType.MAIN])
 includeProject(":room:room-paging-rxjava2", [BuildType.MAIN])
 includeProject(":room:room-paging-rxjava3", [BuildType.MAIN])
-includeProject(":room:room-runtime", [BuildType.MAIN, BuildType.COMPOSE])
+includeProject(":room:room-runtime", [BuildType.MAIN, BuildType.COMPOSE, BuildType.KMP, BuildType.INFRAROGUE])
 includeProject(":room:room-runtime-lint", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":room:room-rxjava2", [BuildType.MAIN])
 includeProject(":room:room-rxjava3", [BuildType.MAIN])
@@ -987,7 +987,9 @@
 includeProject(":wear:wear-input-testing", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":wear:wear-ongoing", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":wear:wear-phone-interactions", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-phone-interactions-samples", "wear/wear-phone-interactions/samples", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":wear:wear-remote-interactions", [BuildType.MAIN, BuildType.WEAR])
+includeProject(":wear:wear-remote-interactions-samples", "wear/wear-remote-interactions/samples", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":wear:wear-samples-ambient", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":wear:wear-tooling-preview", [BuildType.MAIN, BuildType.WEAR])
 includeProject(":wear:tiles:tiles", [BuildType.MAIN, BuildType.WEAR])
diff --git a/sharetarget/integration-tests/testapp/src/main/java/androidx/sharetarget/testapp/MainActivity.java b/sharetarget/integration-tests/testapp/src/main/java/androidx/sharetarget/testapp/MainActivity.java
index d1ed33e..138d206 100644
--- a/sharetarget/integration-tests/testapp/src/main/java/androidx/sharetarget/testapp/MainActivity.java
+++ b/sharetarget/integration-tests/testapp/src/main/java/androidx/sharetarget/testapp/MainActivity.java
@@ -53,13 +53,11 @@
     private View.OnClickListener mOnClickListener = new View.OnClickListener() {
         @Override
         public void onClick(View view) {
-            switch (view.getId()) {
-                case R.id.push_targets:
-                    pushDirectShareTargets();
-                    break;
-                case R.id.remove_targets:
-                    removeAllDirectShareTargets();
-                    break;
+            int id = view.getId();
+            if (id == R.id.push_targets) {
+                pushDirectShareTargets();
+            } else if (id == R.id.remove_targets) {
+                removeAllDirectShareTargets();
             }
         }
     };
diff --git a/sharetarget/sharetarget/src/androidTest/java/androidx/sharetarget/ShortcutInfoCompatSaverTest.java b/sharetarget/sharetarget/src/androidTest/java/androidx/sharetarget/ShortcutInfoCompatSaverTest.java
index 229e42c..f3f5672 100644
--- a/sharetarget/sharetarget/src/androidTest/java/androidx/sharetarget/ShortcutInfoCompatSaverTest.java
+++ b/sharetarget/sharetarget/src/androidTest/java/androidx/sharetarget/ShortcutInfoCompatSaverTest.java
@@ -29,7 +29,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
-import android.os.Build;
 
 import androidx.annotation.NonNull;
 import androidx.core.app.Person;
@@ -39,7 +38,6 @@
 import androidx.sharetarget.test.R;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -56,7 +54,6 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ShortcutInfoCompatSaverTest {
diff --git a/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceSerializeMetrics.java b/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceSerializeMetrics.java
index cc3df0a..dc3c37d 100644
--- a/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceSerializeMetrics.java
+++ b/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceSerializeMetrics.java
@@ -40,7 +40,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Rule;
@@ -58,7 +57,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 19)
 @SuppressWarnings("deprecation")
 public class SliceSerializeMetrics {
 
diff --git a/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceViewMetrics.java b/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceViewMetrics.java
index b892033..a7ca517 100644
--- a/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceViewMetrics.java
+++ b/slice/slice-benchmark/src/androidTest/java/androidx/slice/SliceViewMetrics.java
@@ -25,7 +25,6 @@
 import androidx.slice.widget.SliceView;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -38,7 +37,6 @@
 
 @RunWith(Parameterized.class)
 @SmallTest
-@SdkSuppress(minSdkVersion = 19)
 @SuppressWarnings("deprecation")
 public class SliceViewMetrics {
 
diff --git a/slice/slice-builders-ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt b/slice/slice-builders-ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt
index 6faebd4..71dae27 100644
--- a/slice/slice-builders-ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt
+++ b/slice/slice-builders-ktx/src/androidTest/java/androidx/slice/builders/SliceBuildersKtxTest.kt
@@ -27,11 +27,9 @@
 import androidx.slice.builders.ktx.test.R
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import org.junit.Assert.assertEquals
 import org.junit.Test
 
-@SdkSuppress(minSdkVersion = 19)
 @MediumTest
 @Suppress("DEPRECATION")
 class SliceBuildersKtxTest {
diff --git a/slice/slice-core/src/androidTest/java/androidx/slice/SliceItemTest.java b/slice/slice-core/src/androidTest/java/androidx/slice/SliceItemTest.java
index 6fd9163..11a2a158 100644
--- a/slice/slice-core/src/androidTest/java/androidx/slice/SliceItemTest.java
+++ b/slice/slice-core/src/androidTest/java/androidx/slice/SliceItemTest.java
@@ -25,7 +25,6 @@
 import android.text.style.StyleSpan;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -33,7 +32,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceItemTest {
 
     @Test
diff --git a/slice/slice-core/src/androidTest/java/androidx/slice/SliceTest.java b/slice/slice-core/src/androidTest/java/androidx/slice/SliceTest.java
index 31f39d5..690edd4 100644
--- a/slice/slice-core/src/androidTest/java/androidx/slice/SliceTest.java
+++ b/slice/slice-core/src/androidTest/java/androidx/slice/SliceTest.java
@@ -51,7 +51,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,7 +62,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceTest {
 
     public static boolean sFlag = false;
diff --git a/slice/slice-core/src/androidTest/java/androidx/slice/SliceTestProvider.java b/slice/slice-core/src/androidTest/java/androidx/slice/SliceTestProvider.java
index 3e1949f..a6a41fc 100644
--- a/slice/slice-core/src/androidTest/java/androidx/slice/SliceTestProvider.java
+++ b/slice/slice-core/src/androidTest/java/androidx/slice/SliceTestProvider.java
@@ -34,9 +34,7 @@
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice.Builder;
 import androidx.slice.core.test.R;
-import androidx.test.filters.SdkSuppress;
 
-@SdkSuppress(minSdkVersion = 19)
 public class SliceTestProvider extends androidx.slice.SliceProvider {
 
     @Override
diff --git a/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java b/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java
index 583cb44..ad385d8 100644
--- a/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java
+++ b/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPermissionManagerTest.java
@@ -38,7 +38,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,7 +46,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 19)
 public class CompatPermissionManagerTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPinnedListTest.java b/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPinnedListTest.java
index b0bff92..0654fb0 100644
--- a/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPinnedListTest.java
+++ b/slice/slice-core/src/androidTest/java/androidx/slice/compat/CompatPinnedListTest.java
@@ -29,7 +29,6 @@
 import androidx.slice.SliceSpec;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import junit.framework.AssertionFailedError;
@@ -45,7 +44,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@SdkSuppress(minSdkVersion = 19)
 public class CompatPinnedListTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/slice/slice-core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java b/slice/slice-core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
index 882d888..a0ca18a 100644
--- a/slice/slice-core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
+++ b/slice/slice-core/src/androidTest/java/androidx/slice/compat/SliceProviderCompatTest.java
@@ -43,7 +43,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -53,7 +52,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceProviderCompatTest {
 
     private static final String AUTHORITY = "my.authority";
diff --git a/slice/slice-core/src/main/java/androidx/slice/SliceProvider.java b/slice/slice-core/src/main/java/androidx/slice/SliceProvider.java
index 399ba9f..edb4a01 100644
--- a/slice/slice-core/src/main/java/androidx/slice/SliceProvider.java
+++ b/slice/slice-core/src/main/java/androidx/slice/SliceProvider.java
@@ -211,7 +211,6 @@
 
     @Override
     public final boolean onCreate() {
-        if (Build.VERSION.SDK_INT < 19) return false;
         return onCreateSliceProvider();
     }
 
@@ -243,7 +242,6 @@
     @Nullable
     @Override
     public final String getType(@NonNull Uri uri) {
-        if (Build.VERSION.SDK_INT < 19) return null;
         if (DEBUG) Log.d(TAG, "getFormat " + uri);
         return SLICE_TYPE;
     }
@@ -272,7 +270,7 @@
     @Nullable
     @Override
     public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) {
-        if (Build.VERSION.SDK_INT < 19 || Build.VERSION.SDK_INT >= 28) return null;
+        if (Build.VERSION.SDK_INT >= 28) return null;
         if (extras == null) return null;
         return getSliceProviderCompat().call(method, arg, extras);
     }
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/SliceBuilderTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/SliceBuilderTest.java
index dd4f25e..b24f98d 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/SliceBuilderTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/SliceBuilderTest.java
@@ -41,7 +41,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -53,7 +52,6 @@
  */
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceBuilderTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/SliceMetadataTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/SliceMetadataTest.java
index 90a0c13..639c98b 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/SliceMetadataTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/SliceMetadataTest.java
@@ -56,7 +56,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -75,7 +74,6 @@
  */
 @RunWith(AndroidJUnit4.class)
 @MediumTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceMetadataTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java
index ec1a3eb..92ca772 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/SliceViewManagerTest.java
@@ -57,7 +57,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceViewManagerTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
@@ -111,7 +110,7 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19, maxSdkVersion = 33) // b/262909049: Failing on SDK 34
+    @SdkSuppress(maxSdkVersion = 33) // b/262909049: Failing on SDK 34
     public void testPinList() {
         if (Build.VERSION.SDK_INT == 33 && !"REL".equals(Build.VERSION.CODENAME)) {
             return; // b/262909049: Do not run this test on pre-release Android U.
@@ -140,7 +139,7 @@
         }
     }
 
-    @SdkSuppress(minSdkVersion = 19, maxSdkVersion = 27)
+    @SdkSuppress(maxSdkVersion = 27)
     @Test
     public void testCallback() {
         Uri uri = new Uri.Builder()
@@ -162,7 +161,7 @@
         verify(callback, timeout(2000)).onSliceUpdated(any(Slice.class));
     }
 
-    @SdkSuppress(minSdkVersion = 19, maxSdkVersion = 27)
+    @SdkSuppress(maxSdkVersion = 27)
     @Test
     public void testPinnedSpecs() {
         Uri uri = new Uri.Builder()
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/SliceXmlTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/SliceXmlTest.java
index df563ae..b728500 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/SliceXmlTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/SliceXmlTest.java
@@ -44,7 +44,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,7 +56,6 @@
 
 @RunWith(AndroidJUnit4.class)
 @MediumTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceXmlTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/render/RenderTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/render/RenderTest.java
index e41a676..5231c51 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/render/RenderTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/render/RenderTest.java
@@ -27,7 +27,6 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.rule.GrantPermissionRule;
@@ -46,7 +45,6 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-@SdkSuppress(minSdkVersion = 19)
 public class RenderTest {
 
     @Rule
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/widget/CachedSliceLiveDataTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/widget/CachedSliceLiveDataTest.java
index b34ad92..80db96e 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/widget/CachedSliceLiveDataTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/widget/CachedSliceLiveDataTest.java
@@ -41,7 +41,6 @@
 import androidx.slice.SliceViewManager.SliceCallback;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -60,7 +59,6 @@
 @SuppressWarnings("unchecked")
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@SdkSuppress(minSdkVersion = 19)
 public class CachedSliceLiveDataTest {
 
     private static final Uri URI = Uri.parse("content://test/something");
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceLiveDataTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceLiveDataTest.java
index fd48b3b..6b93bf3 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceLiveDataTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceLiveDataTest.java
@@ -45,7 +45,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.After;
@@ -63,7 +62,6 @@
 @SuppressWarnings("unchecked")
 @RunWith(AndroidJUnit4.class)
 @MediumTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceLiveDataTest {
 
     private static final Uri URI = Uri.parse("content://test/something");
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceStyleTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceStyleTest.java
index c39e53f..4445b5e 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceStyleTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceStyleTest.java
@@ -17,7 +17,6 @@
 package androidx.slice.widget;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
@@ -29,7 +28,6 @@
 import androidx.slice.view.test.R;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -40,7 +38,6 @@
 /** Tests for {@link SliceView}. */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceStyleTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java b/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
index f56036f..93b295c 100644
--- a/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
+++ b/slice/slice-view/src/androidTest/java/androidx/slice/widget/SliceViewTest.java
@@ -48,7 +48,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
-import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -64,7 +63,6 @@
  */
 @RunWith(AndroidJUnit4.class)
 @MediumTest
-@SdkSuppress(minSdkVersion = 19)
 public class SliceViewTest {
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
diff --git a/sqlite/sqlite-framework/src/androidTest/java/androidx/sqlite/db/framework/OpenHelperRecoveryTest.kt b/sqlite/sqlite-framework/src/androidTest/java/androidx/sqlite/db/framework/OpenHelperRecoveryTest.kt
index d307b12..4aaa045 100644
--- a/sqlite/sqlite-framework/src/androidTest/java/androidx/sqlite/db/framework/OpenHelperRecoveryTest.kt
+++ b/sqlite/sqlite-framework/src/androidTest/java/androidx/sqlite/db/framework/OpenHelperRecoveryTest.kt
@@ -18,7 +18,6 @@
 
 import android.content.Context
 import android.database.sqlite.SQLiteException
-import android.os.Build
 import androidx.sqlite.db.SupportSQLiteDatabase
 import androidx.sqlite.db.SupportSQLiteOpenHelper
 import androidx.test.core.app.ApplicationProvider
@@ -40,25 +39,23 @@
     }
     @Test
     fun delegateLaziness() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            val openHelper = FrameworkSQLiteOpenHelper(
-                context,
-                dbName,
-                EmptyCallback(),
-                false,
-                false
-            )
-            openHelper.setWriteAheadLoggingEnabled(true)
+        val openHelper = FrameworkSQLiteOpenHelper(
+            context,
+            dbName,
+            EmptyCallback(),
+            false,
+            false
+        )
+        openHelper.setWriteAheadLoggingEnabled(true)
 
-            val dbFileBeforeWritable = context.getDatabasePath(dbName)
-            assertThat(dbFileBeforeWritable.exists()).isFalse()
+        val dbFileBeforeWritable = context.getDatabasePath(dbName)
+        assertThat(dbFileBeforeWritable.exists()).isFalse()
 
-            val writableDb = openHelper.writableDatabase
-            val dbFileAfterWritable = context.getDatabasePath(dbName)
+        val writableDb = openHelper.writableDatabase
+        val dbFileAfterWritable = context.getDatabasePath(dbName)
 
-            assertThat(dbFileAfterWritable.exists()).isTrue()
-            assertThat(writableDb.isWriteAheadLoggingEnabled).isTrue()
-        }
+        assertThat(dbFileAfterWritable.exists()).isTrue()
+        assertThat(writableDb.isWriteAheadLoggingEnabled).isTrue()
     }
 
     @Test
diff --git a/sqliteMultiplatform/sqlite-driver-unbundled/src/androidMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.kt b/sqliteMultiplatform/sqlite-driver-unbundled/src/androidMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.android.kt
similarity index 100%
rename from sqliteMultiplatform/sqlite-driver-unbundled/src/androidMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.kt
rename to sqliteMultiplatform/sqlite-driver-unbundled/src/androidMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.android.kt
diff --git a/sqliteMultiplatform/sqlite-driver-unbundled/src/jvmMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.kt b/sqliteMultiplatform/sqlite-driver-unbundled/src/jvmMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.jvm.kt
similarity index 100%
rename from sqliteMultiplatform/sqlite-driver-unbundled/src/jvmMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.kt
rename to sqliteMultiplatform/sqlite-driver-unbundled/src/jvmMain/kotlin/androidx/sqliteMultiplatform/unbundled/NativeLibraryLoader.jvm.kt
diff --git a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt
index aaf77af..8ca3a1e 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt
@@ -17,10 +17,10 @@
 package com.android.build.gradle.internal.fixtures
 
 import java.util.function.BiFunction
-import java.util.function.Predicate
 import org.gradle.api.Transformer
 import org.gradle.api.provider.Property
 import org.gradle.api.provider.Provider
+import org.gradle.api.specs.Spec
 
 class FakeGradleProperty<T>(private var value: T? = null) : Property<T> {
 
@@ -47,8 +47,7 @@
         value ?: valueProvider?.get() ?: convention ?: throw IllegalStateException("Value not set")
 
     override fun getOrNull() = value ?: valueProvider?.get() ?: convention
-
-    override fun filter(predicate: Predicate<in T>): Provider<T> {
+    override fun filter(spec: Spec<in T>): Provider<T> {
         throw NotImplementedError()
     }
 
diff --git a/test/uiautomator/uiautomator/api/2.3.0-beta01.txt b/test/uiautomator/uiautomator/api/2.3.0-beta01.txt
new file mode 100644
index 0000000..bfaecd4
--- /dev/null
+++ b/test/uiautomator/uiautomator/api/2.3.0-beta01.txt
@@ -0,0 +1,467 @@
+// Signature format: 4.0
+package androidx.test.uiautomator {
+
+  public class By {
+    method public static androidx.test.uiautomator.BySelector checkable(boolean);
+    method public static androidx.test.uiautomator.BySelector checked(boolean);
+    method public static androidx.test.uiautomator.BySelector clazz(Class);
+    method public static androidx.test.uiautomator.BySelector clazz(String);
+    method public static androidx.test.uiautomator.BySelector clazz(String, String);
+    method public static androidx.test.uiautomator.BySelector clazz(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector clickable(boolean);
+    method public static androidx.test.uiautomator.BySelector copy(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector depth(int);
+    method public static androidx.test.uiautomator.BySelector desc(String);
+    method public static androidx.test.uiautomator.BySelector desc(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector descContains(String);
+    method public static androidx.test.uiautomator.BySelector descEndsWith(String);
+    method public static androidx.test.uiautomator.BySelector descStartsWith(String);
+    method @RequiresApi(30) public static androidx.test.uiautomator.BySelector displayId(int);
+    method public static androidx.test.uiautomator.BySelector enabled(boolean);
+    method public static androidx.test.uiautomator.BySelector focusable(boolean);
+    method public static androidx.test.uiautomator.BySelector focused(boolean);
+    method public static androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector, @IntRange(from=1) int);
+    method public static androidx.test.uiautomator.BySelector hasChild(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector, int);
+    method public static androidx.test.uiautomator.BySelector hasParent(androidx.test.uiautomator.BySelector);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hint(String);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hint(java.util.regex.Pattern);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hintContains(String);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hintEndsWith(String);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hintStartsWith(String);
+    method public static androidx.test.uiautomator.BySelector longClickable(boolean);
+    method public static androidx.test.uiautomator.BySelector pkg(String);
+    method public static androidx.test.uiautomator.BySelector pkg(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector res(String);
+    method public static androidx.test.uiautomator.BySelector res(String, String);
+    method public static androidx.test.uiautomator.BySelector res(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector scrollable(boolean);
+    method public static androidx.test.uiautomator.BySelector selected(boolean);
+    method public static androidx.test.uiautomator.BySelector text(String);
+    method public static androidx.test.uiautomator.BySelector text(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector textContains(String);
+    method public static androidx.test.uiautomator.BySelector textEndsWith(String);
+    method public static androidx.test.uiautomator.BySelector textStartsWith(String);
+  }
+
+  public class BySelector {
+    method public androidx.test.uiautomator.BySelector checkable(boolean);
+    method public androidx.test.uiautomator.BySelector checked(boolean);
+    method public androidx.test.uiautomator.BySelector clazz(Class);
+    method public androidx.test.uiautomator.BySelector clazz(String);
+    method public androidx.test.uiautomator.BySelector clazz(String, String);
+    method public androidx.test.uiautomator.BySelector clazz(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector clickable(boolean);
+    method public androidx.test.uiautomator.BySelector depth(int);
+    method public androidx.test.uiautomator.BySelector depth(int, int);
+    method public androidx.test.uiautomator.BySelector desc(String);
+    method public androidx.test.uiautomator.BySelector desc(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector descContains(String);
+    method public androidx.test.uiautomator.BySelector descEndsWith(String);
+    method public androidx.test.uiautomator.BySelector descStartsWith(String);
+    method @RequiresApi(30) public androidx.test.uiautomator.BySelector displayId(int);
+    method public androidx.test.uiautomator.BySelector enabled(boolean);
+    method public androidx.test.uiautomator.BySelector focusable(boolean);
+    method public androidx.test.uiautomator.BySelector focused(boolean);
+    method public androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector, @IntRange(from=1) int);
+    method public androidx.test.uiautomator.BySelector hasChild(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector, int);
+    method public androidx.test.uiautomator.BySelector hasParent(androidx.test.uiautomator.BySelector);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hint(String);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hint(java.util.regex.Pattern);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hintContains(String);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hintEndsWith(String);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hintStartsWith(String);
+    method public androidx.test.uiautomator.BySelector longClickable(boolean);
+    method public androidx.test.uiautomator.BySelector maxDepth(int);
+    method public androidx.test.uiautomator.BySelector minDepth(int);
+    method public androidx.test.uiautomator.BySelector pkg(String);
+    method public androidx.test.uiautomator.BySelector pkg(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector res(String);
+    method public androidx.test.uiautomator.BySelector res(String, String);
+    method public androidx.test.uiautomator.BySelector res(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector scrollable(boolean);
+    method public androidx.test.uiautomator.BySelector selected(boolean);
+    method public androidx.test.uiautomator.BySelector text(String);
+    method public androidx.test.uiautomator.BySelector text(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector textContains(String);
+    method public androidx.test.uiautomator.BySelector textEndsWith(String);
+    method public androidx.test.uiautomator.BySelector textStartsWith(String);
+  }
+
+  public interface Condition<T, U> {
+    method public U! apply(T!);
+  }
+
+  public final class Configurator {
+    method public long getActionAcknowledgmentTimeout();
+    method public static androidx.test.uiautomator.Configurator getInstance();
+    method public long getKeyInjectionDelay();
+    method public long getScrollAcknowledgmentTimeout();
+    method public int getToolType();
+    method public int getUiAutomationFlags();
+    method public long getWaitForIdleTimeout();
+    method public long getWaitForSelectorTimeout();
+    method public androidx.test.uiautomator.Configurator setActionAcknowledgmentTimeout(long);
+    method public androidx.test.uiautomator.Configurator setKeyInjectionDelay(long);
+    method public androidx.test.uiautomator.Configurator setScrollAcknowledgmentTimeout(long);
+    method public androidx.test.uiautomator.Configurator setToolType(int);
+    method public androidx.test.uiautomator.Configurator setUiAutomationFlags(int);
+    method public androidx.test.uiautomator.Configurator setWaitForIdleTimeout(long);
+    method public androidx.test.uiautomator.Configurator setWaitForSelectorTimeout(long);
+  }
+
+  public enum Direction {
+    method public static androidx.test.uiautomator.Direction reverse(androidx.test.uiautomator.Direction);
+    enum_constant public static final androidx.test.uiautomator.Direction DOWN;
+    enum_constant public static final androidx.test.uiautomator.Direction LEFT;
+    enum_constant public static final androidx.test.uiautomator.Direction RIGHT;
+    enum_constant public static final androidx.test.uiautomator.Direction UP;
+  }
+
+  public abstract class EventCondition<U> implements android.app.UiAutomation.AccessibilityEventFilter {
+    ctor public EventCondition();
+    method public abstract U! getResult();
+  }
+
+  public interface IAutomationSupport {
+    method public void sendStatus(int, android.os.Bundle);
+  }
+
+  public abstract class SearchCondition<U> implements androidx.test.uiautomator.Condition<androidx.test.uiautomator.Searchable,U> {
+    ctor public SearchCondition();
+  }
+
+  public class StaleObjectException extends java.lang.RuntimeException {
+    ctor public StaleObjectException();
+  }
+
+  @Deprecated public class UiAutomatorInstrumentationTestRunner extends android.test.InstrumentationTestRunner {
+    ctor @Deprecated public UiAutomatorInstrumentationTestRunner();
+    method @Deprecated protected android.test.AndroidTestRunner! getAndroidTestRunner();
+    method @Deprecated protected void initializeUiAutomatorTest(androidx.test.uiautomator.UiAutomatorTestCase!);
+  }
+
+  @Deprecated public class UiAutomatorTestCase extends android.test.InstrumentationTestCase {
+    ctor @Deprecated public UiAutomatorTestCase();
+    method @Deprecated public androidx.test.uiautomator.IAutomationSupport! getAutomationSupport();
+    method @Deprecated public android.os.Bundle! getParams();
+    method @Deprecated public androidx.test.uiautomator.UiDevice! getUiDevice();
+    method @Deprecated public void sleep(long);
+  }
+
+  public class UiCollection extends androidx.test.uiautomator.UiObject {
+    ctor public UiCollection(androidx.test.uiautomator.UiSelector);
+    method public androidx.test.uiautomator.UiObject getChildByDescription(androidx.test.uiautomator.UiSelector, String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByInstance(androidx.test.uiautomator.UiSelector, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByText(androidx.test.uiautomator.UiSelector, String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public int getChildCount(androidx.test.uiautomator.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public boolean drag(int, int, int, int, int);
+    method public void dumpWindowHierarchy(java.io.File) throws java.io.IOException;
+    method public void dumpWindowHierarchy(java.io.OutputStream) throws java.io.IOException;
+    method @Deprecated public void dumpWindowHierarchy(String);
+    method @Discouraged(message="Can be useful for simple commands, but lacks support for proper error handling, input data, or complex commands (quotes, pipes) that can be obtained from UiAutomation#executeShellCommandRwe or similar utilities.") @RequiresApi(21) public String executeShellCommand(String) throws java.io.IOException;
+    method public androidx.test.uiautomator.UiObject2! findObject(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.UiObject findObject(androidx.test.uiautomator.UiSelector);
+    method public java.util.List<androidx.test.uiautomator.UiObject2!> findObjects(androidx.test.uiautomator.BySelector);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method @RequiresApi(30) public void freezeRotation(int);
+    method @Deprecated public String! getCurrentActivityName();
+    method public String! getCurrentPackageName();
+    method @Px public int getDisplayHeight();
+    method @Px public int getDisplayHeight(int);
+    method public int getDisplayRotation();
+    method public int getDisplayRotation(int);
+    method public android.graphics.Point getDisplaySizeDp();
+    method @Px public int getDisplayWidth();
+    method @Px public int getDisplayWidth(int);
+    method @Deprecated public static androidx.test.uiautomator.UiDevice getInstance();
+    method public static androidx.test.uiautomator.UiDevice getInstance(android.app.Instrumentation);
+    method public String! getLastTraversedText();
+    method public String! getLauncherPackageName();
+    method public String getProductName();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasObject(androidx.test.uiautomator.BySelector);
+    method public boolean hasWatcherTriggered(String?);
+    method public boolean isNaturalOrientation();
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean openNotification();
+    method public boolean openQuickSettings();
+    method public <U> U! performActionAndWait(Runnable, androidx.test.uiautomator.EventCondition<U!>, long);
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressKeyCodes(int[]);
+    method public boolean pressKeyCodes(int[], int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(String?, androidx.test.uiautomator.UiWatcher?);
+    method public void removeWatcher(String?);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method @Deprecated public void setCompressedLayoutHeirarchy(boolean);
+    method public void setCompressedLayoutHierarchy(boolean);
+    method public void setOrientationLandscape() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationLandscape(int);
+    method public void setOrientationLeft() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationLeft(int);
+    method public void setOrientationNatural() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationNatural(int);
+    method public void setOrientationPortrait() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationPortrait(int);
+    method public void setOrientationRight() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationRight(int);
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(android.graphics.Point![], int);
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean takeScreenshot(java.io.File);
+    method public boolean takeScreenshot(java.io.File, float, int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method @RequiresApi(30) public void unfreezeRotation(int);
+    method public <U> U! wait(androidx.test.uiautomator.Condition<? super androidx.test.uiautomator.UiDevice,U!>, long);
+    method public <U> U! wait(androidx.test.uiautomator.SearchCondition<U!>, long);
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(String?, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor @Deprecated public UiObject(androidx.test.uiautomator.UiSelector!);
+    method public void clearTextField() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean click() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean dragTo(androidx.test.uiautomator.UiObject, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean dragTo(int, int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo? findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChild(androidx.test.uiautomator.UiSelector) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public int getChildCount() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public String getClassName() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public String getContentDescription() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getFromParent(androidx.test.uiautomator.UiSelector) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public String getPackageName() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public final androidx.test.uiautomator.UiSelector getSelector();
+    method public String getText() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public android.graphics.Rect getVisibleBounds() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isCheckable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isChecked() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isClickable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isEnabled() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isFocusable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isFocused() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isScrollable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isSelected() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean longClick() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean performMultiPointerGesture(android.view.MotionEvent.PointerCoords![]!...);
+    method public boolean performTwoPointerGesture(android.graphics.Point, android.graphics.Point, android.graphics.Point, android.graphics.Point, int);
+    method public boolean pinchIn(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean pinchOut(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean setText(String?) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int FINGER_TOUCH_HALF_WIDTH = 20; // 0x14
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field @Deprecated protected static final long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field @Deprecated protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObject2 {
+    method public void clear();
+    method public void click();
+    method public void click(android.graphics.Point);
+    method public void click(android.graphics.Point, long);
+    method public void click(long);
+    method public <U> U! clickAndWait(android.graphics.Point, androidx.test.uiautomator.EventCondition<U!>, long);
+    method public <U> U! clickAndWait(androidx.test.uiautomator.EventCondition<U!>, long);
+    method public void drag(android.graphics.Point);
+    method public void drag(android.graphics.Point, int);
+    method public androidx.test.uiautomator.UiObject2! findObject(androidx.test.uiautomator.BySelector);
+    method public java.util.List<androidx.test.uiautomator.UiObject2!> findObjects(androidx.test.uiautomator.BySelector);
+    method public boolean fling(androidx.test.uiautomator.Direction);
+    method public boolean fling(androidx.test.uiautomator.Direction, int);
+    method public String! getApplicationPackage();
+    method public int getChildCount();
+    method public java.util.List<androidx.test.uiautomator.UiObject2!> getChildren();
+    method public String! getClassName();
+    method public String! getContentDescription();
+    method public int getDisplayId();
+    method @RequiresApi(24) public int getDrawingOrder();
+    method @RequiresApi(26) public String? getHint();
+    method public androidx.test.uiautomator.UiObject2! getParent();
+    method public String! getResourceName();
+    method public String! getText();
+    method public android.graphics.Rect getVisibleBounds();
+    method public android.graphics.Point getVisibleCenter();
+    method public boolean hasObject(androidx.test.uiautomator.BySelector);
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isLongClickable();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public void longClick();
+    method public void pinchClose(float);
+    method public void pinchClose(float, int);
+    method public void pinchOpen(float);
+    method public void pinchOpen(float, int);
+    method public void recycle();
+    method public boolean scroll(androidx.test.uiautomator.Direction, float);
+    method public boolean scroll(androidx.test.uiautomator.Direction, float, int);
+    method public <U> U! scrollUntil(androidx.test.uiautomator.Direction, androidx.test.uiautomator.Condition<? super androidx.test.uiautomator.UiObject2,U!>);
+    method public <U> U! scrollUntil(androidx.test.uiautomator.Direction, androidx.test.uiautomator.EventCondition<U!>);
+    method public void setGestureMargin(int);
+    method public void setGestureMarginPercent(@FloatRange(from=0.0f, to=0.5f) float);
+    method public void setGestureMarginPercent(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
+    method public void setGestureMargins(int, int, int, int);
+    method public void setText(String?);
+    method public void swipe(androidx.test.uiautomator.Direction, float);
+    method public void swipe(androidx.test.uiautomator.Direction, float, int);
+    method public <U> U! wait(androidx.test.uiautomator.Condition<? super androidx.test.uiautomator.UiObject2,U!>, long);
+    method public <U> U! wait(androidx.test.uiautomator.SearchCondition<U!>, long);
+    method public <U> U! wait(androidx.test.uiautomator.UiObject2Condition<U!>, long);
+  }
+
+  public abstract class UiObject2Condition<U> implements androidx.test.uiautomator.Condition<androidx.test.uiautomator.UiObject2,U> {
+    ctor public UiObject2Condition();
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(String);
+    ctor public UiObjectNotFoundException(String, Throwable?);
+    ctor public UiObjectNotFoundException(Throwable?);
+  }
+
+  public class UiScrollable extends androidx.test.uiautomator.UiCollection {
+    ctor public UiScrollable(androidx.test.uiautomator.UiSelector);
+    method protected boolean exists(androidx.test.uiautomator.UiSelector);
+    method public boolean flingBackward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean flingForward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean flingToBeginning(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean flingToEnd(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByDescription(androidx.test.uiautomator.UiSelector, String, boolean) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByText(androidx.test.uiautomator.UiSelector, String, boolean) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollBackward(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollDescriptionIntoView(String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollForward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollForward(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollIntoView(androidx.test.uiautomator.UiObject) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollIntoView(androidx.test.uiautomator.UiSelector) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollTextIntoView(String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiScrollable setAsHorizontalList();
+    method public androidx.test.uiautomator.UiScrollable setAsVerticalList();
+    method public androidx.test.uiautomator.UiScrollable setMaxSearchSwipes(int);
+    method public androidx.test.uiautomator.UiScrollable setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public androidx.test.uiautomator.UiSelector checkable(boolean);
+    method public androidx.test.uiautomator.UiSelector checked(boolean);
+    method public androidx.test.uiautomator.UiSelector childSelector(androidx.test.uiautomator.UiSelector);
+    method public <T> androidx.test.uiautomator.UiSelector className(Class<T!>);
+    method public androidx.test.uiautomator.UiSelector className(String);
+    method public androidx.test.uiautomator.UiSelector classNameMatches(String);
+    method public androidx.test.uiautomator.UiSelector clickable(boolean);
+    method protected androidx.test.uiautomator.UiSelector cloneSelector();
+    method public androidx.test.uiautomator.UiSelector description(String);
+    method public androidx.test.uiautomator.UiSelector descriptionContains(String);
+    method public androidx.test.uiautomator.UiSelector descriptionMatches(String);
+    method public androidx.test.uiautomator.UiSelector descriptionStartsWith(String);
+    method public androidx.test.uiautomator.UiSelector enabled(boolean);
+    method public androidx.test.uiautomator.UiSelector focusable(boolean);
+    method public androidx.test.uiautomator.UiSelector focused(boolean);
+    method public androidx.test.uiautomator.UiSelector fromParent(androidx.test.uiautomator.UiSelector);
+    method public androidx.test.uiautomator.UiSelector index(int);
+    method public androidx.test.uiautomator.UiSelector instance(int);
+    method public androidx.test.uiautomator.UiSelector longClickable(boolean);
+    method public androidx.test.uiautomator.UiSelector packageName(String);
+    method public androidx.test.uiautomator.UiSelector packageNameMatches(String);
+    method public androidx.test.uiautomator.UiSelector resourceId(String);
+    method public androidx.test.uiautomator.UiSelector resourceIdMatches(String);
+    method public androidx.test.uiautomator.UiSelector scrollable(boolean);
+    method public androidx.test.uiautomator.UiSelector selected(boolean);
+    method public androidx.test.uiautomator.UiSelector text(String);
+    method public androidx.test.uiautomator.UiSelector textContains(String);
+    method public androidx.test.uiautomator.UiSelector textMatches(String);
+    method public androidx.test.uiautomator.UiSelector textStartsWith(String);
+  }
+
+  public interface UiWatcher {
+    method public boolean checkForCondition();
+  }
+
+  public class Until {
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> checkable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> checked(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> clickable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descContains(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descEndsWith(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descEquals(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descMatches(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descMatches(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descStartsWith(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> enabled(boolean);
+    method public static androidx.test.uiautomator.SearchCondition<androidx.test.uiautomator.UiObject2!> findObject(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.SearchCondition<java.util.List<androidx.test.uiautomator.UiObject2!>!> findObjects(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> focusable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> focused(boolean);
+    method public static androidx.test.uiautomator.SearchCondition<java.lang.Boolean!> gone(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.SearchCondition<java.lang.Boolean!> hasObject(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> longClickable(boolean);
+    method public static androidx.test.uiautomator.EventCondition<java.lang.Boolean!> newWindow();
+    method public static androidx.test.uiautomator.EventCondition<java.lang.Boolean!> scrollFinished(androidx.test.uiautomator.Direction);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> scrollable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> selected(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textContains(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textEndsWith(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textEquals(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textMatches(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textMatches(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textNotEquals(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textStartsWith(String);
+  }
+
+}
+
diff --git a/test/uiautomator/uiautomator/api/res-2.3.0-beta01.txt b/test/uiautomator/uiautomator/api/res-2.3.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/uiautomator/uiautomator/api/res-2.3.0-beta01.txt
diff --git a/test/uiautomator/uiautomator/api/restricted_2.3.0-beta01.txt b/test/uiautomator/uiautomator/api/restricted_2.3.0-beta01.txt
new file mode 100644
index 0000000..bfaecd4
--- /dev/null
+++ b/test/uiautomator/uiautomator/api/restricted_2.3.0-beta01.txt
@@ -0,0 +1,467 @@
+// Signature format: 4.0
+package androidx.test.uiautomator {
+
+  public class By {
+    method public static androidx.test.uiautomator.BySelector checkable(boolean);
+    method public static androidx.test.uiautomator.BySelector checked(boolean);
+    method public static androidx.test.uiautomator.BySelector clazz(Class);
+    method public static androidx.test.uiautomator.BySelector clazz(String);
+    method public static androidx.test.uiautomator.BySelector clazz(String, String);
+    method public static androidx.test.uiautomator.BySelector clazz(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector clickable(boolean);
+    method public static androidx.test.uiautomator.BySelector copy(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector depth(int);
+    method public static androidx.test.uiautomator.BySelector desc(String);
+    method public static androidx.test.uiautomator.BySelector desc(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector descContains(String);
+    method public static androidx.test.uiautomator.BySelector descEndsWith(String);
+    method public static androidx.test.uiautomator.BySelector descStartsWith(String);
+    method @RequiresApi(30) public static androidx.test.uiautomator.BySelector displayId(int);
+    method public static androidx.test.uiautomator.BySelector enabled(boolean);
+    method public static androidx.test.uiautomator.BySelector focusable(boolean);
+    method public static androidx.test.uiautomator.BySelector focused(boolean);
+    method public static androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector, @IntRange(from=1) int);
+    method public static androidx.test.uiautomator.BySelector hasChild(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector, int);
+    method public static androidx.test.uiautomator.BySelector hasParent(androidx.test.uiautomator.BySelector);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hint(String);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hint(java.util.regex.Pattern);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hintContains(String);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hintEndsWith(String);
+    method @RequiresApi(26) public static androidx.test.uiautomator.BySelector hintStartsWith(String);
+    method public static androidx.test.uiautomator.BySelector longClickable(boolean);
+    method public static androidx.test.uiautomator.BySelector pkg(String);
+    method public static androidx.test.uiautomator.BySelector pkg(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector res(String);
+    method public static androidx.test.uiautomator.BySelector res(String, String);
+    method public static androidx.test.uiautomator.BySelector res(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector scrollable(boolean);
+    method public static androidx.test.uiautomator.BySelector selected(boolean);
+    method public static androidx.test.uiautomator.BySelector text(String);
+    method public static androidx.test.uiautomator.BySelector text(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.BySelector textContains(String);
+    method public static androidx.test.uiautomator.BySelector textEndsWith(String);
+    method public static androidx.test.uiautomator.BySelector textStartsWith(String);
+  }
+
+  public class BySelector {
+    method public androidx.test.uiautomator.BySelector checkable(boolean);
+    method public androidx.test.uiautomator.BySelector checked(boolean);
+    method public androidx.test.uiautomator.BySelector clazz(Class);
+    method public androidx.test.uiautomator.BySelector clazz(String);
+    method public androidx.test.uiautomator.BySelector clazz(String, String);
+    method public androidx.test.uiautomator.BySelector clazz(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector clickable(boolean);
+    method public androidx.test.uiautomator.BySelector depth(int);
+    method public androidx.test.uiautomator.BySelector depth(int, int);
+    method public androidx.test.uiautomator.BySelector desc(String);
+    method public androidx.test.uiautomator.BySelector desc(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector descContains(String);
+    method public androidx.test.uiautomator.BySelector descEndsWith(String);
+    method public androidx.test.uiautomator.BySelector descStartsWith(String);
+    method @RequiresApi(30) public androidx.test.uiautomator.BySelector displayId(int);
+    method public androidx.test.uiautomator.BySelector enabled(boolean);
+    method public androidx.test.uiautomator.BySelector focusable(boolean);
+    method public androidx.test.uiautomator.BySelector focused(boolean);
+    method public androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.BySelector hasAncestor(androidx.test.uiautomator.BySelector, @IntRange(from=1) int);
+    method public androidx.test.uiautomator.BySelector hasChild(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.BySelector hasDescendant(androidx.test.uiautomator.BySelector, int);
+    method public androidx.test.uiautomator.BySelector hasParent(androidx.test.uiautomator.BySelector);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hint(String);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hint(java.util.regex.Pattern);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hintContains(String);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hintEndsWith(String);
+    method @RequiresApi(26) public androidx.test.uiautomator.BySelector hintStartsWith(String);
+    method public androidx.test.uiautomator.BySelector longClickable(boolean);
+    method public androidx.test.uiautomator.BySelector maxDepth(int);
+    method public androidx.test.uiautomator.BySelector minDepth(int);
+    method public androidx.test.uiautomator.BySelector pkg(String);
+    method public androidx.test.uiautomator.BySelector pkg(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector res(String);
+    method public androidx.test.uiautomator.BySelector res(String, String);
+    method public androidx.test.uiautomator.BySelector res(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector scrollable(boolean);
+    method public androidx.test.uiautomator.BySelector selected(boolean);
+    method public androidx.test.uiautomator.BySelector text(String);
+    method public androidx.test.uiautomator.BySelector text(java.util.regex.Pattern);
+    method public androidx.test.uiautomator.BySelector textContains(String);
+    method public androidx.test.uiautomator.BySelector textEndsWith(String);
+    method public androidx.test.uiautomator.BySelector textStartsWith(String);
+  }
+
+  public interface Condition<T, U> {
+    method public U! apply(T!);
+  }
+
+  public final class Configurator {
+    method public long getActionAcknowledgmentTimeout();
+    method public static androidx.test.uiautomator.Configurator getInstance();
+    method public long getKeyInjectionDelay();
+    method public long getScrollAcknowledgmentTimeout();
+    method public int getToolType();
+    method public int getUiAutomationFlags();
+    method public long getWaitForIdleTimeout();
+    method public long getWaitForSelectorTimeout();
+    method public androidx.test.uiautomator.Configurator setActionAcknowledgmentTimeout(long);
+    method public androidx.test.uiautomator.Configurator setKeyInjectionDelay(long);
+    method public androidx.test.uiautomator.Configurator setScrollAcknowledgmentTimeout(long);
+    method public androidx.test.uiautomator.Configurator setToolType(int);
+    method public androidx.test.uiautomator.Configurator setUiAutomationFlags(int);
+    method public androidx.test.uiautomator.Configurator setWaitForIdleTimeout(long);
+    method public androidx.test.uiautomator.Configurator setWaitForSelectorTimeout(long);
+  }
+
+  public enum Direction {
+    method public static androidx.test.uiautomator.Direction reverse(androidx.test.uiautomator.Direction);
+    enum_constant public static final androidx.test.uiautomator.Direction DOWN;
+    enum_constant public static final androidx.test.uiautomator.Direction LEFT;
+    enum_constant public static final androidx.test.uiautomator.Direction RIGHT;
+    enum_constant public static final androidx.test.uiautomator.Direction UP;
+  }
+
+  public abstract class EventCondition<U> implements android.app.UiAutomation.AccessibilityEventFilter {
+    ctor public EventCondition();
+    method public abstract U! getResult();
+  }
+
+  public interface IAutomationSupport {
+    method public void sendStatus(int, android.os.Bundle);
+  }
+
+  public abstract class SearchCondition<U> implements androidx.test.uiautomator.Condition<androidx.test.uiautomator.Searchable,U> {
+    ctor public SearchCondition();
+  }
+
+  public class StaleObjectException extends java.lang.RuntimeException {
+    ctor public StaleObjectException();
+  }
+
+  @Deprecated public class UiAutomatorInstrumentationTestRunner extends android.test.InstrumentationTestRunner {
+    ctor @Deprecated public UiAutomatorInstrumentationTestRunner();
+    method @Deprecated protected android.test.AndroidTestRunner! getAndroidTestRunner();
+    method @Deprecated protected void initializeUiAutomatorTest(androidx.test.uiautomator.UiAutomatorTestCase!);
+  }
+
+  @Deprecated public class UiAutomatorTestCase extends android.test.InstrumentationTestCase {
+    ctor @Deprecated public UiAutomatorTestCase();
+    method @Deprecated public androidx.test.uiautomator.IAutomationSupport! getAutomationSupport();
+    method @Deprecated public android.os.Bundle! getParams();
+    method @Deprecated public androidx.test.uiautomator.UiDevice! getUiDevice();
+    method @Deprecated public void sleep(long);
+  }
+
+  public class UiCollection extends androidx.test.uiautomator.UiObject {
+    ctor public UiCollection(androidx.test.uiautomator.UiSelector);
+    method public androidx.test.uiautomator.UiObject getChildByDescription(androidx.test.uiautomator.UiSelector, String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByInstance(androidx.test.uiautomator.UiSelector, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByText(androidx.test.uiautomator.UiSelector, String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public int getChildCount(androidx.test.uiautomator.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public boolean drag(int, int, int, int, int);
+    method public void dumpWindowHierarchy(java.io.File) throws java.io.IOException;
+    method public void dumpWindowHierarchy(java.io.OutputStream) throws java.io.IOException;
+    method @Deprecated public void dumpWindowHierarchy(String);
+    method @Discouraged(message="Can be useful for simple commands, but lacks support for proper error handling, input data, or complex commands (quotes, pipes) that can be obtained from UiAutomation#executeShellCommandRwe or similar utilities.") @RequiresApi(21) public String executeShellCommand(String) throws java.io.IOException;
+    method public androidx.test.uiautomator.UiObject2! findObject(androidx.test.uiautomator.BySelector);
+    method public androidx.test.uiautomator.UiObject findObject(androidx.test.uiautomator.UiSelector);
+    method public java.util.List<androidx.test.uiautomator.UiObject2!> findObjects(androidx.test.uiautomator.BySelector);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method @RequiresApi(30) public void freezeRotation(int);
+    method @Deprecated public String! getCurrentActivityName();
+    method public String! getCurrentPackageName();
+    method @Px public int getDisplayHeight();
+    method @Px public int getDisplayHeight(int);
+    method public int getDisplayRotation();
+    method public int getDisplayRotation(int);
+    method public android.graphics.Point getDisplaySizeDp();
+    method @Px public int getDisplayWidth();
+    method @Px public int getDisplayWidth(int);
+    method @Deprecated public static androidx.test.uiautomator.UiDevice getInstance();
+    method public static androidx.test.uiautomator.UiDevice getInstance(android.app.Instrumentation);
+    method public String! getLastTraversedText();
+    method public String! getLauncherPackageName();
+    method public String getProductName();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasObject(androidx.test.uiautomator.BySelector);
+    method public boolean hasWatcherTriggered(String?);
+    method public boolean isNaturalOrientation();
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean openNotification();
+    method public boolean openQuickSettings();
+    method public <U> U! performActionAndWait(Runnable, androidx.test.uiautomator.EventCondition<U!>, long);
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressKeyCodes(int[]);
+    method public boolean pressKeyCodes(int[], int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(String?, androidx.test.uiautomator.UiWatcher?);
+    method public void removeWatcher(String?);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method @Deprecated public void setCompressedLayoutHeirarchy(boolean);
+    method public void setCompressedLayoutHierarchy(boolean);
+    method public void setOrientationLandscape() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationLandscape(int);
+    method public void setOrientationLeft() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationLeft(int);
+    method public void setOrientationNatural() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationNatural(int);
+    method public void setOrientationPortrait() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationPortrait(int);
+    method public void setOrientationRight() throws android.os.RemoteException;
+    method @RequiresApi(30) public void setOrientationRight(int);
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(android.graphics.Point![], int);
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean takeScreenshot(java.io.File);
+    method public boolean takeScreenshot(java.io.File, float, int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method @RequiresApi(30) public void unfreezeRotation(int);
+    method public <U> U! wait(androidx.test.uiautomator.Condition<? super androidx.test.uiautomator.UiDevice,U!>, long);
+    method public <U> U! wait(androidx.test.uiautomator.SearchCondition<U!>, long);
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(String?, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor @Deprecated public UiObject(androidx.test.uiautomator.UiSelector!);
+    method public void clearTextField() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean click() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean dragTo(androidx.test.uiautomator.UiObject, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean dragTo(int, int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo? findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChild(androidx.test.uiautomator.UiSelector) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public int getChildCount() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public String getClassName() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public String getContentDescription() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getFromParent(androidx.test.uiautomator.UiSelector) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public String getPackageName() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public final androidx.test.uiautomator.UiSelector getSelector();
+    method public String getText() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public android.graphics.Rect getVisibleBounds() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isCheckable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isChecked() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isClickable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isEnabled() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isFocusable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isFocused() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isScrollable() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean isSelected() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean longClick() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean performMultiPointerGesture(android.view.MotionEvent.PointerCoords![]!...);
+    method public boolean performTwoPointerGesture(android.graphics.Point, android.graphics.Point, android.graphics.Point, android.graphics.Point, int);
+    method public boolean pinchIn(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean pinchOut(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean setText(String?) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int FINGER_TOUCH_HALF_WIDTH = 20; // 0x14
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field @Deprecated protected static final long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field @Deprecated protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObject2 {
+    method public void clear();
+    method public void click();
+    method public void click(android.graphics.Point);
+    method public void click(android.graphics.Point, long);
+    method public void click(long);
+    method public <U> U! clickAndWait(android.graphics.Point, androidx.test.uiautomator.EventCondition<U!>, long);
+    method public <U> U! clickAndWait(androidx.test.uiautomator.EventCondition<U!>, long);
+    method public void drag(android.graphics.Point);
+    method public void drag(android.graphics.Point, int);
+    method public androidx.test.uiautomator.UiObject2! findObject(androidx.test.uiautomator.BySelector);
+    method public java.util.List<androidx.test.uiautomator.UiObject2!> findObjects(androidx.test.uiautomator.BySelector);
+    method public boolean fling(androidx.test.uiautomator.Direction);
+    method public boolean fling(androidx.test.uiautomator.Direction, int);
+    method public String! getApplicationPackage();
+    method public int getChildCount();
+    method public java.util.List<androidx.test.uiautomator.UiObject2!> getChildren();
+    method public String! getClassName();
+    method public String! getContentDescription();
+    method public int getDisplayId();
+    method @RequiresApi(24) public int getDrawingOrder();
+    method @RequiresApi(26) public String? getHint();
+    method public androidx.test.uiautomator.UiObject2! getParent();
+    method public String! getResourceName();
+    method public String! getText();
+    method public android.graphics.Rect getVisibleBounds();
+    method public android.graphics.Point getVisibleCenter();
+    method public boolean hasObject(androidx.test.uiautomator.BySelector);
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isLongClickable();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public void longClick();
+    method public void pinchClose(float);
+    method public void pinchClose(float, int);
+    method public void pinchOpen(float);
+    method public void pinchOpen(float, int);
+    method public void recycle();
+    method public boolean scroll(androidx.test.uiautomator.Direction, float);
+    method public boolean scroll(androidx.test.uiautomator.Direction, float, int);
+    method public <U> U! scrollUntil(androidx.test.uiautomator.Direction, androidx.test.uiautomator.Condition<? super androidx.test.uiautomator.UiObject2,U!>);
+    method public <U> U! scrollUntil(androidx.test.uiautomator.Direction, androidx.test.uiautomator.EventCondition<U!>);
+    method public void setGestureMargin(int);
+    method public void setGestureMarginPercent(@FloatRange(from=0.0f, to=0.5f) float);
+    method public void setGestureMarginPercent(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
+    method public void setGestureMargins(int, int, int, int);
+    method public void setText(String?);
+    method public void swipe(androidx.test.uiautomator.Direction, float);
+    method public void swipe(androidx.test.uiautomator.Direction, float, int);
+    method public <U> U! wait(androidx.test.uiautomator.Condition<? super androidx.test.uiautomator.UiObject2,U!>, long);
+    method public <U> U! wait(androidx.test.uiautomator.SearchCondition<U!>, long);
+    method public <U> U! wait(androidx.test.uiautomator.UiObject2Condition<U!>, long);
+  }
+
+  public abstract class UiObject2Condition<U> implements androidx.test.uiautomator.Condition<androidx.test.uiautomator.UiObject2,U> {
+    ctor public UiObject2Condition();
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(String);
+    ctor public UiObjectNotFoundException(String, Throwable?);
+    ctor public UiObjectNotFoundException(Throwable?);
+  }
+
+  public class UiScrollable extends androidx.test.uiautomator.UiCollection {
+    ctor public UiScrollable(androidx.test.uiautomator.UiSelector);
+    method protected boolean exists(androidx.test.uiautomator.UiSelector);
+    method public boolean flingBackward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean flingForward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean flingToBeginning(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean flingToEnd(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByDescription(androidx.test.uiautomator.UiSelector, String, boolean) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiObject getChildByText(androidx.test.uiautomator.UiSelector, String, boolean) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollBackward(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollDescriptionIntoView(String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollForward() throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollForward(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollIntoView(androidx.test.uiautomator.UiObject) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollIntoView(androidx.test.uiautomator.UiSelector) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollTextIntoView(String) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int, int) throws androidx.test.uiautomator.UiObjectNotFoundException;
+    method public androidx.test.uiautomator.UiScrollable setAsHorizontalList();
+    method public androidx.test.uiautomator.UiScrollable setAsVerticalList();
+    method public androidx.test.uiautomator.UiScrollable setMaxSearchSwipes(int);
+    method public androidx.test.uiautomator.UiScrollable setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public androidx.test.uiautomator.UiSelector checkable(boolean);
+    method public androidx.test.uiautomator.UiSelector checked(boolean);
+    method public androidx.test.uiautomator.UiSelector childSelector(androidx.test.uiautomator.UiSelector);
+    method public <T> androidx.test.uiautomator.UiSelector className(Class<T!>);
+    method public androidx.test.uiautomator.UiSelector className(String);
+    method public androidx.test.uiautomator.UiSelector classNameMatches(String);
+    method public androidx.test.uiautomator.UiSelector clickable(boolean);
+    method protected androidx.test.uiautomator.UiSelector cloneSelector();
+    method public androidx.test.uiautomator.UiSelector description(String);
+    method public androidx.test.uiautomator.UiSelector descriptionContains(String);
+    method public androidx.test.uiautomator.UiSelector descriptionMatches(String);
+    method public androidx.test.uiautomator.UiSelector descriptionStartsWith(String);
+    method public androidx.test.uiautomator.UiSelector enabled(boolean);
+    method public androidx.test.uiautomator.UiSelector focusable(boolean);
+    method public androidx.test.uiautomator.UiSelector focused(boolean);
+    method public androidx.test.uiautomator.UiSelector fromParent(androidx.test.uiautomator.UiSelector);
+    method public androidx.test.uiautomator.UiSelector index(int);
+    method public androidx.test.uiautomator.UiSelector instance(int);
+    method public androidx.test.uiautomator.UiSelector longClickable(boolean);
+    method public androidx.test.uiautomator.UiSelector packageName(String);
+    method public androidx.test.uiautomator.UiSelector packageNameMatches(String);
+    method public androidx.test.uiautomator.UiSelector resourceId(String);
+    method public androidx.test.uiautomator.UiSelector resourceIdMatches(String);
+    method public androidx.test.uiautomator.UiSelector scrollable(boolean);
+    method public androidx.test.uiautomator.UiSelector selected(boolean);
+    method public androidx.test.uiautomator.UiSelector text(String);
+    method public androidx.test.uiautomator.UiSelector textContains(String);
+    method public androidx.test.uiautomator.UiSelector textMatches(String);
+    method public androidx.test.uiautomator.UiSelector textStartsWith(String);
+  }
+
+  public interface UiWatcher {
+    method public boolean checkForCondition();
+  }
+
+  public class Until {
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> checkable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> checked(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> clickable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descContains(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descEndsWith(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descEquals(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descMatches(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descMatches(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> descStartsWith(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> enabled(boolean);
+    method public static androidx.test.uiautomator.SearchCondition<androidx.test.uiautomator.UiObject2!> findObject(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.SearchCondition<java.util.List<androidx.test.uiautomator.UiObject2!>!> findObjects(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> focusable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> focused(boolean);
+    method public static androidx.test.uiautomator.SearchCondition<java.lang.Boolean!> gone(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.SearchCondition<java.lang.Boolean!> hasObject(androidx.test.uiautomator.BySelector);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> longClickable(boolean);
+    method public static androidx.test.uiautomator.EventCondition<java.lang.Boolean!> newWindow();
+    method public static androidx.test.uiautomator.EventCondition<java.lang.Boolean!> scrollFinished(androidx.test.uiautomator.Direction);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> scrollable(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> selected(boolean);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textContains(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textEndsWith(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textEquals(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textMatches(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textMatches(java.util.regex.Pattern);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textNotEquals(String);
+    method public static androidx.test.uiautomator.UiObject2Condition<java.lang.Boolean!> textStartsWith(String);
+  }
+
+}
+
diff --git a/testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/VerifyWithPolling.kt b/testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/VerifyWithPolling.kt
deleted file mode 100644
index 52beb96..0000000
--- a/testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/VerifyWithPolling.kt
+++ /dev/null
@@ -1,39 +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.
- */
-
-package androidx.testutils
-
-import java.lang.SuppressWarnings
-import org.junit.Assert
-
-@SuppressWarnings("BanThreadSleep")
-fun verifyWithPolling(
-    message: String,
-    periodMs: Long,
-    timeoutMs: Long,
-    tryBlock: () -> Boolean
-): Long {
-    var totalDurationMs = 0L
-    while (!tryBlock()) {
-        Thread.sleep(periodMs)
-
-        totalDurationMs += periodMs
-        if (totalDurationMs > timeoutMs) {
-            Assert.fail(message)
-        }
-    }
-    return totalDurationMs
-}
diff --git a/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt b/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt
index 5dbff64..7836624 100644
--- a/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt
+++ b/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt
@@ -18,7 +18,6 @@
 
 import android.content.Context
 import android.content.res.Configuration
-import android.os.Build
 import androidx.core.os.ConfigurationCompat
 import androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR
 import androidx.core.view.ViewCompat.LAYOUT_DIRECTION_RTL
@@ -115,13 +114,11 @@
             configuration.language,
             CoreMatchers.equalTo(lang)
         )
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            assertThat(
-                "Layout direction should be ${if (expectRtl) "RTL" else "LTR"}",
-                configuration.layoutDirection,
-                CoreMatchers.equalTo(if (expectRtl) LAYOUT_DIRECTION_RTL else LAYOUT_DIRECTION_LTR)
-            )
-        }
+        assertThat(
+            "Layout direction should be ${if (expectRtl) "RTL" else "LTR"}",
+            configuration.layoutDirection,
+            CoreMatchers.equalTo(if (expectRtl) LAYOUT_DIRECTION_RTL else LAYOUT_DIRECTION_LTR)
+        )
     }
 
     private fun determineDefaultLayoutDirection() {
@@ -130,8 +127,6 @@
             configuration.language,
             CoreMatchers.equalTo(DEFAULT_LANGUAGE)
         )
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            expectRtlInDefaultLanguage = configuration.layoutDirection == LAYOUT_DIRECTION_RTL
-        }
+        expectRtlInDefaultLanguage = configuration.layoutDirection == LAYOUT_DIRECTION_RTL
     }
 }
diff --git a/testutils/testutils-runtime/src/main/java/androidx/fragment/app/StrictFragment.kt b/testutils/testutils-runtime/src/main/java/androidx/fragment/app/StrictFragment.kt
index fe1c603..f3fa6a7 100644
--- a/testutils/testutils-runtime/src/main/java/androidx/fragment/app/StrictFragment.kt
+++ b/testutils/testutils-runtime/src/main/java/androidx/fragment/app/StrictFragment.kt
@@ -17,7 +17,6 @@
 package androidx.fragment.app
 
 import android.content.Context
-import android.os.Build
 import android.os.Bundle
 import android.util.AttributeSet
 import androidx.annotation.LayoutRes
@@ -53,9 +52,7 @@
     }
 
     fun checkActivityNotDestroyed() {
-        if (Build.VERSION.SDK_INT >= 17) {
-            check(!requireActivity().isDestroyed)
-        }
+        check(!requireActivity().isDestroyed)
     }
 
     fun checkState(caller: String, vararg expected: State) {
diff --git a/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt b/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt
index 288c788..6c46472 100644
--- a/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt
+++ b/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt
@@ -19,7 +19,6 @@
 import android.animation.ValueAnimator
 import android.annotation.SuppressLint
 import android.app.Activity
-import android.os.Build
 import androidx.test.runner.intercepting.SingleActivityFactory
 import java.lang.RuntimeException
 import java.lang.reflect.Method
@@ -73,6 +72,7 @@
         launchActivity: Boolean
     ) : super(singleActivityFactory, initialTouchMode, launchActivity)
 
+    @SuppressLint("BanUncheckedReflection")
     override fun afterActivityLaunched() {
         // make sure "apply()" is invoked
         if (!::testType.isInitialized) {
@@ -85,16 +85,14 @@
 
     override fun apply(base: Statement, description: Description): Statement {
         testType = TestType.NORMAL
-        if (Build.VERSION.SDK_INT >= 16 &&
-            (
-                description.annotations.any { it.annotationClass == AnimationTest::class } ||
-                    description.testClass.annotations.any
-                    { it.annotationClass == AnimationTest::class }
-                )
+        if (description.annotations.any { it.annotationClass == AnimationTest::class } ||
+            description.testClass.annotations.any
+            { it.annotationClass == AnimationTest::class }
         ) {
             testType = TestType.ANIMATION
             val wrappedStatement = super.apply(base, description)
             return object : Statement() {
+                @SuppressLint("BanUncheckedReflection")
                 override fun evaluate() {
                     val savedScale = durationGetter.invoke(null) as Float
                     try {
diff --git a/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationDurationScaleRule.kt b/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationDurationScaleRule.kt
index 650354c..b8862b9 100644
--- a/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationDurationScaleRule.kt
+++ b/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationDurationScaleRule.kt
@@ -18,10 +18,8 @@
 
 import android.animation.ValueAnimator
 import android.annotation.SuppressLint
-import android.os.Build
 import org.junit.rules.TestWatcher
 import org.junit.runner.Description
-import org.junit.runners.model.Statement
 
 /**
  * This rule allows test to control animation duration scale for tests.
@@ -62,24 +60,11 @@
         internal fun create(
             forcedAnimationDurationScale: Float? = null
         ): AnimationDurationScaleRule {
-            return if (Build.VERSION.SDK_INT >= 16) {
-                AnimationDurationScaleRuleImpl(
-                    forcedAnimationDurationScale
-                )
-            } else {
-                NoOpAnimationDurationScaleRule()
-            }
+            return AnimationDurationScaleRuleImpl(forcedAnimationDurationScale)
         }
     }
 }
 
-private class NoOpAnimationDurationScaleRule : AnimationDurationScaleRule() {
-    override fun setAnimationDurationScale(animationDurationScale: Float) {
-    }
-
-    override fun apply(base: Statement, description: Description) = base
-}
-
 private class AnimationDurationScaleRuleImpl(
     /**
      * The new duration scale for the test
diff --git a/testutils/testutils-runtime/src/main/java/androidx/testutils/LocaleTestUtils.kt b/testutils/testutils-runtime/src/main/java/androidx/testutils/LocaleTestUtils.kt
index 0e5bc52..648d807 100644
--- a/testutils/testutils-runtime/src/main/java/androidx/testutils/LocaleTestUtils.kt
+++ b/testutils/testutils-runtime/src/main/java/androidx/testutils/LocaleTestUtils.kt
@@ -200,11 +200,8 @@
         when {
             Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ->
                 newConfig.setLocales(locales.unwrap() as LocaleList)
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 ->
-                newConfig.setLocale(locales.get(0))
-            else ->
-                @Suppress("DEPRECATION")
-                newConfig.locale = locales.get(0)
+
+            else -> newConfig.setLocale(locales.get(0))
         }
         @Suppress("DEPRECATION")
         resources.updateConfiguration(newConfig, resources.displayMetrics)
diff --git a/text/text/lint-baseline.xml b/text/text/lint-baseline.xml
index 9d2be4d..2a6edab 100644
--- a/text/text/lint-baseline.xml
+++ b/text/text/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.2.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.2.0-beta01)" variant="all" version="8.2.0-beta01">
+<issues format="6" by="lint 8.3.0-alpha10" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-alpha10)" variant="all" version="8.3.0-alpha10">
 
     <issue
         id="PrimitiveInCollection"
@@ -7,7 +7,7 @@
         errorLine1="    private val paragraphEnds: List&lt;Int>"
         errorLine2="                               ~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/LayoutHelper.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/LayoutHelper.android.kt"/>
     </issue>
 
     <issue
@@ -16,7 +16,7 @@
         errorLine1="        val lineFeeds = mutableListOf&lt;Int>()"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/LayoutHelper.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/LayoutHelper.android.kt"/>
     </issue>
 
     <issue
@@ -25,7 +25,7 @@
         errorLine1="    private fun breakInWords(layoutHelper: LayoutHelper): List&lt;Int> {"
         errorLine2="                                                          ~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
     </issue>
 
     <issue
@@ -34,7 +34,7 @@
         errorLine1="        val words = breakWithBreakIterator(text, BreakIterator.getLineInstance(Locale.getDefault()))"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
     </issue>
 
     <issue
@@ -43,7 +43,7 @@
         errorLine1="        val set = TreeSet&lt;Int>().apply {"
         errorLine2="        ^">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
     </issue>
 
     <issue
@@ -52,7 +52,7 @@
         errorLine1="    private fun breakWithBreakIterator(text: CharSequence, breaker: BreakIterator): List&lt;Int> {"
         errorLine2="                                                                                    ~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
     </issue>
 
     <issue
@@ -61,7 +61,7 @@
         errorLine1="        val res = mutableListOf(0)"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
     </issue>
 
     <issue
@@ -70,7 +70,7 @@
         errorLine1="    fun breakOffsets(layoutHelper: LayoutHelper, segmentType: SegmentType): List&lt;Int> {"
         errorLine2="                                                                            ~~~~~~~~~">
         <location
-            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt"/>
+            file="src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt"/>
     </issue>
 
 </issues>
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.kt b/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/CharSequenceCharacterIterator.kt b/text/text/src/main/java/androidx/compose/ui/text/android/CharSequenceCharacterIterator.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/CharSequenceCharacterIterator.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/CharSequenceCharacterIterator.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/InlineClassUtils.kt b/text/text/src/main/java/androidx/compose/ui/text/android/InlineClassUtils.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/InlineClassUtils.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/InlineClassUtils.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/InternalPlatformTextApi.kt b/text/text/src/main/java/androidx/compose/ui/text/android/InternalPlatformTextApi.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/InternalPlatformTextApi.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/InternalPlatformTextApi.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/LayoutCompat.kt b/text/text/src/main/java/androidx/compose/ui/text/android/LayoutCompat.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/LayoutCompat.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/LayoutCompat.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/LayoutHelper.kt b/text/text/src/main/java/androidx/compose/ui/text/android/LayoutHelper.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/LayoutHelper.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/LayoutHelper.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.kt b/text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/LayoutIntrinsics.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/ListUtils.kt b/text/text/src/main/java/androidx/compose/ui/text/android/ListUtils.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/ListUtils.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/ListUtils.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/PaintExtensions.kt b/text/text/src/main/java/androidx/compose/ui/text/android/PaintExtensions.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/PaintExtensions.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/PaintExtensions.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/SpannedExtensions.kt b/text/text/src/main/java/androidx/compose/ui/text/android/SpannedExtensions.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/SpannedExtensions.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/SpannedExtensions.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.kt b/text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/TextAndroidCanvas.kt b/text/text/src/main/java/androidx/compose/ui/text/android/TextAndroidCanvas.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/TextAndroidCanvas.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/TextAndroidCanvas.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt b/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt b/text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentBreaker.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentType.kt b/text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentType.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentType.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/animation/SegmentType.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/selection/WordBoundary.kt b/text/text/src/main/java/androidx/compose/ui/text/android/selection/WordBoundary.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/selection/WordBoundary.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/selection/WordBoundary.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/selection/WordIterator.kt b/text/text/src/main/java/androidx/compose/ui/text/android/selection/WordIterator.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/selection/WordIterator.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/selection/WordIterator.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/BaselineShiftSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/BaselineShiftSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/BaselineShiftSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/BaselineShiftSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/FontFeatureSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/FontFeatureSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/FontFeatureSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/FontFeatureSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/IndentationFixSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/IndentationFixSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/IndentationFixSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/IndentationFixSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEm.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEm.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEm.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEm.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPx.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPx.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPx.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPx.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightStyleSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightStyleSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightStyleSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/LineHeightStyleSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/PlaceholderSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/PlaceholderSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/PlaceholderSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/PlaceholderSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/ShadowSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/ShadowSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/ShadowSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/ShadowSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/SkewXSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/SkewXSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/SkewXSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/SkewXSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/TextDecorationSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/TextDecorationSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/TextDecorationSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/TextDecorationSpan.android.kt
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/style/TypefaceSpan.kt b/text/text/src/main/java/androidx/compose/ui/text/android/style/TypefaceSpan.android.kt
similarity index 100%
rename from text/text/src/main/java/androidx/compose/ui/text/android/style/TypefaceSpan.kt
rename to text/text/src/main/java/androidx/compose/ui/text/android/style/TypefaceSpan.android.kt
diff --git a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
index aa266f7..c7ad150 100644
--- a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
+++ b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
@@ -25,7 +25,7 @@
 // Concept of version useful e.g. for human-readable error messages, and stable once released.
 // Does not replace the need for a binary verification mechanism (e.g. checksum check).
 // TODO: populate using CMake
-#define VERSION "1.0.0-beta03"
+#define VERSION "1.0.0"
 
 namespace tracing_perfetto {
     void RegisterWithPerfetto() {
diff --git a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
index ef3b214..d3ef52d 100644
--- a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
+++ b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
@@ -30,7 +30,7 @@
         init {
             PerfettoNative.loadLib()
         }
-        const val libraryVersion = "1.0.0-beta03" // TODO: get using reflection
+        const val libraryVersion = "1.0.0" // TODO: get using reflection
     }
 
     @Test
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
index 3cc418e..47e3465 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
@@ -25,12 +25,12 @@
 
     // TODO(224510255): load from a file produced at build time
     object Metadata {
-        const val version = "1.0.0-beta03"
+        const val version = "1.0.0"
         val checksums = mapOf(
-            "arm64-v8a" to "e11502d6fa0c949774a792c2406744a1fff112ba26e6af19a6722dd55a6061ca",
-            "armeabi-v7a" to "cd286085893cc7760b658f48b436fd317493159dcbab680667c0bf01d25ffb04",
-            "x86" to "2679c351d40e405e46dec58c8f63570eb29196cd9e67404cf66abe74bc933a88",
-            "x86_64" to "2971a9135cd69feb2a4e3c7b42f6b52469421713331cdb7a841c1c8cc707b637",
+            "arm64-v8a" to "a152fbd7ebaa109a9c3cf6bbb6d585aa0df08f97ae022b2090b1096a8f5e2665",
+            "armeabi-v7a" to "b2821c9ddb77a3f070cce42be7cd3255d7ec92c868d7d518a99ed968d9018b9f",
+            "x86" to "4cefdc75fe41deeeb2306891c25ce4db33599698cc6fcb2e82caad5aece9aa09",
+            "x86_64" to "23daf0750238cf96bf9ea9fa1b13ae1d2eeb17644ea5439e18939ec6a8b9e5be",
         )
     }
 
diff --git a/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt b/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt
index 0f42fdc..24d6649 100644
--- a/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt
+++ b/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt
@@ -21,7 +21,6 @@
 import android.widget.ImageView
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.transition.ktx.test.R
 import java.util.concurrent.CountDownLatch
@@ -32,7 +31,6 @@
 import org.junit.Rule
 import org.junit.Test
 
-@SdkSuppress(minSdkVersion = 19)
 @MediumTest
 class TransitionTest {
     @Suppress("DEPRECATION")
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java b/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java
index 3c27a70..92b0821 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java
@@ -26,7 +26,6 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.Build;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.LinearInterpolator;
@@ -92,11 +91,6 @@
 
     @Test
     public void testSuppressLayoutWhileAnimating() throws Throwable {
-        if (Build.VERSION.SDK_INT < 18) {
-            // prior Android 4.3 suppressLayout port has another implementation which is
-            // harder to test
-            return;
-        }
         final TestSuppressLayout suppressLayout = new TestSuppressLayout(rule.getActivity());
         final View testView = new View(rule.getActivity());
         rule.runOnUiThread(new Runnable() {
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java b/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java
index 5ba6b75..b1d6ce8 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java
@@ -50,7 +50,6 @@
         return new ChangeClipBounds();
     }
 
-    @SdkSuppress(minSdkVersion = 18)
     @Test
     public void testChangeClipBounds() throws Throwable {
         final View redSquare = spy(new View(rule.getActivity()));
diff --git a/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java b/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java
index 7aab444..1667459 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java
@@ -146,7 +146,7 @@
         verify(listenerOut, timeout(3000)).onTransitionPause(any(Transition.class));
         verify(listenerIn, timeout(3000)).onTransitionStart(any(Transition.class));
         assertThat(valuesOut[1], allOf(greaterThan(0f), lessThan(1f)));
-        if (Build.VERSION.SDK_INT >= 19 && fadeOut.mInitialAlpha >= 0) {
+        if (fadeOut.mInitialAlpha >= 0) {
             // These won't match on API levels 18 and below due to lack of Animator pause.
             assertEquals(valuesOut[1], valuesIn[0], 0.01f);
         }
@@ -182,7 +182,7 @@
         verify(listenerIn, timeout(3000)).onTransitionPause(any(Transition.class));
         verify(listenerOut, timeout(3000)).onTransitionStart(any(Transition.class));
         assertThat(valuesIn[1], allOf(greaterThan(0f), lessThan(1f)));
-        if (Build.VERSION.SDK_INT >= 19 && fadeIn.mInitialAlpha >= 0) {
+        if (fadeIn.mInitialAlpha >= 0) {
             // These won't match on API levels 18 and below due to lack of Animator pause.
             assertEquals(valuesIn[1], valuesOut[0], 0.01f);
         }
diff --git a/transition/transition/src/main/java/androidx/transition/AnimatorUtils.java b/transition/transition/src/main/java/androidx/transition/AnimatorUtils.java
deleted file mode 100644
index 7ce8668..0000000
--- a/transition/transition/src/main/java/androidx/transition/AnimatorUtils.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2017 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.transition;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.os.Build;
-
-import androidx.annotation.DoNotInline;
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-
-import java.util.ArrayList;
-
-class AnimatorUtils {
-
-    static void addPauseListener(@NonNull Animator animator,
-            @NonNull AnimatorListenerAdapter listener) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.addPauseListener(animator, listener);
-        }
-    }
-
-    static void pause(@NonNull Animator animator) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.pause(animator);
-        } else {
-            final ArrayList<Animator.AnimatorListener> listeners = animator.getListeners();
-            if (listeners != null) {
-                for (int i = 0, size = listeners.size(); i < size; i++) {
-                    final Animator.AnimatorListener listener = listeners.get(i);
-                    if (listener instanceof AnimatorPauseListenerCompat) {
-                        ((AnimatorPauseListenerCompat) listener).onAnimationPause(animator);
-                    }
-                }
-            }
-        }
-    }
-
-    static void resume(@NonNull Animator animator) {
-        if (Build.VERSION.SDK_INT >= 19) {
-            Api19Impl.resume(animator);
-        } else {
-            final ArrayList<Animator.AnimatorListener> listeners = animator.getListeners();
-            if (listeners != null) {
-                for (int i = 0, size = listeners.size(); i < size; i++) {
-                    final Animator.AnimatorListener listener = listeners.get(i);
-                    if (listener instanceof AnimatorPauseListenerCompat) {
-                        ((AnimatorPauseListenerCompat) listener).onAnimationResume(animator);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Listeners can implement this interface in addition to the platform AnimatorPauseListener to
-     * make them compatible with API level 18 and below. Animators will not be paused or resumed,
-     * but the callbacks here are invoked.
-     */
-    interface AnimatorPauseListenerCompat {
-
-        void onAnimationPause(Animator animation);
-
-        void onAnimationResume(Animator animation);
-
-    }
-
-    private AnimatorUtils() { }
-
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static void addPauseListener(Animator animator, AnimatorListenerAdapter listener) {
-            animator.addPauseListener(listener);
-        }
-        @DoNotInline
-        static void pause(Animator animator) {
-            animator.pause();
-        }@DoNotInline
-        static void resume(Animator animator) {
-            animator.resume();
-        }
-    }
-}
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java b/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java
index 1d6b6d0..a9cc6ba 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java
@@ -183,7 +183,7 @@
             animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
             Listener listener = new Listener(imageView, startMatrix, endMatrix);
             animator.addListener(listener);
-            AnimatorUtils.addPauseListener(animator, listener);
+            animator.addPauseListener(listener);
             addListener(listener);
         }
 
@@ -258,8 +258,7 @@
         return matrix;
     }
 
-    private static class Listener extends AnimatorListenerAdapter implements TransitionListener,
-            AnimatorUtils.AnimatorPauseListenerCompat {
+    private static class Listener extends AnimatorListenerAdapter implements TransitionListener {
         private final ImageView mImageView;
         private final Matrix mStartMatrix;
         private final Matrix mEndMatrix;
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeTransform.java b/transition/transition/src/main/java/androidx/transition/ChangeTransform.java
index 0d0cd09..0d5ae8f 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeTransform.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeTransform.java
@@ -330,7 +330,7 @@
                 handleParentChange, mUseOverlay);
 
         animator.addListener(listener);
-        AnimatorUtils.addPauseListener(animator, listener);
+        animator.addPauseListener(listener);
         return animator;
     }
 
@@ -551,8 +551,7 @@
         }
     }
 
-    private static class Listener extends AnimatorListenerAdapter implements
-            AnimatorUtils.AnimatorPauseListenerCompat {
+    private static class Listener extends AnimatorListenerAdapter {
         private boolean mIsCanceled;
         private final Matrix mTempMatrix = new Matrix();
         private final boolean mHandleParentChange;
diff --git a/transition/transition/src/main/java/androidx/transition/Transition.java b/transition/transition/src/main/java/androidx/transition/Transition.java
index 36f608c..4b41fcc 100644
--- a/transition/transition/src/main/java/androidx/transition/Transition.java
+++ b/transition/transition/src/main/java/androidx/transition/Transition.java
@@ -1831,7 +1831,7 @@
             for (int i = numAnimators - 1; i >= 0; i--) {
                 Animator animator = cache[i];
                 cache[i] = null;
-                AnimatorUtils.pause(animator);
+                animator.pause();
             }
             mAnimatorCache = cache;
             notifyListeners(TransitionNotification.ON_PAUSE, false);
@@ -1855,7 +1855,7 @@
                 for (int i = numAnimators - 1; i >= 0; i--) {
                     Animator animator = cache[i];
                     cache[i] = null;
-                    AnimatorUtils.resume(animator);
+                    animator.resume();
                 }
                 mAnimatorCache = cache;
                 notifyListeners(TransitionNotification.ON_RESUME, false);
diff --git a/transition/transition/src/main/java/androidx/transition/TransitionUtils.java b/transition/transition/src/main/java/androidx/transition/TransitionUtils.java
index 960a640..3e323a0d 100644
--- a/transition/transition/src/main/java/androidx/transition/TransitionUtils.java
+++ b/transition/transition/src/main/java/androidx/transition/TransitionUtils.java
@@ -36,10 +36,6 @@
 class TransitionUtils {
 
     private static final int MAX_IMAGE_SIZE = 1024 * 1024;
-    private static final boolean HAS_IS_ATTACHED_TO_WINDOW =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
-    private static final boolean HAS_OVERLAY =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
     private static final boolean HAS_PICTURE_BITMAP =
             Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
 
@@ -94,22 +90,18 @@
             ViewGroup sceneRoot) {
         final boolean addToOverlay;
         final boolean sceneRootIsAttached;
-        if (HAS_IS_ATTACHED_TO_WINDOW) {
-            addToOverlay = !Api19Impl.isAttachedToWindow(view);
-            sceneRootIsAttached = sceneRoot != null && Api19Impl.isAttachedToWindow(sceneRoot);
-        } else {
-            addToOverlay = false;
-            sceneRootIsAttached = false;
-        }
+        addToOverlay = !view.isAttachedToWindow();
+        sceneRootIsAttached = sceneRoot != null && sceneRoot.isAttachedToWindow();
         ViewGroup parent = null;
         int indexInParent = 0;
-        if (HAS_OVERLAY && addToOverlay) {
+        if (addToOverlay) {
             if (!sceneRootIsAttached) {
                 return null;
             }
             parent = (ViewGroup) view.getParent();
             indexInParent = parent.indexOfChild(view);
-            Api18Impl.getOverlayAndAdd(sceneRoot, view);
+            ViewGroupOverlay result = sceneRoot.getOverlay();
+            result.add(view);
         }
         Bitmap bitmap = null;
         int bitmapWidth = Math.round(bounds.width());
@@ -137,8 +129,9 @@
                 view.draw(canvas);
             }
         }
-        if (HAS_OVERLAY && addToOverlay) {
-            Api18Impl.getOverlayAndRemove(sceneRoot, view);
+        if (addToOverlay) {
+            ViewGroupOverlay result = sceneRoot.getOverlay();
+            result.remove(view);
             parent.addView(view, indexInParent);
         }
         return bitmap;
@@ -180,26 +173,6 @@
 
     private TransitionUtils() { }
 
-    @RequiresApi(18)
-    static class Api18Impl {
-        private Api18Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static ViewGroupOverlay getOverlayAndAdd(ViewGroup viewGroup, View toAdd) {
-            ViewGroupOverlay result = viewGroup.getOverlay();
-            result.add(toAdd);
-            return result;
-        }
-
-        @DoNotInline
-        static ViewGroupOverlay getOverlayAndRemove(ViewGroup viewGroup, View toRemove) {
-            ViewGroupOverlay result = viewGroup.getOverlay();
-            result.remove(toRemove);
-            return result;
-        }
-    }
     @RequiresApi(28)
     static class Api28Impl {
         private Api28Impl() {
@@ -212,15 +185,4 @@
         }
 
     }
-    @RequiresApi(19)
-    static class Api19Impl {
-        private Api19Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static boolean isAttachedToWindow(View view) {
-            return view.isAttachedToWindow();
-        }
-    }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/ViewGroupOverlayApi18.java b/transition/transition/src/main/java/androidx/transition/ViewGroupOverlayApi18.java
index 20e4282..4c5f4e8 100644
--- a/transition/transition/src/main/java/androidx/transition/ViewGroupOverlayApi18.java
+++ b/transition/transition/src/main/java/androidx/transition/ViewGroupOverlayApi18.java
@@ -22,9 +22,7 @@
 import android.view.ViewGroupOverlay;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 
-@RequiresApi(18)
 class ViewGroupOverlayApi18 implements ViewGroupOverlayImpl {
 
     private final ViewGroupOverlay mViewGroupOverlay;
diff --git a/transition/transition/src/main/java/androidx/transition/ViewGroupUtils.java b/transition/transition/src/main/java/androidx/transition/ViewGroupUtils.java
index 37126f5..52c2f97 100644
--- a/transition/transition/src/main/java/androidx/transition/ViewGroupUtils.java
+++ b/transition/transition/src/main/java/androidx/transition/ViewGroupUtils.java
@@ -44,10 +44,7 @@
      * Backward-compatible {@link ViewGroup#getOverlay()}.
      */
     static ViewGroupOverlayImpl getOverlay(@NonNull ViewGroup group) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return new ViewGroupOverlayApi18(group);
-        }
-        return ViewGroupOverlayApi14.createFrom(group);
+        return new ViewGroupOverlayApi18(group);
     }
 
     /**
@@ -56,14 +53,11 @@
     static void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
         if (Build.VERSION.SDK_INT >= 29) {
             Api29Impl.suppressLayout(group, suppress);
-        } else if (Build.VERSION.SDK_INT >= 18) {
-            hiddenSuppressLayout(group, suppress);
         } else {
-            ViewGroupUtilsApi14.suppressLayout(group, suppress);
+            hiddenSuppressLayout(group, suppress);
         }
     }
 
-    @RequiresApi(18)
     @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     private static void hiddenSuppressLayout(@NonNull ViewGroup group, boolean suppress) {
         if (sTryHiddenSuppressLayout) {
diff --git a/transition/transition/src/main/java/androidx/transition/ViewGroupUtilsApi14.java b/transition/transition/src/main/java/androidx/transition/ViewGroupUtilsApi14.java
deleted file mode 100644
index 2a83cc1..0000000
--- a/transition/transition/src/main/java/androidx/transition/ViewGroupUtilsApi14.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2016 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.transition;
-
-import android.animation.LayoutTransition;
-import android.annotation.SuppressLint;
-import android.util.Log;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-class ViewGroupUtilsApi14 {
-
-    private static final String TAG = "ViewGroupUtilsApi14";
-
-    private static final int LAYOUT_TRANSITION_CHANGING = 4;
-
-    private static LayoutTransition sEmptyLayoutTransition;
-
-    private static Field sLayoutSuppressedField;
-    private static boolean sLayoutSuppressedFieldFetched;
-
-    private static Method sCancelMethod;
-    private static boolean sCancelMethodFetched;
-
-    static void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
-        // Prepare the empty LayoutTransition
-        if (sEmptyLayoutTransition == null) {
-            sEmptyLayoutTransition = new LayoutTransition() {
-                @Override
-                public boolean isChangingLayout() {
-                    return true;
-                }
-            };
-            sEmptyLayoutTransition.setAnimator(LayoutTransition.APPEARING, null);
-            sEmptyLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
-            sEmptyLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
-            sEmptyLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, null);
-            sEmptyLayoutTransition.setAnimator(LAYOUT_TRANSITION_CHANGING, null);
-        }
-        if (suppress) {
-            // Save the current LayoutTransition
-            final LayoutTransition layoutTransition = group.getLayoutTransition();
-            if (layoutTransition != null) {
-                if (layoutTransition.isRunning()) {
-                    cancelLayoutTransition(layoutTransition);
-                }
-                if (layoutTransition != sEmptyLayoutTransition) {
-                    group.setTag(R.id.transition_layout_save, layoutTransition);
-                }
-            }
-            // Suppress the layout
-            group.setLayoutTransition(sEmptyLayoutTransition);
-        } else {
-            // Thaw the layout suppression
-            group.setLayoutTransition(null);
-            // Request layout if necessary
-            if (!sLayoutSuppressedFieldFetched) {
-                try {
-                    sLayoutSuppressedField = ViewGroup.class.getDeclaredField("mLayoutSuppressed");
-                    sLayoutSuppressedField.setAccessible(true);
-                } catch (NoSuchFieldException e) {
-                    Log.i(TAG, "Failed to access mLayoutSuppressed field by reflection");
-                }
-                sLayoutSuppressedFieldFetched = true;
-            }
-            boolean layoutSuppressed = false;
-            if (sLayoutSuppressedField != null) {
-                try {
-                    layoutSuppressed = sLayoutSuppressedField.getBoolean(group);
-                    if (layoutSuppressed) {
-                        sLayoutSuppressedField.setBoolean(group, false);
-                    }
-                } catch (IllegalAccessException e) {
-                    Log.i(TAG, "Failed to get mLayoutSuppressed field by reflection");
-                }
-            }
-            if (layoutSuppressed) {
-                group.requestLayout();
-            }
-            // Restore the saved LayoutTransition
-            final LayoutTransition layoutTransition =
-                    (LayoutTransition) group.getTag(R.id.transition_layout_save);
-            if (layoutTransition != null) {
-                group.setTag(R.id.transition_layout_save, null);
-                group.setLayoutTransition(layoutTransition);
-            }
-        }
-    }
-
-    /**
-     * Note, this is only called on API 17 and older.
-     */
-    @SuppressLint({"SoonBlockedPrivateApi", "BanUncheckedReflection"})
-    private static void cancelLayoutTransition(LayoutTransition t) {
-        if (!sCancelMethodFetched) {
-            try {
-                sCancelMethod = LayoutTransition.class.getDeclaredMethod("cancel");
-                sCancelMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to access cancel method by reflection");
-            }
-            sCancelMethodFetched = true;
-        }
-        if (sCancelMethod != null) {
-            try {
-                sCancelMethod.invoke(t);
-            } catch (IllegalAccessException e) {
-                Log.i(TAG, "Failed to access cancel method by reflection");
-            } catch (InvocationTargetException e) {
-                Log.i(TAG, "Failed to invoke cancel method by reflection");
-            }
-        }
-    }
-
-    private ViewGroupUtilsApi14() {
-    }
-}
diff --git a/transition/transition/src/main/java/androidx/transition/ViewUtils.java b/transition/transition/src/main/java/androidx/transition/ViewUtils.java
index 388c11d..1cd039c 100644
--- a/transition/transition/src/main/java/androidx/transition/ViewUtils.java
+++ b/transition/transition/src/main/java/androidx/transition/ViewUtils.java
@@ -31,7 +31,7 @@
  */
 class ViewUtils {
 
-    private static final ViewUtilsBase IMPL;
+    private static final ViewUtilsApi19 IMPL;
     private static final String TAG = "ViewUtils";
 
     static {
@@ -43,10 +43,8 @@
             IMPL = new ViewUtilsApi22();
         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             IMPL = new ViewUtilsApi21();
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            IMPL = new ViewUtilsApi19();
         } else {
-            IMPL = new ViewUtilsBase();
+            IMPL = new ViewUtilsApi19();
         }
     }
 
@@ -87,20 +85,14 @@
      * Backward-compatible {@link View#getOverlay()}.
      */
     static ViewOverlayImpl getOverlay(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return new ViewOverlayApi18(view);
-        }
-        return ViewOverlayApi14.createFrom(view);
+        return new ViewOverlayApi18(view);
     }
 
     /**
      * Backward-compatible {@link View#getWindowId()}.
      */
     static @NonNull WindowIdImpl getWindowId(@NonNull View view) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            return new WindowIdApi18(view);
-        }
-        return new WindowIdApi14(view.getWindowToken());
+        return new WindowIdApi18(view);
     }
 
     static void setTransitionAlpha(@NonNull View view, float alpha) {
diff --git a/transition/transition/src/main/java/androidx/transition/ViewUtilsApi19.java b/transition/transition/src/main/java/androidx/transition/ViewUtilsApi19.java
index 3668345..448ba3a 100644
--- a/transition/transition/src/main/java/androidx/transition/ViewUtilsApi19.java
+++ b/transition/transition/src/main/java/androidx/transition/ViewUtilsApi19.java
@@ -17,21 +17,36 @@
 package androidx.transition;
 
 import android.annotation.SuppressLint;
+import android.graphics.Matrix;
+import android.util.Log;
 import android.view.View;
+import android.view.ViewParent;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
-@RequiresApi(19)
-class ViewUtilsApi19 extends ViewUtilsBase {
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+class ViewUtilsApi19 {
+
+    private static final String TAG = "ViewUtilsApi19";
 
     /**
      * False when linking of the hidden set[get]TransitionAlpha method has previously failed.
      */
     private static boolean sTryHiddenTransitionAlpha = true;
+    private static Method sSetFrameMethod;
+    private static boolean sSetFrameFetched;
 
-    @Override
+    private static Field sViewFlagsField;
+    private static boolean sViewFlagsFieldFetched;
+    private static final int VISIBILITY_MASK = 0x0000000C;
+
+    private float[] mMatrixValues;
     @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     public void setTransitionAlpha(@NonNull View view, float alpha) {
         if (sTryHiddenTransitionAlpha) {
@@ -47,7 +62,6 @@
         view.setAlpha(alpha);
     }
 
-    @Override
     @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     public float getTransitionAlpha(@NonNull View view) {
         if (sTryHiddenTransitionAlpha) {
@@ -62,16 +76,130 @@
         return view.getAlpha();
     }
 
-    @Override
     public void saveNonTransitionAlpha(@NonNull View view) {
         // Do nothing
     }
 
-    @Override
     public void clearNonTransitionAlpha(@NonNull View view) {
         // Do nothing
     }
 
+    public void transformMatrixToGlobal(@NonNull View view, @NonNull Matrix matrix) {
+        final ViewParent parent = view.getParent();
+        if (parent instanceof View) {
+            final View vp = (View) parent;
+            transformMatrixToGlobal(vp, matrix);
+            matrix.preTranslate(-vp.getScrollX(), -vp.getScrollY());
+        }
+        matrix.preTranslate(view.getLeft(), view.getTop());
+        final Matrix vm = view.getMatrix();
+        if (!vm.isIdentity()) {
+            matrix.preConcat(vm);
+        }
+    }
+
+    public void transformMatrixToLocal(@NonNull View view, @NonNull Matrix matrix) {
+        final ViewParent parent = view.getParent();
+        if (parent instanceof View) {
+            final View vp = (View) parent;
+            transformMatrixToLocal(vp, matrix);
+            matrix.postTranslate(vp.getScrollX(), vp.getScrollY());
+        }
+        matrix.postTranslate(-view.getLeft(), -view.getTop());
+        final Matrix vm = view.getMatrix();
+        if (!vm.isIdentity()) {
+            final Matrix inverted = new Matrix();
+            if (vm.invert(inverted)) {
+                matrix.postConcat(inverted);
+            }
+        }
+    }
+
+    public void setAnimationMatrix(@NonNull View view, @Nullable Matrix matrix) {
+        if (matrix == null || matrix.isIdentity()) {
+            view.setPivotX(view.getWidth() / 2);
+            view.setPivotY(view.getHeight() / 2);
+            view.setTranslationX(0);
+            view.setTranslationY(0);
+            view.setScaleX(1);
+            view.setScaleY(1);
+            view.setRotation(0);
+        } else {
+            float[] values = mMatrixValues;
+            if (values == null) {
+                mMatrixValues = values = new float[9];
+            }
+            matrix.getValues(values);
+            final float sin = values[Matrix.MSKEW_Y];
+            final float cos = (float) Math.sqrt(1 - sin * sin)
+                    * (values[Matrix.MSCALE_X] < 0 ? -1 : 1);
+            final float rotation = (float) Math.toDegrees(Math.atan2(sin, cos));
+            final float scaleX = values[Matrix.MSCALE_X] / cos;
+            final float scaleY = values[Matrix.MSCALE_Y] / cos;
+            final float dx = values[Matrix.MTRANS_X];
+            final float dy = values[Matrix.MTRANS_Y];
+            view.setPivotX(0);
+            view.setPivotY(0);
+            view.setTranslationX(dx);
+            view.setTranslationY(dy);
+            view.setRotation(rotation);
+            view.setScaleX(scaleX);
+            view.setScaleY(scaleY);
+        }
+    }
+
+    @SuppressLint("BanUncheckedReflection") // This class is only used on APIs 14-18
+    public void setLeftTopRightBottom(@NonNull View v, int left, int top, int right, int bottom) {
+        fetchSetFrame();
+        if (sSetFrameMethod != null) {
+            try {
+                sSetFrameMethod.invoke(v, left, top, right, bottom);
+            } catch (IllegalAccessException e) {
+                // Do nothing
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e.getCause());
+            }
+        }
+    }
+
+    @SuppressLint("SoonBlockedPrivateApi") // Only called on API <23
+    public void setTransitionVisibility(@NonNull View view, int visibility) {
+        if (!sViewFlagsFieldFetched) {
+            try {
+                sViewFlagsField = View.class.getDeclaredField("mViewFlags");
+                sViewFlagsField.setAccessible(true);
+            } catch (NoSuchFieldException e) {
+                Log.i(TAG, "fetchViewFlagsField: ");
+            }
+            sViewFlagsFieldFetched = true;
+        }
+        if (sViewFlagsField != null) {
+            try {
+                int viewFlags = sViewFlagsField.getInt(view);
+                sViewFlagsField.setInt(view, (viewFlags & ~VISIBILITY_MASK) | visibility);
+            } catch (IllegalAccessException e) {
+                // Do nothing
+            }
+        }
+    }
+
+    /**
+     * Note, this is only called on API 18 and older.
+     */
+    @SuppressLint({"PrivateApi", "SoonBlockedPrivateApi"})
+    private void fetchSetFrame() {
+        if (!sSetFrameFetched) {
+            try {
+                sSetFrameMethod = View.class.getDeclaredMethod("setFrame",
+                        int.class, int.class, int.class, int.class);
+                sSetFrameMethod.setAccessible(true);
+            } catch (NoSuchMethodException e) {
+                Log.i(TAG, "Failed to retrieve setFrame method", e);
+            }
+            sSetFrameFetched = true;
+        }
+    }
+
     @RequiresApi(29)
     static class Api29Impl {
         private Api29Impl() {
diff --git a/transition/transition/src/main/java/androidx/transition/ViewUtilsBase.java b/transition/transition/src/main/java/androidx/transition/ViewUtilsBase.java
deleted file mode 100644
index 535f18c..0000000
--- a/transition/transition/src/main/java/androidx/transition/ViewUtilsBase.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2016 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.transition;
-
-import android.annotation.SuppressLint;
-import android.graphics.Matrix;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewParent;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-// This class is guaranteed to only be called on SDKs 14-18 due to gating
-class ViewUtilsBase {
-
-    private static final String TAG = "ViewUtilsBase";
-
-    private static Method sSetFrameMethod;
-    private static boolean sSetFrameFetched;
-
-    private static Field sViewFlagsField;
-    private static boolean sViewFlagsFieldFetched;
-    private static final int VISIBILITY_MASK = 0x0000000C;
-
-    private float[] mMatrixValues;
-
-    public void setTransitionAlpha(@NonNull View view, float alpha) {
-        Float savedAlpha = (Float) view.getTag(R.id.save_non_transition_alpha);
-        if (savedAlpha != null) {
-            view.setAlpha(savedAlpha * alpha);
-        } else {
-            view.setAlpha(alpha);
-        }
-    }
-
-    public float getTransitionAlpha(@NonNull View view) {
-        Float savedAlpha = (Float) view.getTag(R.id.save_non_transition_alpha);
-        if (savedAlpha != null) {
-            return view.getAlpha() / savedAlpha;
-        } else {
-            return view.getAlpha();
-        }
-    }
-
-    public void saveNonTransitionAlpha(@NonNull View view) {
-        if (view.getTag(R.id.save_non_transition_alpha) == null) {
-            view.setTag(R.id.save_non_transition_alpha, view.getAlpha());
-        }
-    }
-
-    public void clearNonTransitionAlpha(@NonNull View view) {
-        // We don't clear the saved value when the view is hidden; that's the situation we are
-        // saving this value for.
-        if (view.getVisibility() == View.VISIBLE) {
-            view.setTag(R.id.save_non_transition_alpha, null);
-        }
-    }
-
-    public void transformMatrixToGlobal(@NonNull View view, @NonNull Matrix matrix) {
-        final ViewParent parent = view.getParent();
-        if (parent instanceof View) {
-            final View vp = (View) parent;
-            transformMatrixToGlobal(vp, matrix);
-            matrix.preTranslate(-vp.getScrollX(), -vp.getScrollY());
-        }
-        matrix.preTranslate(view.getLeft(), view.getTop());
-        final Matrix vm = view.getMatrix();
-        if (!vm.isIdentity()) {
-            matrix.preConcat(vm);
-        }
-    }
-
-    public void transformMatrixToLocal(@NonNull View view, @NonNull Matrix matrix) {
-        final ViewParent parent = view.getParent();
-        if (parent instanceof View) {
-            final View vp = (View) parent;
-            transformMatrixToLocal(vp, matrix);
-            matrix.postTranslate(vp.getScrollX(), vp.getScrollY());
-        }
-        matrix.postTranslate(-view.getLeft(), -view.getTop());
-        final Matrix vm = view.getMatrix();
-        if (!vm.isIdentity()) {
-            final Matrix inverted = new Matrix();
-            if (vm.invert(inverted)) {
-                matrix.postConcat(inverted);
-            }
-        }
-    }
-
-    public void setAnimationMatrix(@NonNull View view, @Nullable Matrix matrix) {
-        if (matrix == null || matrix.isIdentity()) {
-            view.setPivotX(view.getWidth() / 2);
-            view.setPivotY(view.getHeight() / 2);
-            view.setTranslationX(0);
-            view.setTranslationY(0);
-            view.setScaleX(1);
-            view.setScaleY(1);
-            view.setRotation(0);
-        } else {
-            float[] values = mMatrixValues;
-            if (values == null) {
-                mMatrixValues = values = new float[9];
-            }
-            matrix.getValues(values);
-            final float sin = values[Matrix.MSKEW_Y];
-            final float cos = (float) Math.sqrt(1 - sin * sin)
-                    * (values[Matrix.MSCALE_X] < 0 ? -1 : 1);
-            final float rotation = (float) Math.toDegrees(Math.atan2(sin, cos));
-            final float scaleX = values[Matrix.MSCALE_X] / cos;
-            final float scaleY = values[Matrix.MSCALE_Y] / cos;
-            final float dx = values[Matrix.MTRANS_X];
-            final float dy = values[Matrix.MTRANS_Y];
-            view.setPivotX(0);
-            view.setPivotY(0);
-            view.setTranslationX(dx);
-            view.setTranslationY(dy);
-            view.setRotation(rotation);
-            view.setScaleX(scaleX);
-            view.setScaleY(scaleY);
-        }
-    }
-
-    @SuppressLint("BanUncheckedReflection") // This class is only used on APIs 14-18
-    public void setLeftTopRightBottom(@NonNull View v, int left, int top, int right, int bottom) {
-        fetchSetFrame();
-        if (sSetFrameMethod != null) {
-            try {
-                sSetFrameMethod.invoke(v, left, top, right, bottom);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
-            }
-        }
-    }
-
-    @SuppressLint("SoonBlockedPrivateApi") // Only called on API <23
-    public void setTransitionVisibility(@NonNull View view, int visibility) {
-        if (!sViewFlagsFieldFetched) {
-            try {
-                sViewFlagsField = View.class.getDeclaredField("mViewFlags");
-                sViewFlagsField.setAccessible(true);
-            } catch (NoSuchFieldException e) {
-                Log.i(TAG, "fetchViewFlagsField: ");
-            }
-            sViewFlagsFieldFetched = true;
-        }
-        if (sViewFlagsField != null) {
-            try {
-                int viewFlags = sViewFlagsField.getInt(view);
-                sViewFlagsField.setInt(view, (viewFlags & ~VISIBILITY_MASK) | visibility);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            }
-        }
-    }
-
-    /**
-     * Note, this is only called on API 18 and older.
-     */
-    @SuppressLint({"PrivateApi", "SoonBlockedPrivateApi"})
-    private void fetchSetFrame() {
-        if (!sSetFrameFetched) {
-            try {
-                sSetFrameMethod = View.class.getDeclaredMethod("setFrame",
-                        int.class, int.class, int.class, int.class);
-                sSetFrameMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve setFrame method", e);
-            }
-            sSetFrameFetched = true;
-        }
-    }
-
-}
diff --git a/transition/transition/src/main/java/androidx/transition/Visibility.java b/transition/transition/src/main/java/androidx/transition/Visibility.java
index 8b3fc2e..7b42e21 100644
--- a/transition/transition/src/main/java/androidx/transition/Visibility.java
+++ b/transition/transition/src/main/java/androidx/transition/Visibility.java
@@ -441,7 +441,7 @@
                             startView);
 
                     animator.addListener(listener);
-                    AnimatorUtils.addPauseListener(animator, listener);
+                    animator.addPauseListener(listener);
                     getRootTransition().addListener(listener);
                 }
             }
@@ -610,8 +610,7 @@
         }
     }
 
-    private class OverlayListener extends AnimatorListenerAdapter implements TransitionListener,
-            AnimatorUtils.AnimatorPauseListenerCompat {
+    private class OverlayListener extends AnimatorListenerAdapter implements TransitionListener {
         private final ViewGroup mOverlayHost;
         private final View mOverlayView;
         private final View mStartView;
diff --git a/transition/transition/src/main/java/androidx/transition/WindowIdApi14.java b/transition/transition/src/main/java/androidx/transition/WindowIdApi14.java
deleted file mode 100644
index 6a9231e..0000000
--- a/transition/transition/src/main/java/androidx/transition/WindowIdApi14.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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.transition;
-
-import android.os.IBinder;
-
-class WindowIdApi14 implements WindowIdImpl {
-
-    private final IBinder mToken;
-
-    WindowIdApi14(IBinder token) {
-        mToken = token;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        return o instanceof WindowIdApi14 && ((WindowIdApi14) o).mToken.equals(this.mToken);
-    }
-
-    @Override
-    public int hashCode() {
-        return mToken.hashCode();
-    }
-}
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TextField.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TextField.kt
index de4d6e1..7c71660 100644
--- a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TextField.kt
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TextField.kt
@@ -41,7 +41,7 @@
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.ExperimentalTvFoundationApi
-import androidx.tv.foundation.text.AndroidImeOptions
+import androidx.tv.foundation.text.PlatformImeOptions
 import androidx.tv.foundation.text.TvKeyboardAlignment
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.MaterialTheme
@@ -87,7 +87,7 @@
         },
         keyboardOptions = KeyboardOptions(
             keyboardType = keyboardType,
-            platformImeOptions = AndroidImeOptions(TvKeyboardAlignment.Left),
+            platformImeOptions = PlatformImeOptions(TvKeyboardAlignment.Left),
             imeAction = ImeAction.Next
         ),
         colors = OutlinedTextFieldDefaults.colors(
diff --git a/tv/tv-foundation/api/current.txt b/tv/tv-foundation/api/current.txt
index 2049638..daa9a60 100644
--- a/tv/tv-foundation/api/current.txt
+++ b/tv/tv-foundation/api/current.txt
@@ -254,8 +254,8 @@
 package androidx.tv.foundation.text {
 
   public final class TvImeOptionsKt {
-    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.AndroidImeOptions AndroidImeOptions(androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
-    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.AndroidImeOptions keyboardAlignment(androidx.compose.ui.text.input.AndroidImeOptions, androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
+    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.PlatformImeOptions PlatformImeOptions(androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
+    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.PlatformImeOptions keyboardAlignment(androidx.compose.ui.text.input.PlatformImeOptions, androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
   }
 
   @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public enum TvKeyboardAlignment {
diff --git a/tv/tv-foundation/api/restricted_current.txt b/tv/tv-foundation/api/restricted_current.txt
index 2049638..daa9a60 100644
--- a/tv/tv-foundation/api/restricted_current.txt
+++ b/tv/tv-foundation/api/restricted_current.txt
@@ -254,8 +254,8 @@
 package androidx.tv.foundation.text {
 
   public final class TvImeOptionsKt {
-    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.AndroidImeOptions AndroidImeOptions(androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
-    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.AndroidImeOptions keyboardAlignment(androidx.compose.ui.text.input.AndroidImeOptions, androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
+    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.PlatformImeOptions PlatformImeOptions(androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
+    method @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public static androidx.compose.ui.text.input.PlatformImeOptions keyboardAlignment(androidx.compose.ui.text.input.PlatformImeOptions, androidx.tv.foundation.text.TvKeyboardAlignment horizontalAlignment);
   }
 
   @SuppressCompatibility @androidx.tv.foundation.ExperimentalTvFoundationApi public enum TvKeyboardAlignment {
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridTest.kt
index 13b3fde..5a30ac2 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridTest.kt
@@ -59,7 +59,6 @@
 import androidx.tv.foundation.lazy.list.setContentWithTestViewConfiguration
 import com.google.common.collect.Range
 import com.google.common.truth.IntegerSubject
-import com.google.common.truth.Truth
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.runBlocking
 import org.junit.Test
@@ -71,6 +70,8 @@
 class LazyGridTest(
     private val orientation: Orientation
 ) : BaseLazyGridTestWithOrientation(orientation) {
+
+    @Suppress("PrivatePropertyName")
     private val LazyGridTag = "LazyGridTag"
 
     companion object {
@@ -148,7 +149,7 @@
             }
         }
 
-        rule.keyPress(3)
+        rule.keyPress(2)
 
         rule.onNodeWithTag("4")
             .assertIsDisplayed()
@@ -670,9 +671,9 @@
                 state.scrollToItem(50)
             }
             composedIndexes.forEach {
-                Truth.assertThat(it).isLessThan(count)
+                assertThat(it).isLessThan(count)
             }
-            Truth.assertThat(state.firstVisibleItemIndex).isEqualTo(9)
+            assertThat(state.firstVisibleItemIndex).isEqualTo(9)
         }
     }
 
@@ -723,7 +724,7 @@
             }
         }
 
-        rule.keyPress(3)
+        rule.keyPress(2)
 
         rule.onNodeWithTag("1")
             .assertMainAxisStartPositionInRootIsEqualTo(0.dp)
@@ -891,7 +892,7 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(exception).isInstanceOf(IllegalArgumentException::class.java)
+            assertThat(exception).isInstanceOf(IllegalArgumentException::class.java)
         }
     }
 
@@ -922,17 +923,17 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(remeasureCount).isEqualTo(1)
+            assertThat(remeasureCount).isEqualTo(1)
             counter.value++
         }
 
         rule.runOnIdle {
-            Truth.assertThat(remeasureCount).isEqualTo(1)
+            assertThat(remeasureCount).isEqualTo(1)
         }
     }
 
     @Test
-    fun scrollingALotDoesntCauseLazyLayoutRecomposition() {
+    fun scrollingALotDoesNotCauseLazyLayoutRecomposition() {
         var recomposeCount = 0
         lateinit var state: TvLazyGridState
 
@@ -953,7 +954,7 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(recomposeCount).isEqualTo(1)
+            assertThat(recomposeCount).isEqualTo(1)
 
             runBlocking {
                 state.scrollToItem(100)
@@ -961,7 +962,7 @@
         }
 
         rule.runOnIdle {
-            Truth.assertThat(recomposeCount).isEqualTo(1)
+            assertThat(recomposeCount).isEqualTo(1)
         }
     }
 
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt
index 4d8ad86..196d022 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt
@@ -34,16 +34,20 @@
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
 import androidx.tv.foundation.lazy.list.setContentWithTestViewConfiguration
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
 
+private const val ContainerTag = "ContainerTag"
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
 class LazyGridsReverseLayoutTest {
-
-    private val ContainerTag = "ContainerTag"
-
     @get:Rule
     val rule = createComposeRule()
 
@@ -164,7 +168,7 @@
         }
 
         // we scroll down and as the scrolling is reversed it shouldn't affect anything
-        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_UP, 2)
+        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_DOWN, 2)
 
         rule.runOnIdle {
             assertThat(state.firstVisibleItemScrollOffset).isEqualTo(0)
@@ -193,7 +197,7 @@
             }
         }
 
-        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_DOWN, 2)
+        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_DOWN, 1)
 
         val scrolled = rule.runOnIdle {
             assertThat(state.firstVisibleItemScrollOffset).isGreaterThan(0)
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
index baf2ba0..4fd6a16 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
@@ -93,8 +93,10 @@
 @LargeTest
 @RunWith(Parameterized::class)
 class LazyListTest(orientation: Orientation) : BaseLazyListTestWithOrientation(orientation) {
+    @Suppress("PrivatePropertyName")
     private val LazyListTag = "LazyListTag"
-    private val firstItemTag = "firstItemTag"
+    @Suppress("PrivatePropertyName")
+    private val FirstItemTag = "firstItemTag"
 
     @Test
     fun lazyListShowsCombinedItems() {
@@ -243,7 +245,7 @@
             }
         }
 
-        rule.keyPress(3)
+        rule.keyPress(2)
 
         rule.onNodeWithTag("1")
             .assertIsDisplayed()
@@ -274,7 +276,7 @@
             }
         }
 
-        rule.keyPress(3)
+        rule.keyPress(2)
 
         rule.onNodeWithTag("1")
             .assertIsNotDisplayed()
@@ -306,7 +308,7 @@
             }
         }
 
-        rule.keyPress(4)
+        rule.keyPress(3)
 
         rule.onNodeWithTag("1")
             .assertIsNotDisplayed()
@@ -463,7 +465,8 @@
             }
         }
 
-        rule.keyPress(3)
+        rule.waitForIdle()
+        rule.keyPress(2)
 
         rule.onNodeWithTag(thirdTag)
             .assertExists()
@@ -487,13 +490,13 @@
             LazyColumnOrRow(Modifier.requiredSize(width = 100.dp, height = 150.dp)) {
                 items(listOf(0)) {
                     Spacer(
-                        Modifier.fillParentMaxWidth().requiredHeight(50.dp).testTag(firstItemTag)
+                        Modifier.fillParentMaxWidth().requiredHeight(50.dp).testTag(FirstItemTag)
                     )
                 }
             }
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(100.dp)
             .assertHeightIsEqualTo(50.dp)
     }
@@ -504,13 +507,13 @@
             LazyColumnOrRow(Modifier.requiredSize(width = 100.dp, height = 150.dp)) {
                 items(listOf(0)) {
                     Spacer(
-                        Modifier.requiredWidth(50.dp).fillParentMaxHeight().testTag(firstItemTag)
+                        Modifier.requiredWidth(50.dp).fillParentMaxHeight().testTag(FirstItemTag)
                     )
                 }
             }
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(50.dp)
             .assertHeightIsEqualTo(150.dp)
     }
@@ -520,12 +523,12 @@
         rule.setContentWithTestViewConfiguration {
             LazyColumnOrRow(Modifier.requiredSize(width = 100.dp, height = 150.dp)) {
                 items(listOf(0)) {
-                    Spacer(Modifier.fillParentMaxSize().testTag(firstItemTag))
+                    Spacer(Modifier.fillParentMaxSize().testTag(FirstItemTag))
                 }
             }
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(100.dp)
             .assertHeightIsEqualTo(150.dp)
     }
@@ -538,13 +541,13 @@
                     Spacer(
                         Modifier.fillParentMaxWidth(0.7f)
                             .requiredHeight(50.dp)
-                            .testTag(firstItemTag)
+                            .testTag(FirstItemTag)
                     )
                 }
             }
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(70.dp)
             .assertHeightIsEqualTo(50.dp)
     }
@@ -557,13 +560,13 @@
                     Spacer(
                         Modifier.requiredWidth(50.dp)
                             .fillParentMaxHeight(0.3f)
-                            .testTag(firstItemTag)
+                            .testTag(FirstItemTag)
                     )
                 }
             }
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(50.dp)
             .assertHeightIsEqualTo(45.dp)
     }
@@ -573,12 +576,12 @@
         rule.setContentWithTestViewConfiguration {
             LazyColumnOrRow(Modifier.requiredSize(width = 100.dp, height = 150.dp)) {
                 items(listOf(0)) {
-                    Spacer(Modifier.fillParentMaxSize(0.5f).testTag(firstItemTag))
+                    Spacer(Modifier.fillParentMaxSize(0.5f).testTag(FirstItemTag))
                 }
             }
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(50.dp)
             .assertHeightIsEqualTo(75.dp)
     }
@@ -589,7 +592,7 @@
         rule.setContentWithTestViewConfiguration {
             LazyColumnOrRow(Modifier.requiredSize(parentSize)) {
                 items(listOf(0)) {
-                    Spacer(Modifier.fillParentMaxSize().testTag(firstItemTag))
+                    Spacer(Modifier.fillParentMaxSize().testTag(FirstItemTag))
                 }
             }
         }
@@ -598,7 +601,7 @@
             parentSize = 150.dp
         }
 
-        rule.onNodeWithTag(firstItemTag)
+        rule.onNodeWithTag(FirstItemTag)
             .assertWidthIsEqualTo(150.dp)
             .assertHeightIsEqualTo(150.dp)
     }
@@ -752,6 +755,8 @@
             }
         }
 
+        rule.waitForIdle()
+
         // getting focus to the first element
         rule.keyPress(2)
         // we already displaying the first item, so this should do nothing
@@ -1066,12 +1071,10 @@
             ) {
                 items(items) {
                     Spacer(
-                        if (it == 0) {
-                            Modifier.crossAxisSize(30.dp).mainAxisSize(itemSize / 2)
-                        } else if (it == 1) {
-                            Modifier.crossAxisSize(20.dp).mainAxisSize(itemSize / 2)
-                        } else {
-                            Modifier.crossAxisSize(20.dp).mainAxisSize(itemSize)
+                        when (it) {
+                            0 -> Modifier.crossAxisSize(30.dp).mainAxisSize(itemSize / 2)
+                            1 -> Modifier.crossAxisSize(20.dp).mainAxisSize(itemSize / 2)
+                            else -> Modifier.crossAxisSize(20.dp).mainAxisSize(itemSize)
                         }
                     )
                 }
@@ -1161,7 +1164,7 @@
     }
 
     @Test
-    fun overscrollingBackwardFromNotTheFirstPosition() {
+    fun overScrollingBackwardFromNotTheFirstPosition() {
         val containerTag = "container"
         val itemSizePx = 10
         val itemSizeDp = with(rule.density) { itemSizePx.toDp() }
@@ -1513,7 +1516,7 @@
             }
         }
 
-        rule.keyPress(3)
+        rule.keyPress(2)
 
         rule.onNodeWithTag("1")
             .assertStartPositionInRootIsEqualTo(0.dp)
@@ -1687,7 +1690,7 @@
     }
 
     @Test
-    fun scrollingALotDoesntCauseLazyLayoutRecomposition() {
+    fun scrollingALotDoesNotCauseLazyLayoutRecomposition() {
         var recomposeCount = 0
         lateinit var state: TvLazyListState
 
@@ -1759,8 +1762,8 @@
                         Box(Modifier.fillParentMaxSize())
                     }
                 }
-            }) { measurables, _ ->
-                val placeable = measurables.first().measure(constraints)
+            }) { measurableList, _ ->
+                val placeable = measurableList.first().measure(constraints)
                 layout(constraints.maxWidth, constraints.maxHeight) {
                     placeable.place(0, 0)
                 }
@@ -1789,13 +1792,13 @@
                                 .testTag("item"))
                     }
                 }
-            }) { measurables, _ ->
+            }) { measurableList, _ ->
                 val crossInfinityConstraints = if (vertical) {
                     Constraints(maxWidth = Constraints.Infinity, maxHeight = 100)
                 } else {
                     Constraints(maxWidth = 100, maxHeight = Constraints.Infinity)
                 }
-                val placeable = measurables.first().measure(crossInfinityConstraints)
+                val placeable = measurableList.first().measure(crossInfinityConstraints)
                 layout(placeable.width, placeable.height) {
                     placeable.place(0, 0)
                 }
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsReverseLayoutTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsReverseLayoutTest.kt
index 4ec7ab7..32ee3a2 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsReverseLayoutTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsReverseLayoutTest.kt
@@ -34,15 +34,22 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.MediumTest
 import androidx.tv.foundation.PivotOffsets
 import androidx.tv.foundation.lazy.grid.keyPress
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
 
+@MediumTest
+@RunWith(AndroidJUnit4::class)
 class LazyListsReverseLayoutTest {
 
+    @Suppress("PrivatePropertyName")
     private val ContainerTag = "ContainerTag"
 
     @get:Rule
@@ -151,6 +158,7 @@
             .assertTopPositionInRootIsEqualTo(itemSize)
     }
 
+    @FlakyTest(bugId = 313465577)
     @Test
     fun column_scrollForwardHalfWay() {
         lateinit var state: TvLazyListState
@@ -167,7 +175,7 @@
             }
         }
 
-        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_UP, 3)
+        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_UP, 1)
 
         val scrolled = rule.runOnIdle {
             assertThat(state.firstVisibleItemIndex).isEqualTo(0)
@@ -310,6 +318,7 @@
             .assertLeftPositionInRootIsEqualTo(itemSize)
     }
 
+    @FlakyTest(bugId = 313465577)
     @Test
     fun row_scrollForwardHalfWay() {
         lateinit var state: TvLazyListState
@@ -326,7 +335,7 @@
             }
         }
 
-        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_LEFT, 3)
+        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_LEFT, 1)
 
         val scrolled = rule.runOnIdle {
             assertThat(state.firstVisibleItemScrollOffset).isGreaterThan(0)
@@ -438,7 +447,7 @@
             }
         }
 
-        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_RIGHT, 3)
+        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_RIGHT, 2)
 
         val scrolled = rule.runOnIdle {
             assertThat(state.firstVisibleItemScrollOffset).isGreaterThan(0)
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyRowTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyRowTest.kt
index 0817a21..8ae3f7d 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyRowTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyRowTest.kt
@@ -46,6 +46,7 @@
 @MediumTest
 @RunWith(AndroidJUnit4::class)
 class LazyRowTest {
+    @Suppress("PrivatePropertyName")
     private val LazyListTag = "LazyListTag"
 
     @get:Rule
@@ -144,7 +145,7 @@
             }
         }
 
-        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_LEFT, 3)
+        rule.keyPress(NativeKeyEvent.KEYCODE_DPAD_LEFT, 2)
 
         rule.runOnIdle {
             assertThat(state.firstVisibleItemIndex).isEqualTo(1)
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/text/TvImeOptionsTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/text/TvImeOptionsTest.kt
index 7a29001..c77b930 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/text/TvImeOptionsTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/text/TvImeOptionsTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.tv.foundation.text
 
-import androidx.compose.ui.text.input.AndroidImeOptions
+import androidx.compose.ui.text.input.PlatformImeOptions
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import androidx.tv.foundation.ExperimentalTvFoundationApi
@@ -32,7 +32,7 @@
     fun privateImeOptions_keyboardAlignment() {
         val privateImeOptions = "testOptions"
         val keyboardAlignment = TvKeyboardAlignment.Left
-        val imeOptions = AndroidImeOptions(privateImeOptions).keyboardAlignment(keyboardAlignment)
+        val imeOptions = PlatformImeOptions(privateImeOptions).keyboardAlignment(keyboardAlignment)
 
         assertThat(
             imeOptions.privateImeOptions == "$privateImeOptions,${keyboardAlignment.option}"
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/text/TvImeOptions.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/text/TvImeOptions.kt
index 135534a..da6e10b 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/text/TvImeOptions.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/text/TvImeOptions.kt
@@ -16,7 +16,7 @@
 
 package androidx.tv.foundation.text
 
-import androidx.compose.ui.text.input.AndroidImeOptions
+import androidx.compose.ui.text.input.PlatformImeOptions
 import androidx.tv.foundation.ExperimentalTvFoundationApi
 
 /**
@@ -28,9 +28,9 @@
  *  keyboard.
  */
 @ExperimentalTvFoundationApi
-fun AndroidImeOptions(
+fun PlatformImeOptions(
     horizontalAlignment: TvKeyboardAlignment
-) = AndroidImeOptions(horizontalAlignment.option)
+) = PlatformImeOptions(horizontalAlignment.option)
 
 /**
  *  Adds the keyboard alignment option to the private IME configuration options.
@@ -41,12 +41,12 @@
  *  keyboard.
  */
 @ExperimentalTvFoundationApi
-fun AndroidImeOptions.keyboardAlignment(
+fun PlatformImeOptions.keyboardAlignment(
     horizontalAlignment: TvKeyboardAlignment
-): AndroidImeOptions {
+): PlatformImeOptions {
     val privateImeOptions =
         if (!privateImeOptions.isNullOrBlank()) this.privateImeOptions + "," else ""
-    return AndroidImeOptions(privateImeOptions + horizontalAlignment.option)
+    return PlatformImeOptions(privateImeOptions + horizontalAlignment.option)
 }
 
 /**
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt
index a39c580..e8223a2 100644
--- a/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt
@@ -21,6 +21,7 @@
 import android.view.KeyEvent
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.background
+import androidx.compose.foundation.focusable
 import androidx.compose.foundation.interaction.FocusInteraction
 import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -28,13 +29,16 @@
 import androidx.compose.foundation.interaction.collectIsPressedAsState
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.defaultMinSize
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -516,7 +520,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun clickableSurface_onFocus_changesGlowColor() {
-        rule.setContent {
+        rule.setFocusableContent {
             Surface(
                 modifier = Modifier
                     .testTag("surface")
@@ -926,8 +930,8 @@
     @Test
     fun toggleableSurface_onCheckedChange_changesGlowColor() {
         var isChecked by mutableStateOf(false)
-        var focusManager: FocusManager? = null
-        rule.setContent {
+        lateinit var focusManager: FocusManager
+        rule.setFocusableContent {
             focusManager = LocalFocusManager.current
             Surface(
                 checked = isChecked,
@@ -960,7 +964,7 @@
             .performKeyInput { pressKey(Key.DirectionCenter) }
 
         // Remove focused state to reveal selected state
-        focusManager?.clearFocus()
+        rule.runOnUiThread { focusManager.clearFocus() }
 
         rule.onNodeWithTag("surface")
             .captureToImage()
@@ -971,8 +975,8 @@
     @Test
     fun toggleableSurface_onCheckedChange_changesScaleFactor() {
         var isChecked by mutableStateOf(false)
-        var focusManager: FocusManager? = null
-        rule.setContent {
+        lateinit var focusManager: FocusManager
+        rule.setFocusableContent {
             focusManager = LocalFocusManager.current
             Box(
                 modifier = Modifier
@@ -997,7 +1001,7 @@
             .performKeyInput { pressKey(Key.DirectionCenter) }
 
         // Remove focused state to reveal selected state
-        focusManager?.clearFocus()
+        rule.runOnUiThread { focusManager.clearFocus() }
 
         rule.onRoot().captureToImage().assertDoesNotContainColor(Color.Blue)
     }
@@ -1006,8 +1010,8 @@
     @Test
     fun toggleableSurface_onCheckedChange_showsOutline() {
         var isChecked by mutableStateOf(false)
-        var focusManager: FocusManager? = null
-        rule.setContent {
+        lateinit var focusManager: FocusManager
+        rule.setFocusableContent {
             focusManager = LocalFocusManager.current
             Surface(
                 checked = isChecked,
@@ -1036,7 +1040,9 @@
             .performKeyInput { pressKey(Key.DirectionCenter) }
 
         // Remove focused state to reveal selected state
-        focusManager?.clearFocus()
+        rule.runOnUiThread { focusManager.clearFocus() }
+
+        rule.waitForIdle()
 
         surface.captureToImage().assertContainsColor(Color.Magenta)
     }
@@ -1073,7 +1079,7 @@
         val clickableItemTag = "clickable-item"
         val toggleableItemTag = "toggleable-item"
         val rootElementTag = "root"
-        var focusManager: FocusManager? = null
+        lateinit var focusManager: FocusManager
 
         rule.setContent {
             // arrange
@@ -1147,7 +1153,7 @@
         // blue border shouldn't be visible
         rootEl.captureToImage().assertDoesNotContainColor(Color.Blue)
 
-        focusManager?.moveFocus(FocusDirection.Down)
+        focusManager.moveFocus(FocusDirection.Down)
         rule.waitForIdle()
 
         // blue border should be visible
@@ -1158,7 +1164,7 @@
             .performSemanticsAction(SemanticsActions.OnClick)
         rule.waitForIdle()
 
-        focusManager?.moveFocus(FocusDirection.Up)
+        focusManager.moveFocus(FocusDirection.Up)
         rule.waitForIdle()
 
         // blue border shouldn't be visible
@@ -1207,8 +1213,7 @@
             rule
                 .onNodeWithTag(containerTag)
                 .captureToImage()
-                .toPixelMap(0, 0, 1, 1)
-                .get(0, 0) == Color.White
+                .toPixelMap(0, 0, 1, 1)[0, 0] == Color.White
         )
 
         rule.onNodeWithTag(surfaceTag).requestFocus()
@@ -1219,8 +1224,7 @@
             rule
                 .onNodeWithTag(containerTag)
                 .captureToImage()
-                .toPixelMap(0, 0, 1, 1)
-                .get(0, 0) == Color.Red
+                .toPixelMap(0, 0, 1, 1)[0, 0] == Color.Red
         )
     }
 }
@@ -1258,3 +1262,29 @@
     }
     return this
 }
+
+/**
+ * This function adds a parent composable which has size.
+ * [View.requestFocus()][android.view.View.requestFocus] will not take focus if the view has no
+ * size.
+ *
+ * @param extraItemForInitialFocus Includes an extra item that takes focus initially. This is
+ * useful in cases where we need tests that could be affected by initial focus. Eg. When there is
+ * only one focusable item and we clear focus, that item could end up being focused on again by the
+ * initial focus logic.
+ */
+private fun ComposeContentTestRule.setFocusableContent(
+    extraItemForInitialFocus: Boolean = true,
+    content: @Composable () -> Unit
+) {
+    setContent {
+        if (extraItemForInitialFocus) {
+            Row {
+                Box(modifier = Modifier.requiredSize(10.dp, 10.dp).focusable())
+                Box(modifier = Modifier.requiredSize(100.dp, 100.dp)) { content() }
+            }
+        } else {
+            Box(modifier = Modifier.requiredSize(100.dp, 100.dp)) { content() }
+        }
+    }
+}
diff --git a/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java b/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java
index 2b8df02..2ae01e1 100644
--- a/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java
+++ b/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java
@@ -918,12 +918,8 @@
 
     // We don't support RTL auto mirroring since the getLayoutDirection() is for API 17+.
     private boolean needMirroring() {
-        if (Build.VERSION.SDK_INT >= 17) {
-            return isAutoMirrored()
-                    && DrawableCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
-        } else {
-            return false;
-        }
+        return isAutoMirrored()
+                && DrawableCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
     }
 
     // Extra override functions for delegation for SDK >= 7.
diff --git a/versionedparcelable/OWNERS b/versionedparcelable/OWNERS
index f51eb81..76c3c64 100644
--- a/versionedparcelable/OWNERS
+++ b/versionedparcelable/OWNERS
@@ -1,4 +1,3 @@
 # Bug component: 460991
 [email protected]
[email protected]
 [email protected]
diff --git a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/MutableCollectionBaseActivity.kt b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/MutableCollectionBaseActivity.kt
index 2f3ca9d..46f34c1 100644
--- a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/MutableCollectionBaseActivity.kt
+++ b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/MutableCollectionBaseActivity.kt
@@ -16,7 +16,6 @@
 
 package androidx.viewpager2.integration.testapp
 
-import android.os.Build
 import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
@@ -61,9 +60,7 @@
         itemSpinner.adapter = object : BaseAdapter() {
             override fun getView(position: Int, convertView: View?, parent: ViewGroup): View =
                 ((convertView as TextView?) ?: TextView(parent.context)).apply {
-                    if (Build.VERSION.SDK_INT >= 17) {
-                        textDirection = View.TEXT_DIRECTION_LOCALE
-                    }
+                    textDirection = View.TEXT_DIRECTION_LOCALE
                     text = getItem(position)
                 }
 
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
index f3ba3a4..9e64aee 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
@@ -21,7 +21,6 @@
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import androidx.testutils.LocaleTestUtils
@@ -58,10 +57,8 @@
             localeUtil.resetLocale()
             localeUtil.setLocale(LocaleTestUtils.RTL_LANGUAGE)
         }
-        if (Build.VERSION.SDK_INT >= 18) {
-            // Make sure accessibility is enabled (side effect of creating a UI Automator instance)
-            uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-        }
+        // Make sure accessibility is enabled (side effect of creating a UI Automator instance)
+        uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
     }
 
     override fun tearDown() {
@@ -71,7 +68,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 16)
     fun test_onPerformPageAction() {
         setUpTest(config.orientation).apply {
             setAdapterSync(viewAdapterProvider.provider(stringSequence(6)))
@@ -102,13 +98,11 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     fun test_collectionInfo() {
         test_collectionInfo(6)
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     fun test_collectionInfo_zeroItems() {
         test_collectionInfo(0)
     }
@@ -139,7 +133,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 19)
     fun test_collectionItemInfo() {
         setUpTest(config.orientation).apply {
             setAdapterSync(viewAdapterProvider.provider(stringSequence(6)))
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index aaa96c9..721e6f1 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -20,7 +20,6 @@
 import android.os.Build
 import android.util.Log
 import android.view.View
-import android.view.View.OVER_SCROLL_NEVER
 import android.view.ViewConfiguration
 import android.view.accessibility.AccessibilityNodeInfo
 import androidx.core.view.ViewCompat
@@ -73,7 +72,6 @@
 import org.hamcrest.Matchers.lessThan
 import org.hamcrest.Matchers.lessThanOrEqualTo
 import org.junit.After
-import org.junit.Assert.fail
 import org.junit.Before
 import org.junit.Rule
 
@@ -125,11 +123,6 @@
         }
         onView(withId(R.id.view_pager)).check(matches(isDisplayed()))
 
-        // animations getting in the way on API < 16
-        if (Build.VERSION.SDK_INT < 16) {
-            viewPager.recyclerView.overScrollMode = OVER_SCROLL_NEVER
-        }
-
         return Context(activityTestRule)
     }
 
@@ -303,13 +296,9 @@
                 isUserInputEnabled && isVerticalOrientation &&
                 currentPage < numPages - 1
 
-            val expectScrollBackwardAction =
-                Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && isUserInputEnabled &&
-                    currentPage > 0
+            val expectScrollBackwardAction = isUserInputEnabled && currentPage > 0
 
-            val expectScrollForwardAction =
-                Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && isUserInputEnabled &&
-                    currentPage < numPages - 1
+            val expectScrollForwardAction = isUserInputEnabled && currentPage < numPages - 1
 
             assertThat(
                 "Left action expected: $expectPageLeftAction",
@@ -734,11 +723,7 @@
             if (i < n - 1) {
                 Log.w(BaseTest.TAG, "Bad state, retrying block", e)
             } else {
-                val errorMessage = "Block hit bad state $n times"
-                when {
-                    Build.VERSION.SDK_INT >= 19 -> throw AssertionError(errorMessage, e)
-                    else -> fail(errorMessage)
-                }
+                throw AssertionError("Block hit bad state $n times", e)
             }
             resetBlock()
         }
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
index 2dfbb83..6576efe 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
@@ -18,7 +18,6 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.LocaleTestUtils
 import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
 import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
@@ -77,7 +76,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = 17)
     fun test_canScrollHorizontallyVertically_horizontal_rtl() {
         // given RTL locale
         localeUtil.resetLocale()
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
index fc58747..074d046 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
@@ -26,7 +26,6 @@
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD
 import androidx.core.view.animation.PathInterpolatorCompat
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.testutils.LocaleTestUtils
 import androidx.viewpager2.widget.BaseTest.Context.SwipeMethod
 import androidx.viewpager2.widget.FakeDragTest.Event.OnPageScrollStateChangedEvent
@@ -343,7 +342,6 @@
      * onPageScrollStateChanged(0)
      */
     @Test
-    @SdkSuppress(minSdkVersion = 16)
     fun test_performA11yActionDuringFakeDrag() {
         startManualDragDuringFakeDrag(.9f, 1000, interpolator = fastDecelerateInterpolator) {
             test.runOnUiThreadSync {
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
index f9e4951..e680a22 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
@@ -22,7 +22,6 @@
 import androidx.fragment.app.FragmentManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.filters.SdkSuppress
 import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
 import java.util.concurrent.TimeUnit.MILLISECONDS
 import org.junit.Test
@@ -41,7 +40,6 @@
     private val timeoutMs = 3000L
 
     @Test
-    @SdkSuppress(minSdkVersion = 16) /** [View.setHasTransientState] was introduced in API 16 */
     fun test_swipeBetweenPages() {
         setUpTest(orientation).apply {
             val expectedValues = stringSequence(totalPages)
@@ -67,7 +65,6 @@
 
     private fun createTransientStateCallback(): FragmentManager.FragmentLifecycleCallbacks {
         return object : FragmentManager.FragmentLifecycleCallbacks() {
-            @SdkSuppress(minSdkVersion = 16)
             override fun onFragmentViewCreated(
                 fm: FragmentManager,
                 f: Fragment,
diff --git a/viewpager2/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java b/viewpager2/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
index d6df0d7..3a5f4ab0 100644
--- a/viewpager2/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
+++ b/viewpager2/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
@@ -1449,9 +1449,7 @@
         public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
             AccessibilityNodeInfoCompat infoCompat = AccessibilityNodeInfoCompat.wrap(info);
             addCollectionInfo(infoCompat);
-            if (Build.VERSION.SDK_INT >= 16) {
-                addScrollActions(infoCompat);
-            }
+            addScrollActions(infoCompat);
         }
 
         @Override
diff --git a/wear/benchmark/integration-tests/macrobenchmark-target/build.gradle b/wear/benchmark/integration-tests/macrobenchmark-target/build.gradle
index f24e3ef..54fcef0 100644
--- a/wear/benchmark/integration-tests/macrobenchmark-target/build.gradle
+++ b/wear/benchmark/integration-tests/macrobenchmark-target/build.gradle
@@ -42,5 +42,5 @@
     implementation 'androidx.core:core-ktx'
     implementation(libs.material)
     implementation(project(":profileinstaller:profileinstaller"))
-    implementation 'androidx.wear:wear:1.1.0'
+    implementation 'androidx.wear:wear:1.3.0'
 }
diff --git a/wear/compose/compose-foundation/src/androidTest/kotlin/androidx/wear/compose/foundation/HierarchicalFocusCoordinatorTest.kt b/wear/compose/compose-foundation/src/androidTest/kotlin/androidx/wear/compose/foundation/HierarchicalFocusCoordinatorTest.kt
index 53be515..3d55748 100644
--- a/wear/compose/compose-foundation/src/androidTest/kotlin/androidx/wear/compose/foundation/HierarchicalFocusCoordinatorTest.kt
+++ b/wear/compose/compose-foundation/src/androidTest/kotlin/androidx/wear/compose/foundation/HierarchicalFocusCoordinatorTest.kt
@@ -170,7 +170,7 @@
         val selected = mutableStateOf(0)
         var focused = false
         rule.setContent {
-            Box {
+            Box(Modifier.focusable()) {
                 HierarchicalFocusCoordinator({ selected.value == 0 }) {
                     FocusableTestItem { focused = it }
                 }
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt
index df92362a..65d57d4 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt
@@ -38,6 +38,7 @@
 import androidx.compose.runtime.key
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
 import androidx.compose.ui.geometry.Offset
@@ -145,6 +146,19 @@
             derivedStateOf { ((state.swipeableState.offset ?: 0f) / maxWidthPx).coerceIn(0f, 1f) }
         }
         val isSwiping by remember { derivedStateOf { progress > 0 } }
+        var squeezeMode by remember {
+            mutableStateOf(true)
+        }
+        LaunchedEffect(state.isAnimationRunning) {
+            if (state.targetValue == SwipeToDismissValue.Dismissed) {
+                squeezeMode = false
+            }
+        }
+        LaunchedEffect(state.targetValue) {
+            if (!squeezeMode && state.targetValue == SwipeToDismissValue.Default) {
+                squeezeMode = true
+            }
+        }
 
         repeat(2) {
             val isBackground = it == 0
@@ -164,9 +178,7 @@
                                                 max(0f, (1f - scale) * maxWidthPx / 2f)
 
                                             val translationX =
-                                                if (state.targetValue
-                                                    != SwipeToDismissValue.Dismissed
-                                                ) {
+                                                if (squeezeMode) {
                                                     // Squeeze
                                                     squeezeOffset
                                                 } else {
@@ -197,10 +209,16 @@
                             Canvas(Modifier.fillMaxSize()) {
                                 val color = if (isBackground) {
                                     backgroundScrimColor
-                                        .copy(alpha = MAX_BACKGROUND_SCRIM_ALPHA * (1 - progress))
+                                        .copy(
+                                            alpha = (MAX_BACKGROUND_SCRIM_ALPHA * (1 - progress))
+                                                .coerceIn(0f, 1f)
+                                        )
                                 } else {
                                     contentScrimColor
-                                        .copy(alpha = min(MAX_CONTENT_SCRIM_ALPHA, progress / 2f))
+                                        .copy(
+                                            alpha = min(MAX_CONTENT_SCRIM_ALPHA, progress / 2f)
+                                                .coerceIn(0f, 1f)
+                                        )
                                 }
                                 drawRect(color = color)
                             }
diff --git a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ButtonTest.kt b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ButtonTest.kt
index 167a921..d16609a 100644
--- a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ButtonTest.kt
+++ b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ButtonTest.kt
@@ -18,7 +18,9 @@
 
 import android.os.Build
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.IndicationNodeFactory
 import androidx.compose.foundation.background
+import androidx.compose.foundation.interaction.InteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
@@ -36,6 +38,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.compositeOver
+import androidx.compose.ui.node.DelegatableNode
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.SemanticsProperties
@@ -415,6 +418,16 @@
         shape = shape,
         border = border,
         buttonSize = 52.dp,
+        ripple = EmptyIndication,
         content = content
     )
 }
+
+internal object EmptyIndication : IndicationNodeFactory {
+    override fun create(interactionSource: InteractionSource): DelegatableNode =
+        object : Modifier.Node() {}
+
+    override fun equals(other: Any?): Boolean = other === this
+
+    override fun hashCode(): Int = -1
+}
diff --git a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
index 756d558..56436a3 100644
--- a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
+++ b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
@@ -736,6 +736,7 @@
         shape = shape,
         interactionSource = interactionSource,
         role = role,
+        ripple = EmptyIndication,
         content = content
     )
 
@@ -771,6 +772,7 @@
         border = border,
         defaultIconSpacing = defaultIconSpacing,
         role = role,
+        ripple = EmptyIndication
     )
 
     @Composable
@@ -809,6 +811,7 @@
         defaultCompactChipTapTargetPadding = defaultCompactChipTapTargetPadding,
         defaultIconSpacing = defaultIconSpacing,
         role = role,
+        ripple = EmptyIndication
     )
 
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
diff --git a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/SelectionControlsTest.kt b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/SelectionControlsTest.kt
index 8cb1df6..ece305c 100644
--- a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/SelectionControlsTest.kt
+++ b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/SelectionControlsTest.kt
@@ -867,7 +867,8 @@
         progressAnimationSpec =
         tween(200, 0, CubicBezierEasing(0.0f, 0.0f, 0.2f, 1.0f)),
         width = width,
-        height = height
+        height = height,
+        ripple = EmptyIndication
     )
 
     @Composable
@@ -928,7 +929,8 @@
         progressAnimationSpec =
         tween(150, 0, CubicBezierEasing(0.0f, 0.0f, 0.2f, 1.0f)),
         width = width,
-        height = height
+        height = height,
+        ripple = EmptyIndication
     )
 
     @Composable
@@ -975,7 +977,8 @@
         dotAlphaProgressDelay = dotAlphaProgressDelay,
         easing = progressAnimationEasing,
         width = width,
-        height = height
+        height = height,
+        ripple = EmptyIndication
     )
 
     private fun setupCheckBoxWithCustomColors(checked: Boolean, enabled: Boolean) {
diff --git a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/StepperTest.kt b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/StepperTest.kt
index 338c9c4..9dbbad5 100644
--- a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/StepperTest.kt
+++ b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/StepperTest.kt
@@ -392,6 +392,7 @@
         backgroundColor = backgroundColor,
         enabledButtonProviderValues = enabledButtonProviderValues,
         disabledButtonProviderValues = disabledButtonProviderValues,
+        buttonRipple = EmptyIndication,
         content = content,
     )
 
diff --git a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ToggleButtonTest.kt b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ToggleButtonTest.kt
index 5d092ae..512d711 100644
--- a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ToggleButtonTest.kt
+++ b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ToggleButtonTest.kt
@@ -1022,6 +1022,7 @@
         toggleButtonSize = toggleButtonSize,
         interactionSource = interactionSource,
         shape = shape,
+        ripple = EmptyIndication,
         content = content
     )
 }
@@ -1067,7 +1068,8 @@
     contentPadding = contentPadding,
     shape = shape,
     selectionControlWidth = selectionControlWidth,
-    selectionControlHeight = selectionControlHeight
+    selectionControlHeight = selectionControlHeight,
+    ripple = EmptyIndication,
 )
 
 @Composable
@@ -1114,7 +1116,8 @@
     checkedInteractionSource = checkedInteractionSource,
     clickInteractionSource = clickInteractionSource,
     contentPadding = contentPadding,
-    shape = shape
+    shape = shape,
+    ripple = EmptyIndication,
 )
 
 private val CHIP_HORIZONTAL_PADDING = 14.dp
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt
index fb8cc57c..2933651 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Button.kt
@@ -17,6 +17,7 @@
 
 import androidx.annotation.RestrictTo
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Indication
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
@@ -25,7 +26,6 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.size
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.State
 import androidx.compose.ui.Alignment
@@ -59,6 +59,7 @@
  * @param shape Defines the button's shape.
  * @param border Resolves the border for this button in different states.
  * @param buttonSize The default size of the button unless overridden by Modifier.size.
+ * @param ripple Ripple used for this button.
  * @param content The content displayed on the [Button] such as text, icon or image.
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -72,6 +73,7 @@
     shape: Shape,
     border: @Composable (enabled: Boolean) -> State<BorderStroke?>?,
     buttonSize: Dp,
+    ripple: Indication,
     content: @Composable BoxScope.() -> Unit,
 ) {
     val borderStroke = border(enabled)?.value
@@ -85,7 +87,7 @@
                 onClick = onClick,
                 enabled = enabled,
                 interactionSource = interactionSource,
-                indication = rememberRipple(),
+                indication = ripple,
             )
             .then(
                 if (borderStroke != null) Modifier.border(border = borderStroke, shape = shape)
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Card.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Card.kt
index ef51f18..c2dc1fb 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Card.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Card.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.RestrictTo
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.Image
+import androidx.compose.foundation.Indication
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.Interaction
@@ -34,7 +35,6 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -79,6 +79,7 @@
  * appearance / behavior of this card in different [Interaction]s.
  * @param role The type of user interface element. Accessibility services might use this
  * to describe the element or do customizations
+ * @param ripple Ripple used for this card
  * @param content A main slot for a content of this card
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -93,6 +94,7 @@
     shape: Shape,
     interactionSource: MutableInteractionSource,
     role: Role?,
+    ripple: Indication,
     content: @Composable ColumnScope.() -> Unit,
 ) {
     Column(
@@ -108,7 +110,7 @@
                 enabled = enabled,
                 onClick = onClick,
                 role = role,
-                indication = rememberRipple(),
+                indication = ripple,
                 interactionSource = interactionSource,
             )
             .then(
@@ -161,6 +163,7 @@
  * appearance / behavior of this card in different [Interaction]s.
  * @param shape Defines the card's shape. It is strongly recommended to use the default as this
  * shape is a key characteristic of the Wear Material Theme
+ * @param ripple Ripple used for this card
  * @param appImage A slot for a small [Image] associated with the application.
  * @param appName A slot for displaying the application name, expected to be a single line of start
  * aligned text.
@@ -181,6 +184,7 @@
     containerPainter: Painter,
     interactionSource: MutableInteractionSource,
     shape: Shape,
+    ripple: Indication,
     appImage: @Composable (RowScope.() -> Unit)?,
     appName: @Composable RowScope.() -> Unit,
     time: @Composable (RowScope.() -> Unit)?,
@@ -196,7 +200,8 @@
         contentPadding = contentPadding,
         interactionSource = interactionSource,
         role = null,
-        shape = shape
+        shape = shape,
+        ripple = ripple
     ) {
         Column {
             Row(
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt
index 53c58aed..05d429f 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt
@@ -18,6 +18,7 @@
 
 import androidx.annotation.RestrictTo
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Indication
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.Interaction
@@ -36,7 +37,6 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.State
 import androidx.compose.ui.Alignment
@@ -77,6 +77,7 @@
  * appearance / behavior of this Chip in different [Interaction]s.
  * @param role The type of user interface element. Accessibility services might use this
  * to describe the element or do customizations
+ * @param ripple Ripple used for this chip
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -90,6 +91,7 @@
     shape: Shape,
     interactionSource: MutableInteractionSource,
     role: Role?,
+    ripple: Indication,
     content: @Composable RowScope.() -> Unit,
 ) {
     val borderStroke = border(enabled)?.value
@@ -111,7 +113,7 @@
                 enabled = enabled,
                 onClick = onClick,
                 role = role,
-                indication = rememberRipple(),
+                indication = ripple,
                 interactionSource = interactionSource,
             )
             .padding(contentPadding),
@@ -164,6 +166,7 @@
  * @param defaultIconSpacing Spacing between icon and label, if both are provided.
  * @param role Role semantics that accessibility services can use to provide more
  * context to users.
+ * @param ripple Ripple used for this chip
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -181,6 +184,7 @@
     border: @Composable (enabled: Boolean) -> State<BorderStroke?>?,
     defaultIconSpacing: Dp,
     role: Role?,
+    ripple: Indication
 ) {
     Chip(
         modifier = modifier,
@@ -191,7 +195,8 @@
         contentPadding = contentPadding,
         shape = shape,
         interactionSource = interactionSource,
-        role = role
+        role = role,
+        ripple = ripple
     ) {
         Row(
             verticalAlignment = Alignment.CenterVertically,
@@ -271,6 +276,7 @@
  * @param defaultIconSpacing Spacing between icon and label, if both are provided
  * @param role Role semantics that accessibility services can use to provide more
  * context to users.
+ * @param ripple Ripple used for this chip
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -289,6 +295,7 @@
     defaultCompactChipTapTargetPadding: PaddingValues,
     defaultIconSpacing: Dp,
     role: Role?,
+    ripple: Indication
 ) {
     if (label != null) {
         Chip(
@@ -305,7 +312,8 @@
             shape = shape,
             border = border,
             defaultIconSpacing = defaultIconSpacing,
-            role = role
+            role = role,
+            ripple = ripple
         )
     } else {
         // Icon only compact chips have their own layout with a specific width and center aligned
@@ -322,6 +330,7 @@
             shape = shape,
             interactionSource = interactionSource,
             role = role,
+            ripple = ripple
         ) {
             // Use a box to fill and center align the icon into the single slot of the Chip
             Box(modifier = Modifier
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/SelectionControls.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/SelectionControls.kt
index bcd8688..82c880b 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/SelectionControls.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/SelectionControls.kt
@@ -33,7 +33,6 @@
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.State
 import androidx.compose.ui.Alignment
@@ -77,6 +76,7 @@
  * @param drawBox Draws the checkbox.
  * @param width Width of the checkbox.
  * @param height Height of the checkbox.
+ * @param ripple Ripple used for the checkbox.
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -91,7 +91,8 @@
     progressAnimationSpec: TweenSpec<Float>,
     drawBox: FunctionDrawBox,
     width: Dp,
-    height: Dp
+    height: Dp,
+    ripple: Indication
 ) {
     val targetState = if (checked) SelectionStage.Checked else SelectionStage.Unchecked
     val transition = updateTransition(targetState, label = "checkboxTransition")
@@ -118,7 +119,7 @@
                 enabled,
                 checked,
                 interactionSource,
-                rememberRipple(),
+                ripple,
                 width,
                 height
             )
@@ -168,6 +169,7 @@
  * @param progressAnimationSpec Animation spec to animate the progress.
  * @param width Width of the switch.
  * @param height Height of the switch.
+ * @param ripple Ripple used for the switch.
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -187,6 +189,7 @@
     progressAnimationSpec: TweenSpec<Float>,
     width: Dp,
     height: Dp,
+    ripple: Indication
 ) {
     val targetState = if (checked) SelectionStage.Checked else SelectionStage.Unchecked
     val transition = updateTransition(targetState, label = "switchTransition")
@@ -215,7 +218,7 @@
                 enabled,
                 checked,
                 interactionSource,
-                rememberRipple(),
+                ripple,
                 width,
                 height
             )
@@ -262,6 +265,7 @@
  * @param easing Animation spec to animate the progress.
  * @param width Width of the radio button.
  * @param height Height of the radio button.
+ * @param ripple Ripple used for the radio button.
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -278,7 +282,8 @@
     dotAlphaProgressDelay: Int,
     easing: CubicBezierEasing,
     width: Dp,
-    height: Dp
+    height: Dp,
+    ripple: Indication
 ) {
     val targetState = if (selected) SelectionStage.Checked else SelectionStage.Unchecked
     val transition = updateTransition(targetState)
@@ -315,7 +320,7 @@
                 this.role = Role.RadioButton
             }
             .maybeSelectable(
-                onClick, enabled, selected, interactionSource, rememberRipple(), width, height
+                onClick, enabled, selected, interactionSource, ripple, width, height
             )
             .drawWithCache
             {
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt
index 70428a4..0e9ca3f 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt
@@ -17,6 +17,7 @@
 package androidx.wear.compose.materialcore
 
 import androidx.annotation.RestrictTo
+import androidx.compose.foundation.Indication
 import androidx.compose.foundation.background
 import androidx.compose.foundation.indication
 import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -30,7 +31,6 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.wrapContentWidth
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.ProvidedValue
@@ -71,6 +71,7 @@
  * @param disabledButtonProviderValues Values of CompositionLocal providers for disabled button such
  * as LocalContentColor, LocalContentAlpha, LocalTextStyle which are dependent on a specific
  * material design version and are not part of this material-agnostic library.
+ * @param buttonRipple Unbounded ripple used for the decrease and increase button
  * @param content Content body for the Stepper.
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -86,6 +87,7 @@
     backgroundColor: Color,
     enabledButtonProviderValues: Array<ProvidedValue<*>>,
     disabledButtonProviderValues: Array<ProvidedValue<*>>,
+    buttonRipple: Indication,
     content: @Composable BoxScope.() -> Unit
 ) {
     require(steps >= 0) { "steps should be >= 0" }
@@ -118,6 +120,7 @@
             enabled = increaseButtonEnabled,
             buttonProviderValues = if (increaseButtonEnabled) enabledButtonProviderValues
             else disabledButtonProviderValues,
+            ripple = buttonRipple,
             content = increaseIcon
         )
         Box(
@@ -135,6 +138,7 @@
             enabled = decreaseButtonEnabled,
             buttonProviderValues = if (decreaseButtonEnabled) enabledButtonProviderValues
             else disabledButtonProviderValues,
+            ripple = buttonRipple,
             content = decreaseIcon
         )
     }
@@ -147,6 +151,7 @@
     paddingValues: PaddingValues,
     enabled: Boolean,
     buttonProviderValues: Array<ProvidedValue<*>>,
+    ripple: Indication,
     content: @Composable () -> Unit
 ) {
     val interactionSource = remember { MutableInteractionSource() }
@@ -161,7 +166,7 @@
                 indication = null
             )
             .wrapContentWidth()
-            .indication(interactionSource, rememberRipple(bounded = false))
+            .indication(interactionSource, ripple)
             .padding(paddingValues),
         contentAlignment = contentAlignment,
     ) {
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/ToggleButton.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/ToggleButton.kt
index ce2be36..85e2513 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/ToggleButton.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/ToggleButton.kt
@@ -18,6 +18,7 @@
 
 import androidx.annotation.RestrictTo
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Indication
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
@@ -41,7 +42,6 @@
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.layout.wrapContentWidth
 import androidx.compose.foundation.selection.toggleable
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.State
 import androidx.compose.ui.Alignment
@@ -83,6 +83,7 @@
  * appearance / behavior of this ToggleButton in different [Interaction]s.
  * @param shape Defines the shape for this toggle button. It is strongly recommended to use the
  * default as this shape is a key characteristic of the Wear Material Theme.
+ * @param ripple Ripple used for this toggle button
  * @param content The icon, image or text to be drawn inside the toggle button.
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -97,6 +98,7 @@
     toggleButtonSize: Dp,
     interactionSource: MutableInteractionSource,
     shape: Shape,
+    ripple: Indication,
     content: @Composable BoxScope.() -> Unit,
 ) {
     // Round toggle button
@@ -112,7 +114,7 @@
                 onValueChange = onCheckedChange,
                 enabled = enabled,
                 interactionSource = interactionSource,
-                indication = rememberRipple()
+                indication = ripple
             )
             .then(
                 if (borderStroke != null) Modifier.border(border = borderStroke, shape = shape)
@@ -163,6 +165,7 @@
  * default as this shape is a key characteristic of the Wear Material Theme
  * @param selectionControlWidth Width for the selection control.
  * @param selectionControlHeight Height for the selection control.
+ * @param ripple Ripple used for this toggle button
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -180,7 +183,8 @@
     contentPadding: PaddingValues,
     shape: Shape,
     selectionControlWidth: Dp,
-    selectionControlHeight: Dp
+    selectionControlHeight: Dp,
+    ripple: Indication
 ) {
     // Stadium/Chip shaped toggle button
     Row(
@@ -192,7 +196,7 @@
                 enabled = enabled,
                 value = checked,
                 onValueChange = onCheckedChange,
-                indication = rememberRipple(),
+                indication = ripple,
                 interactionSource = interactionSource
             )
             .padding(contentPadding),
@@ -263,6 +267,7 @@
  * content
  * @param shape Defines the SplitToggleButton's shape. It is strongly recommended to use the
  * default as this shape is a key characteristic of the Wear Material Theme
+ * @param ripple Ripple used for this toggle button
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Composable
@@ -280,7 +285,8 @@
     checkedInteractionSource: MutableInteractionSource,
     clickInteractionSource: MutableInteractionSource,
     contentPadding: PaddingValues,
-    shape: Shape
+    shape: Shape,
+    ripple: Indication
 ) {
     val (startPadding, endPadding) = contentPadding.splitHorizontally()
 
@@ -296,7 +302,7 @@
                 .clickable(
                     enabled = enabled,
                     onClick = onClick,
-                    indication = rememberRipple(),
+                    indication = ripple,
                     interactionSource = clickInteractionSource,
                 )
                 .semantics {
@@ -328,7 +334,7 @@
                     enabled = enabled,
                     value = checked,
                     onValueChange = onCheckedChange,
-                    indication = rememberRipple(),
+                    indication = ripple,
                     interactionSource = checkedInteractionSource
                 )
                 .fillMaxHeight()
diff --git a/wear/compose/compose-material/api/current.txt b/wear/compose/compose-material/api/current.txt
index 03bbbc7..5bb549f 100644
--- a/wear/compose/compose-material/api/current.txt
+++ b/wear/compose/compose-material/api/current.txt
@@ -478,6 +478,13 @@
     property public final float factorAtMin;
   }
 
+  public final class RippleKt {
+    method @SuppressCompatibility @androidx.wear.compose.material.ExperimentalWearMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalUseFallbackRippleImplementation();
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(androidx.compose.ui.graphics.ColorProducer color, optional boolean bounded, optional float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(optional boolean bounded, optional float radius, optional long color);
+    property @SuppressCompatibility @androidx.wear.compose.material.ExperimentalWearMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalUseFallbackRippleImplementation;
+  }
+
   public final class ScaffoldKt {
     method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? vignette, optional kotlin.jvm.functions.Function0<kotlin.Unit>? positionIndicator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? pageIndicator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? timeText, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
diff --git a/wear/compose/compose-material/api/restricted_current.txt b/wear/compose/compose-material/api/restricted_current.txt
index 03bbbc7..5bb549f 100644
--- a/wear/compose/compose-material/api/restricted_current.txt
+++ b/wear/compose/compose-material/api/restricted_current.txt
@@ -478,6 +478,13 @@
     property public final float factorAtMin;
   }
 
+  public final class RippleKt {
+    method @SuppressCompatibility @androidx.wear.compose.material.ExperimentalWearMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalUseFallbackRippleImplementation();
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(androidx.compose.ui.graphics.ColorProducer color, optional boolean bounded, optional float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(optional boolean bounded, optional float radius, optional long color);
+    property @SuppressCompatibility @androidx.wear.compose.material.ExperimentalWearMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalUseFallbackRippleImplementation;
+  }
+
   public final class ScaffoldKt {
     method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? vignette, optional kotlin.jvm.functions.Function0<kotlin.Unit>? positionIndicator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? pageIndicator, optional kotlin.jvm.functions.Function0<kotlin.Unit>? timeText, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Button.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Button.kt
index b298e04..49355d6 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Button.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Button.kt
@@ -163,6 +163,7 @@
         shape = shape,
         border = { border.borderStroke(enabled = it) },
         buttonSize = ButtonDefaults.DefaultButtonSize,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled),
             MaterialTheme.typography.button,
@@ -345,6 +346,7 @@
         shape = shape,
         border = { border.borderStroke(it) },
         buttonSize = ButtonDefaults.ExtraSmallButtonSize,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled),
             MaterialTheme.typography.button,
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Card.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Card.kt
index 81a53a4..f480fec 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Card.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Card.kt
@@ -115,6 +115,7 @@
         shape = shape,
         interactionSource = interactionSource,
         role = role,
+        ripple = rippleOrFallbackImplementation(),
     ) {
         CompositionLocalProvider(
             LocalContentColor provides contentColor,
@@ -202,6 +203,7 @@
         containerPainter = backgroundPainter,
         interactionSource = remember { MutableInteractionSource() },
         shape = MaterialTheme.shapes.large,
+        ripple = rippleOrFallbackImplementation(),
         appImage = appImage?.let { { appImage() } },
         appName = {
             CompositionLocalProvider(
@@ -308,7 +310,8 @@
         contentPadding = CardDefaults.ContentPadding,
         interactionSource = remember { MutableInteractionSource() },
         role = null,
-        shape = MaterialTheme.shapes.large
+        shape = MaterialTheme.shapes.large,
+        ripple = rippleOrFallbackImplementation(),
     ) {
         Column {
             Row(
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt
index e5161f7b..a9bf879 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt
@@ -35,7 +35,6 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
@@ -204,7 +203,7 @@
                 enabled = enabled,
                 onClick = onClick,
                 role = role,
-                indication = rememberRipple(),
+                indication = rippleOrFallbackImplementation(),
                 interactionSource = interactionSource,
             )
             .padding(contentPadding),
@@ -707,6 +706,7 @@
         defaultCompactChipTapTargetPadding = ChipDefaults.CompactChipTapTargetPadding,
         defaultIconSpacing = ChipDefaults.IconSpacing,
         role = Role.Button,
+        ripple = rippleOrFallbackImplementation()
     )
 }
 
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/MaterialTheme.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/MaterialTheme.kt
index 86d8124..5017f99 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/MaterialTheme.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/MaterialTheme.kt
@@ -17,12 +17,8 @@
 
 import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.text.selection.LocalTextSelectionColors
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.runtime.remember
 import androidx.wear.compose.foundation.LocalSwipeToDismissBackgroundScrimColor
@@ -71,15 +67,17 @@
         // provided, and overwrite the values set in it.
         colors.copy()
     }.apply { updateColorsFrom(colors) }
-    val rippleIndication = rememberRipple()
+    val rippleIndication = rippleOrFallbackImplementation()
     val selectionColors = rememberTextSelectionColors(rememberedColors)
+    @Suppress("DEPRECATION_ERROR")
     CompositionLocalProvider(
         LocalColors provides rememberedColors,
         LocalShapes provides shapes,
         LocalTypography provides typography,
         LocalContentAlpha provides ContentAlpha.high,
         LocalIndication provides rippleIndication,
-        LocalRippleTheme provides MaterialRippleTheme,
+        // TODO: b/304985887 - remove after one stable release
+        androidx.compose.material.ripple.LocalRippleTheme provides CompatRippleTheme,
         LocalTextSelectionColors provides selectionColors,
         LocalSwipeToDismissBackgroundScrimColor provides rememberedColors.background,
         LocalSwipeToDismissContentScrimColor provides rememberedColors.background
@@ -104,18 +102,3 @@
         @Composable
         get() = LocalShapes.current
 }
-
-@Immutable
-private object MaterialRippleTheme : RippleTheme {
-    @Composable
-    override fun defaultColor() = RippleTheme.defaultRippleColor(
-        contentColor = LocalContentColor.current,
-        lightTheme = false
-    )
-
-    @Composable
-    override fun rippleAlpha() = RippleTheme.defaultRippleAlpha(
-        contentColor = LocalContentColor.current,
-        lightTheme = false
-    )
-}
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Ripple.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Ripple.kt
new file mode 100644
index 0000000..06fd1c6
--- /dev/null
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Ripple.kt
@@ -0,0 +1,290 @@
+/*
+ * 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.wear.compose.material
+
+import androidx.compose.foundation.Indication
+import androidx.compose.foundation.IndicationNodeFactory
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.material.ripple.RippleAlpha
+import androidx.compose.material.ripple.createRippleModifierNode
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.staticCompositionLocalOf
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.graphics.isSpecified
+import androidx.compose.ui.graphics.luminance
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DelegatingNode
+import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.unit.Dp
+
+/**
+ * Creates a Ripple using the provided values and values inferred from the theme.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new animation, and
+ * responds to other [Interaction]s by showing a fixed state layer with varying alpha values
+ * depending on the [Interaction].
+ *
+ * [MaterialTheme] provides Ripples using [androidx.compose.foundation.LocalIndication], so a Ripple
+ * will be used as the default [Indication] inside components such as
+ * [androidx.compose.foundation.clickable] and [androidx.compose.foundation.indication], in
+ * addition to Material provided components that use a Ripple as well.
+ *
+ * You can also explicitly create a Ripple and provide it to custom components in order to change
+ * the parameters from the default, such as to create an unbounded ripple with a fixed size.
+ *
+ * To create a Ripple with a manually defined color that can change over time, see the other
+ * [ripple] overload with a [ColorProducer] parameter. This will avoid unnecessary recompositions
+ * when changing the color, and preserve existing ripple state when the color changes.
+ *
+ * @param bounded If true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have alpha applied to calculate the final
+ * color used to draw the ripple. If [Color.Unspecified] is provided the color used will be
+ * the default ripple color instead.
+ */
+@Stable
+fun ripple(
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified,
+    color: Color = Color.Unspecified
+): IndicationNodeFactory {
+    return if (radius == Dp.Unspecified && color == Color.Unspecified) {
+        if (bounded) return DefaultBoundedRipple else DefaultUnboundedRipple
+    } else {
+        RippleNodeFactory(bounded, radius, color)
+    }
+}
+
+/**
+ * Creates a Ripple using the provided values and values inferred from the theme.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new ripple animation, and
+ * responds to other [Interaction]s by showing a fixed state layer with varying alpha values
+ * depending on the [Interaction].
+ *
+ * [MaterialTheme] provides Ripples using [androidx.compose.foundation.LocalIndication], so a Ripple
+ * will be used as the default [Indication] inside components such as
+ * [androidx.compose.foundation.clickable] and [androidx.compose.foundation.indication], in
+ * addition to Material provided components that use a Ripple as well.
+ *
+ * You can also explicitly create a Ripple and provide it to custom components in order to change
+ * the parameters from the default, such as to create an unbounded ripple with a fixed size.
+ *
+ * To create a Ripple with a static color, see the [ripple] overload with a [Color] parameter. This
+ * overload is optimized for Ripples that have dynamic colors that change over time, to reduce
+ * unnecessary recompositions.
+ *
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have alpha applied to calculate the final
+ *  * color used to draw the ripple. If you are creating this [ColorProducer] outside of composition
+ *  (where it will be automatically remembered), make sure that its instance is stable
+ *  (such as by remembering the object that holds it), or remember the returned [ripple] object to
+ *  make sure that ripple nodes are not being created each recomposition.
+ * @param bounded If true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ */
+@Stable
+fun ripple(
+    color: ColorProducer,
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified
+): IndicationNodeFactory {
+    return RippleNodeFactory(bounded, radius, color)
+}
+
+/**
+ * Default values used by [ripple].
+ */
+private object RippleDefaults {
+    /**
+     * Represents the default color that will be used for a ripple if a color has not been
+     * explicitly set on the ripple instance.
+     *
+     * @param contentColor the color of content (text or iconography) in the component that
+     * contains the ripple.
+     */
+    fun rippleColor(
+        contentColor: Color,
+    ): Color {
+        val contentLuminance = contentColor.luminance()
+        // If we are on a colored surface (typically indicated by low luminance content), the
+        // ripple color should be white.
+        return if (contentLuminance < 0.5) {
+            Color.White
+            // Otherwise use contentColor
+        } else {
+            contentColor
+        }
+    }
+}
+
+/**
+ * Temporary CompositionLocal to allow configuring whether the old ripple implementation that uses
+ * the deprecated [androidx.compose.material.ripple.RippleTheme] API should be used in Material
+ * components and LocalIndication, instead of the new [ripple] API. This flag defaults to false,
+ * and will be removed after one stable release: it should only be used to temporarily unblock
+ * upgrading.
+ *
+ * Provide this CompositionLocal before you provide [MaterialTheme] to make sure it is correctly
+ * provided through LocalIndication.
+ */
+// TODO: b/304985887 - remove after one stable release
+@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+@get:ExperimentalWearMaterialApi
+@ExperimentalWearMaterialApi
+val LocalUseFallbackRippleImplementation: ProvidableCompositionLocal<Boolean> =
+    staticCompositionLocalOf { false }
+
+// TODO: b/304985887 - remove after one stable release
+@Suppress("DEPRECATION_ERROR")
+@OptIn(ExperimentalWearMaterialApi::class)
+@Composable
+internal fun rippleOrFallbackImplementation(
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified,
+    color: Color = Color.Unspecified
+): Indication {
+    return if (LocalUseFallbackRippleImplementation.current) {
+        androidx.compose.material.ripple.rememberRipple(bounded, radius, color)
+    } else {
+        ripple(bounded, radius, color)
+    }
+}
+
+// TODO: b/304985887 - remove after one stable release
+@Suppress("DEPRECATION_ERROR")
+@Immutable
+internal object CompatRippleTheme : androidx.compose.material.ripple.RippleTheme {
+
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun defaultColor() = RippleDefaults.rippleColor(LocalContentColor.current)
+
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun rippleAlpha() = RippleAlpha
+}
+
+@Stable
+private class RippleNodeFactory private constructor(
+    private val bounded: Boolean,
+    private val radius: Dp,
+    private val colorProducer: ColorProducer?,
+    private val color: Color
+) : IndicationNodeFactory {
+    constructor(
+        bounded: Boolean,
+        radius: Dp,
+        colorProducer: ColorProducer
+    ) : this(bounded, radius, colorProducer, Color.Unspecified)
+
+    constructor(
+        bounded: Boolean,
+        radius: Dp,
+        color: Color
+    ) : this(bounded, radius, null, color)
+
+    override fun create(interactionSource: InteractionSource): DelegatableNode {
+        val colorProducer = colorProducer ?: ColorProducer { color }
+        return DelegatingThemeAwareRippleNode(interactionSource, bounded, radius, colorProducer)
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is RippleNodeFactory) return false
+
+        if (bounded != other.bounded) return false
+        if (radius != other.radius) return false
+        if (colorProducer != other.colorProducer) return false
+        return color == other.color
+    }
+
+    override fun hashCode(): Int {
+        var result = bounded.hashCode()
+        result = 31 * result + radius.hashCode()
+        result = 31 * result + colorProducer.hashCode()
+        result = 31 * result + color.hashCode()
+        return result
+    }
+}
+
+private class DelegatingThemeAwareRippleNode(
+    private val interactionSource: InteractionSource,
+    private val bounded: Boolean,
+    private val radius: Dp,
+    private val color: ColorProducer,
+) : DelegatingNode(), CompositionLocalConsumerModifierNode {
+    override fun onAttach() {
+        val calculateColor = ColorProducer {
+            val userDefinedColor = color()
+            if (userDefinedColor.isSpecified) {
+                userDefinedColor
+            } else {
+                RippleDefaults.rippleColor(contentColor = currentValueOf(LocalContentColor))
+            }
+        }
+
+        delegate(createRippleModifierNode(
+            interactionSource,
+            bounded,
+            radius,
+            calculateColor,
+            CalculateRippleAlpha
+        ))
+    }
+}
+
+private val DefaultBoundedRipple = RippleNodeFactory(
+    bounded = true,
+    radius = Dp.Unspecified,
+    color = Color.Unspecified
+)
+
+private val DefaultUnboundedRipple = RippleNodeFactory(
+    bounded = false,
+    radius = Dp.Unspecified,
+    color = Color.Unspecified
+)
+
+private val CalculateRippleAlpha = { RippleAlpha }
+
+private val RippleAlpha = RippleAlpha(
+    pressedAlpha = 0.10f,
+    focusedAlpha = 0.12f,
+    draggedAlpha = 0.08f,
+    hoveredAlpha = 0.04f
+)
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt
index 0b28d50..33da0fc 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt
@@ -101,6 +101,7 @@
             LocalContentColor provides iconColor.copy(alpha = ContentAlpha.disabled),
             LocalContentAlpha provides iconColor.copy(alpha = ContentAlpha.disabled).alpha
         ),
+        buttonRipple = rippleOrFallbackImplementation(bounded = false)
     ) {
         CompositionLocalProvider(
             LocalContentColor provides contentColor
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/SwipeToReveal.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/SwipeToReveal.kt
index 5a3c2a3..4c130f0 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/SwipeToReveal.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/SwipeToReveal.kt
@@ -37,7 +37,6 @@
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.Delete
 import androidx.compose.material.icons.outlined.MoreVert
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.remember
@@ -277,7 +276,7 @@
         modifier = modifier
             .clickable(
                 interactionSource = interactionSource,
-                indication = rememberRipple(),
+                indication = rippleOrFallbackImplementation(),
                 role = Role.Button,
                 onClick = {
                     revealState.lastActionType = RevealActionType.UndoAction
@@ -546,7 +545,7 @@
             .fillMaxSize()
             .clickable(
                 interactionSource = interactionSource,
-                indication = rememberRipple(),
+                indication = rippleOrFallbackImplementation(),
                 role = Role.Button,
                 onClick = {
                     revealState.lastActionType = actionType
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt
index 4a208e3..814f9e3 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleButton.kt
@@ -225,6 +225,7 @@
         toggleButtonSize = ToggleButtonDefaults.DefaultToggleButtonSize,
         interactionSource = interactionSource,
         shape = shape,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled, checked = checked),
             MaterialTheme.typography.button,
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleChip.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleChip.kt
index 006e320..8b0775a 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleChip.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleChip.kt
@@ -156,7 +156,8 @@
     contentPadding = contentPadding,
     shape = shape,
     selectionControlHeight = TOGGLE_CONTROL_HEIGHT,
-    selectionControlWidth = TOGGLE_CONTROL_WIDTH
+    selectionControlWidth = TOGGLE_CONTROL_WIDTH,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
@@ -275,7 +276,8 @@
     checkedInteractionSource = checkedInteractionSource,
     clickInteractionSource = clickInteractionSource,
     contentPadding = contentPadding,
-    shape = shape
+    shape = shape,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleControl.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleControl.kt
index cabf021..0194f26 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleControl.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ToggleControl.kt
@@ -87,7 +87,8 @@
     drawBox = { drawScope, color, _, _ -> drawScope.drawBox(color) },
     progressAnimationSpec = PROGRESS_ANIMATION_SPEC,
     width = WIDTH,
-    height = HEIGHT
+    height = HEIGHT,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
@@ -155,7 +156,8 @@
     },
     progressAnimationSpec = PROGRESS_ANIMATION_SPEC,
     width = WIDTH,
-    height = HEIGHT
+    height = HEIGHT,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
@@ -209,7 +211,8 @@
     dotAlphaProgressDelay = FLASH,
     easing = STANDARD_IN,
     width = WIDTH,
-    height = HEIGHT
+    height = HEIGHT,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
diff --git a/wear/compose/compose-material3/api/current.txt b/wear/compose/compose-material3/api/current.txt
index 3d1f4dc..5bb31ba7 100644
--- a/wear/compose/compose-material3/api/current.txt
+++ b/wear/compose/compose-material3/api/current.txt
@@ -33,7 +33,7 @@
     method public float getHeight();
     method public float getIconSize();
     method public float getLargeIconSize();
-    method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.ButtonColors imageBackgroundButtonColors(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush, optional long contentColor, optional long secondaryContentColor, optional long iconColor);
+    method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.ButtonColors imageBackgroundButtonColors(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush, optional long contentColor, optional long secondaryContentColor, optional long iconColor, optional long disabledContentColor, optional long disabledSecondaryContentColor, optional long disabledIconColor);
     method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedButtonBorder(boolean enabled, optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
     method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.ButtonColors outlinedButtonColors(optional long contentColor, optional long secondaryContentColor, optional long iconColor, optional long disabledContentColor, optional long disabledSecondaryContentColor, optional long disabledIconColor);
     property public final float ButtonHorizontalPadding;
@@ -360,6 +360,13 @@
     method public static androidx.compose.ui.Modifier rangeSemantics(androidx.compose.ui.Modifier, float value, boolean enabled, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, int steps);
   }
 
+  public final class RippleKt {
+    method @SuppressCompatibility @androidx.wear.compose.material3.ExperimentalWearMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalUseFallbackRippleImplementation();
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(androidx.compose.ui.graphics.ColorProducer color, optional boolean bounded, optional float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(optional boolean bounded, optional float radius, optional long color);
+    property @SuppressCompatibility @androidx.wear.compose.material3.ExperimentalWearMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalUseFallbackRippleImplementation;
+  }
+
   public final class SelectionControlsKt {
     method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material3.CheckboxColors colors, optional boolean enabled);
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material3.RadioButtonColors colors, optional boolean enabled);
diff --git a/wear/compose/compose-material3/api/restricted_current.txt b/wear/compose/compose-material3/api/restricted_current.txt
index 3d1f4dc..5bb31ba7 100644
--- a/wear/compose/compose-material3/api/restricted_current.txt
+++ b/wear/compose/compose-material3/api/restricted_current.txt
@@ -33,7 +33,7 @@
     method public float getHeight();
     method public float getIconSize();
     method public float getLargeIconSize();
-    method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.ButtonColors imageBackgroundButtonColors(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush, optional long contentColor, optional long secondaryContentColor, optional long iconColor);
+    method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.ButtonColors imageBackgroundButtonColors(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush, optional long contentColor, optional long secondaryContentColor, optional long iconColor, optional long disabledContentColor, optional long disabledSecondaryContentColor, optional long disabledIconColor);
     method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedButtonBorder(boolean enabled, optional long borderColor, optional long disabledBorderColor, optional float borderWidth);
     method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.ButtonColors outlinedButtonColors(optional long contentColor, optional long secondaryContentColor, optional long iconColor, optional long disabledContentColor, optional long disabledSecondaryContentColor, optional long disabledIconColor);
     property public final float ButtonHorizontalPadding;
@@ -360,6 +360,13 @@
     method public static androidx.compose.ui.Modifier rangeSemantics(androidx.compose.ui.Modifier, float value, boolean enabled, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, int steps);
   }
 
+  public final class RippleKt {
+    method @SuppressCompatibility @androidx.wear.compose.material3.ExperimentalWearMaterial3Api public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalUseFallbackRippleImplementation();
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(androidx.compose.ui.graphics.ColorProducer color, optional boolean bounded, optional float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.IndicationNodeFactory ripple(optional boolean bounded, optional float radius, optional long color);
+    property @SuppressCompatibility @androidx.wear.compose.material3.ExperimentalWearMaterial3Api public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalUseFallbackRippleImplementation;
+  }
+
   public final class SelectionControlsKt {
     method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material3.CheckboxColors colors, optional boolean enabled);
     method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.material3.RadioButtonColors colors, optional boolean enabled);
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
index 1a91267..f9b299c 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
@@ -36,7 +36,6 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.State
@@ -59,6 +58,7 @@
 import androidx.wear.compose.material3.tokens.ChildButtonTokens
 import androidx.wear.compose.material3.tokens.FilledButtonTokens
 import androidx.wear.compose.material3.tokens.FilledTonalButtonTokens
+import androidx.wear.compose.material3.tokens.ImageButtonTokens
 import androidx.wear.compose.material3.tokens.OutlinedButtonTokens
 
 /**
@@ -908,19 +908,37 @@
      * @param secondaryContentColor The secondary content color of this [Button] when enabled, used
      * for secondaryLabel content
      * @param iconColor The icon color of this [Button] when enabled, used for icon content
+     * @param disabledContentColor The content color of this [Button] when disabled
+     * @param disabledSecondaryContentColor The secondary content color of this [Button] when
+     * disabled, used for secondary label content
+     * @param disabledIconColor The icon color of this [Button] when disabled, used for icon content
      */
     @Composable
     fun imageBackgroundButtonColors(
         backgroundImagePainter: Painter,
         backgroundImageScrimBrush: Brush = Brush.linearGradient(
             colors = listOf(
-                MaterialTheme.colorScheme.surface.copy(alpha = 1.0f),
-                MaterialTheme.colorScheme.surface.copy(alpha = 0f)
+                ImageButtonTokens.BackgroundImageGradientColor.value.copy(
+                    alpha = ImageButtonTokens.GradientStartOpacity
+                ),
+                ImageButtonTokens.BackgroundImageGradientColor.value.copy(
+                    alpha = ImageButtonTokens.GradientEndOpacity
+                )
             )
         ),
-        contentColor: Color = MaterialTheme.colorScheme.onSurface,
-        secondaryContentColor: Color = contentColor,
-        iconColor: Color = contentColor,
+        contentColor: Color = ImageButtonTokens.ContentColor.value,
+        secondaryContentColor: Color = ImageButtonTokens.SecondaryContentColor.value,
+        iconColor: Color = ImageButtonTokens.IconColor.value,
+        disabledContentColor: Color = ImageButtonTokens.DisabledContentColor.value.toDisabledColor(
+            disabledAlpha = ImageButtonTokens.DisabledContentOpacity
+        ),
+        disabledSecondaryContentColor: Color = ImageButtonTokens.DisabledContentColor.value
+            .toDisabledColor(
+                disabledAlpha = ImageButtonTokens.DisabledContentOpacity
+            ),
+        disabledIconColor: Color = ImageButtonTokens.DisabledContentColor.value.toDisabledColor(
+            disabledAlpha = ImageButtonTokens.DisabledContentOpacity
+        )
     ): ButtonColors {
         val backgroundPainter =
             remember(backgroundImagePainter, backgroundImageScrimBrush) {
@@ -930,7 +948,7 @@
                 )
             }
 
-        val disabledContentAlpha = ContentAlpha.disabled
+        val disabledContentAlpha = ImageButtonTokens.DisabledContentOpacity
         val disabledBackgroundPainter =
             remember(backgroundImagePainter, backgroundImageScrimBrush, disabledContentAlpha) {
                 androidx.wear.compose.materialcore.ImageWithScrimPainter(
@@ -945,11 +963,9 @@
             secondaryContentColor = secondaryContentColor,
             iconColor = iconColor,
             disabledContainerPainter = disabledBackgroundPainter,
-            disabledContentColor = contentColor.copy(alpha = ContentAlpha.disabled),
-            disabledSecondaryContentColor = secondaryContentColor.copy(
-                alpha = ContentAlpha.disabled
-            ),
-            disabledIconColor = iconColor.copy(alpha = ContentAlpha.disabled),
+            disabledContentColor = disabledContentColor,
+            disabledSecondaryContentColor = disabledSecondaryContentColor,
+            disabledIconColor = disabledIconColor,
         )
     }
 
@@ -971,7 +987,7 @@
             OutlinedButtonTokens.DisabledContainerBorderColor.value.toDisabledColor(
                 disabledAlpha = OutlinedButtonTokens.DisabledContainerBorderOpacity
             ),
-        borderWidth: Dp = 1.dp
+        borderWidth: Dp = OutlinedButtonTokens.ContainerBorderWidth
     ): BorderStroke {
         return remember {
             BorderStroke(borderWidth, if (enabled) borderColor else disabledBorderColor)
@@ -1223,7 +1239,7 @@
                 enabled = enabled,
                 onClick = onClick,
                 role = Role.Button,
-                indication = rememberRipple(),
+                indication = rippleOrFallbackImplementation(),
                 interactionSource = interactionSource,
             )
             .padding(contentPadding),
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt
index 1c42711..bea5798 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt
@@ -198,6 +198,7 @@
         contentPadding = contentPadding,
         appImage = appImage?.let { { appImage() } },
         interactionSource = interactionSource,
+        ripple = rippleOrFallbackImplementation(),
         appName = {
             CompositionLocalProvider(
                 LocalContentColor provides colors.appNameColor,
@@ -330,7 +331,8 @@
         contentPadding = contentPadding,
         interactionSource = interactionSource,
         role = null,
-        shape = shape
+        shape = shape,
+        ripple = rippleOrFallbackImplementation(),
     ) {
         Column {
             if (content == null) {
@@ -649,6 +651,7 @@
         interactionSource = interactionSource,
         role = null,
         shape = shape,
+        ripple = rippleOrFallbackImplementation()
     ) {
         CompositionLocalProvider(
             LocalContentColor provides colors.contentColor,
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt
index 8755ede..5698de2 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/IconButton.kt
@@ -93,6 +93,7 @@
         shape = shape,
         border = { rememberUpdatedState(border) },
         buttonSize = IconButtonDefaults.DefaultButtonSize,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled),
             content
@@ -316,6 +317,7 @@
         toggleButtonSize = IconButtonDefaults.DefaultButtonSize,
         interactionSource = interactionSource,
         shape = shape,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled, checked = checked),
             content
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/MaterialTheme.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/MaterialTheme.kt
index cea4edb..dfa54b1 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/MaterialTheme.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/MaterialTheme.kt
@@ -17,12 +17,8 @@
 
 import androidx.compose.foundation.LocalIndication
 import androidx.compose.foundation.text.selection.LocalTextSelectionColors
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.runtime.remember
 import androidx.wear.compose.foundation.LocalSwipeToDismissBackgroundScrimColor
@@ -66,15 +62,17 @@
         // provided, and overwrite the values set in it.
         colorScheme.copy()
     }.apply { updateColorSchemeFrom(colorScheme) }
-    val rippleIndication = rememberRipple()
+    val rippleIndication = rippleOrFallbackImplementation()
     val selectionColors = rememberTextSelectionColors(rememberedColors)
+    @Suppress("DEPRECATION_ERROR")
     CompositionLocalProvider(
         LocalColorScheme provides rememberedColors,
         LocalShapes provides shapes,
         LocalTypography provides typography,
         LocalContentAlpha provides ContentAlpha.high,
         LocalIndication provides rippleIndication,
-        LocalRippleTheme provides MaterialRippleTheme,
+        // TODO: b/304985887 - remove after one stable release
+        androidx.compose.material.ripple.LocalRippleTheme provides CompatRippleTheme,
         LocalTextSelectionColors provides selectionColors,
         LocalSwipeToDismissBackgroundScrimColor provides rememberedColors.background,
         LocalSwipeToDismissContentScrimColor provides rememberedColors.background
@@ -99,18 +97,3 @@
         @Composable
         get() = LocalShapes.current
 }
-
-@Immutable
-private object MaterialRippleTheme : RippleTheme {
-    @Composable
-    override fun defaultColor() = RippleTheme.defaultRippleColor(
-        contentColor = LocalContentColor.current,
-        lightTheme = false
-    )
-
-    @Composable
-    override fun rippleAlpha() = RippleTheme.defaultRippleAlpha(
-        contentColor = LocalContentColor.current,
-        lightTheme = false
-    )
-}
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Ripple.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Ripple.kt
new file mode 100644
index 0000000..02209a1
--- /dev/null
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Ripple.kt
@@ -0,0 +1,261 @@
+/*
+ * 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.wear.compose.material3
+
+import androidx.compose.foundation.Indication
+import androidx.compose.foundation.IndicationNodeFactory
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.InteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
+import androidx.compose.material.ripple.RippleAlpha
+import androidx.compose.material.ripple.createRippleModifierNode
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.staticCompositionLocalOf
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorProducer
+import androidx.compose.ui.graphics.isSpecified
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.node.DelegatingNode
+import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.unit.Dp
+
+/**
+ * Creates a Ripple using the provided values and values inferred from the theme.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new ripple animation, and
+ * responds to other [Interaction]s by showing a fixed state layer with varying alpha values
+ * depending on the [Interaction].
+ *
+ * [MaterialTheme] provides Ripples using [androidx.compose.foundation.LocalIndication], so a Ripple
+ * will be used as the default [Indication] inside components such as
+ * [androidx.compose.foundation.clickable] and [androidx.compose.foundation.indication], in
+ * addition to Material provided components that use a Ripple as well.
+ *
+ * You can also explicitly create a Ripple and provide it to custom components in order to change
+ * the parameters from the default, such as to create an unbounded ripple with a fixed size.
+ *
+ * To create a Ripple with a manually defined color that can change over time, see the other
+ * [ripple] overload with a [ColorProducer] parameter. This will avoid unnecessary recompositions
+ * when changing the color, and preserve existing ripple state when the color changes.
+ *
+ * @param bounded If true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have alpha applied to calculate the final
+ * color used to draw the ripple. If [Color.Unspecified] is provided the color used will be
+ * [LocalContentColor] instead.
+ */
+@Stable
+fun ripple(
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified,
+    color: Color = Color.Unspecified
+): IndicationNodeFactory {
+    return if (radius == Dp.Unspecified && color == Color.Unspecified) {
+        if (bounded) return DefaultBoundedRipple else DefaultUnboundedRipple
+    } else {
+        RippleNodeFactory(bounded, radius, color)
+    }
+}
+
+/**
+ * Creates a Ripple using the provided values and values inferred from the theme.
+ *
+ * A Ripple is a Material implementation of [Indication] that expresses different [Interaction]s
+ * by drawing ripple animations and state layers.
+ *
+ * A Ripple responds to [PressInteraction.Press] by starting a new ripple animation, and
+ * responds to other [Interaction]s by showing a fixed state layer with varying alpha values
+ * depending on the [Interaction].
+ *
+ * [MaterialTheme] provides Ripples using [androidx.compose.foundation.LocalIndication], so a Ripple
+ * will be used as the default [Indication] inside components such as
+ * [androidx.compose.foundation.clickable] and [androidx.compose.foundation.indication], in
+ * addition to Material provided components that use a Ripple as well.
+ *
+ * You can also explicitly create a Ripple and provide it to custom components in order to change
+ * the parameters from the default, such as to create an unbounded ripple with a fixed size.
+ *
+ * To create a Ripple with a static color, see the [ripple] overload with a [Color] parameter. This
+ * overload is optimized for Ripples that have dynamic colors that change over time, to reduce
+ * unnecessary recompositions.
+ *
+ * @param color the color of the ripple. This color is usually the same color used by the text or
+ * iconography in the component. This color will then have alpha applied to calculate the final
+ * color used to draw the ripple. If you are creating this [ColorProducer] outside of composition
+ * (where it will be automatically remembered), make sure that its instance is stable
+ * (such as by remembering the object that holds it), or remember the returned [ripple] object to
+ * make sure that ripple nodes are not being created each recomposition.
+ * @param bounded If true, ripples are clipped by the bounds of the target layout. Unbounded
+ * ripples always animate from the target layout center, bounded ripples animate from the touch
+ * position.
+ * @param radius the radius for the ripple. If [Dp.Unspecified] is provided then the size will be
+ * calculated based on the target layout size.
+ */
+@Stable
+fun ripple(
+    color: ColorProducer,
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified
+): IndicationNodeFactory {
+    return RippleNodeFactory(bounded, radius, color)
+}
+
+/**
+ * Temporary CompositionLocal to allow configuring whether the old ripple implementation that uses
+ * the deprecated [androidx.compose.material.ripple.RippleTheme] API should be used in Material
+ * components and LocalIndication, instead of the new [ripple] API. This flag defaults to false,
+ * and will be removed after one stable release: it should only be used to temporarily unblock
+ * upgrading.
+ *
+ * Provide this CompositionLocal before you provide [MaterialTheme] to make sure it is correctly
+ * provided through LocalIndication.
+ */
+// TODO: b/304985887 - remove after one stable release
+@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+@get:ExperimentalWearMaterial3Api
+@ExperimentalWearMaterial3Api
+val LocalUseFallbackRippleImplementation: ProvidableCompositionLocal<Boolean> =
+    staticCompositionLocalOf { false }
+
+// TODO: b/304985887 - remove after one stable release
+@Suppress("DEPRECATION_ERROR")
+@OptIn(ExperimentalWearMaterial3Api::class)
+@Composable
+internal fun rippleOrFallbackImplementation(
+    bounded: Boolean = true,
+    radius: Dp = Dp.Unspecified,
+    color: Color = Color.Unspecified
+): Indication {
+    return if (LocalUseFallbackRippleImplementation.current) {
+        androidx.compose.material.ripple.rememberRipple(bounded, radius, color)
+    } else {
+        ripple(bounded, radius, color)
+    }
+}
+
+// TODO: b/304985887 - remove after one stable release
+@Suppress("DEPRECATION_ERROR")
+@Immutable
+internal object CompatRippleTheme : androidx.compose.material.ripple.RippleTheme {
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun defaultColor() = LocalContentColor.current
+
+    @Deprecated("Super method is deprecated")
+    @Composable
+    override fun rippleAlpha() = RippleAlpha
+}
+
+@Stable
+private class RippleNodeFactory private constructor(
+    private val bounded: Boolean,
+    private val radius: Dp,
+    private val colorProducer: ColorProducer?,
+    private val color: Color
+) : IndicationNodeFactory {
+    constructor(
+        bounded: Boolean,
+        radius: Dp,
+        colorProducer: ColorProducer
+    ) : this(bounded, radius, colorProducer, Color.Unspecified)
+
+    constructor(
+        bounded: Boolean,
+        radius: Dp,
+        color: Color
+    ) : this(bounded, radius, null, color)
+
+    override fun create(interactionSource: InteractionSource): DelegatableNode {
+        val colorProducer = colorProducer ?: ColorProducer { color }
+        return DelegatingThemeAwareRippleNode(interactionSource, bounded, radius, colorProducer)
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is RippleNodeFactory) return false
+
+        if (bounded != other.bounded) return false
+        if (radius != other.radius) return false
+        if (colorProducer != other.colorProducer) return false
+        return color == other.color
+    }
+
+    override fun hashCode(): Int {
+        var result = bounded.hashCode()
+        result = 31 * result + radius.hashCode()
+        result = 31 * result + colorProducer.hashCode()
+        result = 31 * result + color.hashCode()
+        return result
+    }
+}
+
+private class DelegatingThemeAwareRippleNode(
+    private val interactionSource: InteractionSource,
+    private val bounded: Boolean,
+    private val radius: Dp,
+    private val color: ColorProducer,
+) : DelegatingNode(), CompositionLocalConsumerModifierNode {
+    override fun onAttach() {
+        val calculateColor = ColorProducer {
+            val userDefinedColor = color()
+            if (userDefinedColor.isSpecified) {
+                userDefinedColor
+            } else {
+                currentValueOf(LocalContentColor)
+            }
+        }
+
+        delegate(createRippleModifierNode(
+            interactionSource,
+            bounded,
+            radius,
+            calculateColor,
+            CalculateRippleAlpha
+        ))
+    }
+}
+
+private val RippleAlpha: RippleAlpha = RippleAlpha(
+    pressedAlpha = 0.12f,
+    focusedAlpha = 0.12f,
+    draggedAlpha = 0.16f,
+    hoveredAlpha = 0.08f
+)
+
+private val CalculateRippleAlpha = { RippleAlpha }
+
+private val DefaultBoundedRipple = RippleNodeFactory(
+    bounded = true,
+    radius = Dp.Unspecified,
+    color = Color.Unspecified
+)
+private val DefaultUnboundedRipple = RippleNodeFactory(
+    bounded = false,
+    radius = Dp.Unspecified,
+    color = Color.Unspecified
+)
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt
index 22c2fa9..fde902e 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/SelectionControls.kt
@@ -85,7 +85,8 @@
     },
     progressAnimationSpec = PROGRESS_ANIMATION_SPEC,
     width = WIDTH,
-    height = HEIGHT
+    height = HEIGHT,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
@@ -150,7 +151,8 @@
     },
     progressAnimationSpec = SWITCH_PROGRESS_ANIMATION_SPEC,
     width = WIDTH,
-    height = HEIGHT
+    height = HEIGHT,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
@@ -196,7 +198,8 @@
     dotAlphaProgressDelay = SHORT_2,
     easing = STANDARD_DECELERATE,
     width = WIDTH,
-    height = HEIGHT
+    height = HEIGHT,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt
index 061f918..2041a01 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Slider.kt
@@ -31,7 +31,6 @@
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Add
-import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Immutable
@@ -136,7 +135,10 @@
         val containerColor = colors.containerColor(enabled)
         val barSeparatorColor = colors.barSeparatorColor(enabled)
         CompositionLocalProvider(
-            LocalIndication provides rememberRipple(bounded = false, radius = this.maxWidth / 2)
+            LocalIndication provides rippleOrFallbackImplementation(
+                bounded = false,
+                radius = this.maxWidth / 2
+            )
         ) {
             Row(
                 verticalAlignment = Alignment.CenterVertically,
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt
index 2c71a42..e7740809 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt
@@ -94,7 +94,8 @@
         disabledButtonProviderValues = arrayOf(
             LocalContentColor provides iconColor.copy(alpha = ContentAlpha.disabled),
             LocalContentAlpha provides iconColor.copy(alpha = ContentAlpha.disabled).alpha
-        )
+        ),
+        buttonRipple = rippleOrFallbackImplementation(bounded = false)
     ) {
         CompositionLocalProvider(
             LocalContentColor provides contentColor
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt
index 36e7bfe..dc7b922 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/TextButton.kt
@@ -99,6 +99,7 @@
         shape = shape,
         border = { rememberUpdatedState(border) },
         buttonSize = TextButtonDefaults.DefaultButtonSize,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled),
             TextButtonTokens.ContentFont.value,
@@ -168,6 +169,7 @@
         toggleButtonSize = TextButtonDefaults.DefaultButtonSize,
         interactionSource = interactionSource,
         shape = shape,
+        ripple = rippleOrFallbackImplementation(),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled, checked = checked),
             TextToggleButtonTokens.ContentFont.value,
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ToggleButton.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ToggleButton.kt
index afd00b2..f9abbdb 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ToggleButton.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/ToggleButton.kt
@@ -138,7 +138,8 @@
         contentPadding = contentPadding,
         shape = shape,
         selectionControlWidth = SELECTION_CONTROL_WIDTH,
-        selectionControlHeight = SELECTION_CONTROL_HEIGHT
+        selectionControlHeight = SELECTION_CONTROL_HEIGHT,
+        ripple = rippleOrFallbackImplementation()
     )
 
 /**
@@ -254,7 +255,8 @@
     checkedInteractionSource = checkedInteractionSource,
     clickInteractionSource = clickInteractionSource,
     contentPadding = contentPadding,
-    shape = shape
+    shape = shape,
+    ripple = rippleOrFallbackImplementation()
 )
 
 /**
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/ImageButtonTokens.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/ImageButtonTokens.kt
new file mode 100644
index 0000000..1f8188e
--- /dev/null
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/ImageButtonTokens.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+// VERSION: v0_33
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+package androidx.wear.compose.material3.tokens
+
+internal object ImageButtonTokens {
+    val BackgroundImageGradientColor = ColorSchemeKeyTokens.Surface
+    val ContentColor = ColorSchemeKeyTokens.OnSurface
+    val DisabledContentOpacity = 0.38f
+    val DisabledContentColor = ColorSchemeKeyTokens.OnSurface
+    val GradientEndOpacity = 0.0f
+    val GradientStartOpacity = 1.0f
+    val IconColor = ColorSchemeKeyTokens.OnSurface
+    val SecondaryContentColor = ColorSchemeKeyTokens.OnSurface
+}
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/OutlinedButtonTokens.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/OutlinedButtonTokens.kt
index dcebc7d..75f8220 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/OutlinedButtonTokens.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/tokens/OutlinedButtonTokens.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-// VERSION: v0_11
+// VERSION: v0_33
 // GENERATED CODE - DO NOT MODIFY BY HAND
 
 package androidx.wear.compose.material3.tokens
@@ -23,6 +23,7 @@
 
 internal object OutlinedButtonTokens {
     val ContainerBorderColor = ColorSchemeKeyTokens.Outline
+    val ContainerBorderWidth = 1.0.dp
     val ContainerHeight = 52.0.dp
     val ContainerShape = ShapeKeyTokens.CornerLarge
     val DisabledContainerBorderColor = ColorSchemeKeyTokens.OnSurface
diff --git a/wear/compose/compose-ui-tooling/build.gradle b/wear/compose/compose-ui-tooling/build.gradle
index c31d84f..4d68f5b 100644
--- a/wear/compose/compose-ui-tooling/build.gradle
+++ b/wear/compose/compose-ui-tooling/build.gradle
@@ -28,7 +28,7 @@
 
     implementation(libs.kotlinStdlibCommon)
     implementation(project(":compose:ui:ui-tooling-preview"))
-    implementation("androidx.wear:wear-tooling-preview:1.0.0-beta01")
+    implementation("androidx.wear:wear-tooling-preview:1.0.0")
 
     samples(project(":wear:compose:compose-material-samples"))
 }
diff --git a/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt b/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt
index 79fd99f..8b9b0288 100644
--- a/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt
+++ b/wear/compose/integration-tests/demos/src/androidTest/java/androidx/wear/compose/integration/demos/test/DemoTest.kt
@@ -17,7 +17,6 @@
 package androidx.wear.compose.integration.demos.test
 
 import android.util.Log
-import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.SemanticsNodeInteractionCollection
 import androidx.compose.ui.test.hasClickAction
 import androidx.compose.ui.test.hasScrollToNodeAction
@@ -47,7 +46,6 @@
 // given the use of ScalingLAZYColumn.
 @LargeTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalTestApi::class)
 class DemoTest {
     // We need to provide the recompose factory first to use new clock.
     @get:Rule
@@ -152,16 +150,18 @@
 
     private fun clearFocusFromDemo() {
         with(rule.activity) {
-            if (hostView.hasFocus()) {
-                if (hostView.isFocused) {
-                    // One of the Compose components has focus.
-                    focusManager.clearFocus(force = true)
-                } else {
-                    // A child view has focus. (View interop scenario).
-                    // We could also use hostViewGroup.focusedChild?.clearFocus(), but the
-                    // interop views might end up being focused if one of them is marked as
-                    // focusedByDefault. So we clear focus by requesting focus on the owner.
-                    rule.runOnUiThread { hostView.requestFocus() }
+            rule.runOnUiThread {
+                if (hostView.hasFocus()) {
+                    if (hostView.isFocused) {
+                        // One of the Compose components has focus.
+                        focusManager.clearFocus(force = true)
+                    } else {
+                        // A child view has focus. (View interop scenario).
+                        // We could also use hostViewGroup.focusedChild?.clearFocus(), but the
+                        // interop views might end up being focused if one of them is marked as
+                        // focusedByDefault. So we clear focus by requesting focus on the owner.
+                        hostView.requestFocus()
+                    }
                 }
             }
         }
@@ -191,13 +191,13 @@
     val newPath = path + this
     return DemoCategory(
         title,
-        demos.mapNotNull {
-            when (it) {
+        demos.mapNotNull { demo ->
+            when (demo) {
                 is DemoCategory -> {
-                    it.filter(newPath, predicate).let { if (it.demos.isEmpty()) null else it }
+                    demo.filter(newPath, predicate).let { if (it.demos.isEmpty()) null else it }
                 }
                 else -> {
-                    if (predicate(newPath, it)) it else null
+                    if (predicate(newPath, demo)) demo else null
                 }
             }
         }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicDataBiTransformNode.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicDataBiTransformNode.java
index 16df6ce..2b3ecda 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicDataBiTransformNode.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicDataBiTransformNode.java
@@ -153,7 +153,11 @@
                 mDownstream.onInvalidated();
             } else {
                 O result = mTransformer.apply(lhs, rhs);
-                mDownstream.onData(result);
+                if (result == null) {
+                    mDownstream.onInvalidated();
+                } else {
+                    mDownstream.onData(result);
+                }
             }
         }
     }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
index 3ca2138..fb45b99 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
@@ -23,6 +23,7 @@
 import androidx.annotation.UiThread;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
+import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedFloat;
 import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticFloatOp;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateFloatSource;
@@ -35,12 +36,12 @@
 
     /** Dynamic float node that has a fixed value. */
     static class FixedFloatNode implements DynamicDataSourceNode<Float> {
-        private final float mValue;
+        @Nullable private final Float mValue;
         private final DynamicTypeValueReceiverWithPreUpdate<Float> mDownstream;
 
         FixedFloatNode(
                 FixedFloat protoNode, DynamicTypeValueReceiverWithPreUpdate<Float> downstream) {
-            this.mValue = protoNode.getValue();
+            this.mValue = getValidValueOrNull(protoNode.getValue());
             this.mDownstream = downstream;
         }
 
@@ -53,7 +54,7 @@
         @Override
         @UiThread
         public void init() {
-            if (Float.isNaN(mValue)) {
+            if (mValue == null) {
                 mDownstream.onInvalidated();
             } else {
                 mDownstream.onData(mValue);
@@ -75,7 +76,7 @@
                     dataStore,
                     StateSourceNode.<DynamicFloat>createKey(
                             protoNode.getSourceNamespace(), protoNode.getSourceKey()),
-                    se -> se.getFloatVal().getValue(),
+                    se -> getValidValueOrNull(se.getFloatVal().getValue()),
                     downstream);
         }
     }
@@ -89,32 +90,36 @@
                 DynamicTypeValueReceiverWithPreUpdate<Float> downstream) {
             super(
                     downstream,
-                    (lhs, rhs) -> {
-                        try {
-                            switch (protoNode.getOperationType()) {
-                                case ARITHMETIC_OP_TYPE_UNDEFINED:
-                                case UNRECOGNIZED:
-                                    Log.e(TAG, "Unknown operation type in ArithmeticFloatNode");
-                                    return Float.NaN;
-                                case ARITHMETIC_OP_TYPE_ADD:
-                                    return lhs + rhs;
-                                case ARITHMETIC_OP_TYPE_SUBTRACT:
-                                    return lhs - rhs;
-                                case ARITHMETIC_OP_TYPE_MULTIPLY:
-                                    return lhs * rhs;
-                                case ARITHMETIC_OP_TYPE_DIVIDE:
-                                    return lhs / rhs;
-                                case ARITHMETIC_OP_TYPE_MODULO:
-                                    return lhs % rhs;
-                            }
-                        } catch (ArithmeticException ex) {
-                            Log.e(TAG, "ArithmeticException in ArithmeticFloatNode", ex);
-                            return Float.NaN;
-                        }
+                    (lhs, rhs) ->
+                            getValidValueOrNull(
+                                    computeResult(protoNode.getOperationType(), lhs, rhs)));
+        }
 
+        private static float computeResult(
+                DynamicProto.ArithmeticOpType opType, Float lhs, Float rhs) {
+            try {
+                switch (opType) {
+                    case ARITHMETIC_OP_TYPE_UNDEFINED:
+                    case UNRECOGNIZED:
                         Log.e(TAG, "Unknown operation type in ArithmeticFloatNode");
                         return Float.NaN;
-                    });
+                    case ARITHMETIC_OP_TYPE_ADD:
+                        return lhs + rhs;
+                    case ARITHMETIC_OP_TYPE_SUBTRACT:
+                        return lhs - rhs;
+                    case ARITHMETIC_OP_TYPE_MULTIPLY:
+                        return lhs * rhs;
+                    case ARITHMETIC_OP_TYPE_DIVIDE:
+                        return lhs / rhs;
+                    case ARITHMETIC_OP_TYPE_MODULO:
+                        return lhs % rhs;
+                }
+            } catch (ArithmeticException ex) {
+                Log.e(TAG, "ArithmeticException in ArithmeticFloatNode", ex);
+                return Float.NaN;
+            }
+            Log.e(TAG, "Unknown operation type in ArithmeticFloatNode");
+            return Float.NaN;
         }
     }
 
@@ -154,8 +159,13 @@
         @Override
         @UiThread
         public void init() {
-            mQuotaAwareAnimator.setFloatValues(mProtoNode.getFromValue(), mProtoNode.getToValue());
-            startOrSkipAnimator();
+            if (isValid(mProtoNode.getFromValue()) && isValid(mProtoNode.getToValue())) {
+                mQuotaAwareAnimator.setFloatValues(
+                        mProtoNode.getFromValue(), mProtoNode.getToValue());
+                startOrSkipAnimator();
+            } else {
+                mDownstream.onInvalidated();
+            }
         }
 
         @Override
@@ -237,4 +247,13 @@
             return mInputCallback;
         }
     }
+
+    private static boolean isValid(Float value) {
+        return value != null && Float.isFinite(value);
+    }
+
+    @Nullable
+    private static Float getValidValueOrNull(Float value) {
+        return isValid(value) ? value : null;
+    }
 }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
index dc035e0..b43d388 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
@@ -150,7 +150,7 @@
                             }
                         } catch (ArithmeticException ex) {
                             Log.e(TAG, "ArithmeticException in ArithmeticInt32Node", ex);
-                            return 0;
+                            return null;
                         }
 
                         Log.e(TAG, "Unknown operation type in ArithmeticInt32Node");
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
index dc0c723..98da705 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
@@ -79,7 +79,11 @@
     @Override
     public void onData(@NonNull DynamicDataValue newData) {
         T actualValue = mStateExtractor.apply(newData);
-        mDownstream.onData(actualValue);
+        if (actualValue == null) {
+            this.onInvalidated();
+        } else {
+            mDownstream.onData(actualValue);
+        }
     }
 
     @Override
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
index 43ff081..27ea07b 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
@@ -68,21 +68,58 @@
 @RunWith(AndroidJUnit4.class)
 public class FloatNodeTest {
     private static final AppDataKey<DynamicFloat> KEY_FOO = new AppDataKey<>("foo");
-    @Rule
-    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Mock private PlatformDataProvider mMockDataProvider;
+
     @Test
-    public void fixedFloatNodesTest() {
+    public void fixedFloatNodesTest_invalidateNotCalled() {
         List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
         float testValue = 6.6f;
 
         FixedFloat protoNode = FixedFloat.newBuilder().setValue(testValue).build();
-        FixedFloatNode node = new FixedFloatNode(protoNode, new AddToListCallback<>(results));
+        FixedFloatNode node =
+                new FixedFloatNode(protoNode, new AddToListCallback<>(results, invalidList));
 
         node.preInit();
         node.init();
 
         assertThat(results).containsExactly(testValue);
+        assertThat(invalidList).isEmpty();
+    }
+
+    @Test
+    public void fixedFloatNodes_receiveNaN_invalidate() {
+        List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+        AddToListCallback<Float> addToListCallback = new AddToListCallback<>(results, invalidList);
+        float testValue = Float.NaN;
+
+        FixedFloat protoNode = FixedFloat.newBuilder().setValue(testValue).build();
+        FixedFloatNode node = new FixedFloatNode(protoNode, addToListCallback);
+
+        node.preInit();
+        node.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
+    }
+
+    @Test
+    public void fixedFloatNodes_receiveInfinite_invalidate() {
+        List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+        AddToListCallback<Float> addToListCallback = new AddToListCallback<>(results, invalidList);
+        float testValue = Float.POSITIVE_INFINITY;
+
+        FixedFloat protoNode = FixedFloat.newBuilder().setValue(testValue).build();
+        FixedFloatNode node = new FixedFloatNode(protoNode, addToListCallback);
+
+        node.preInit();
+        node.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
     }
 
     @Test
@@ -108,6 +145,58 @@
     }
 
     @Test
+    public void stateFloatSourceNode_receiveNaN_invalidate() {
+        List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+
+        float testValue = Float.NaN;
+        StateStore oss =
+                new StateStore(
+                        ImmutableMap.of(
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
+                                        .setFloatVal(FixedFloat.newBuilder().setValue(testValue))
+                                        .build()));
+
+        StateFloatSource protoNode = StateFloatSource.newBuilder().setSourceKey("foo").build();
+        StateFloatSourceNode node =
+                new StateFloatSourceNode(
+                        oss, protoNode, new AddToListCallback<>(results, invalidList));
+
+        node.preInit();
+        node.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
+    }
+
+    @Test
+    public void stateFloatSourceNode_receiveInfinite_invalidate() {
+        List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+
+        float testValue = Float.POSITIVE_INFINITY;
+        StateStore oss =
+                new StateStore(
+                        ImmutableMap.of(
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
+                                        .setFloatVal(FixedFloat.newBuilder().setValue(testValue))
+                                        .build()));
+
+        StateFloatSource protoNode = StateFloatSource.newBuilder().setSourceKey("foo").build();
+        StateFloatSourceNode node =
+                new StateFloatSourceNode(
+                        oss, protoNode, new AddToListCallback<>(results, invalidList));
+
+        node.preInit();
+        node.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
+    }
+
+    @Test
     public void stateFloatSourceNode_updatesWithStateChanges() {
         List<Float> results = new ArrayList<>();
         float oldValue = 6.5f;
@@ -141,22 +230,17 @@
 
     @Test
     public void stateFloatSource_canSubscribeToHeartRateUpdates() {
-        PlatformDataStore platformDataStore = new PlatformDataStore(
-                Collections.singletonMap(
-                        HEART_RATE_BPM,
-                        mMockDataProvider));
+        PlatformDataStore platformDataStore =
+                new PlatformDataStore(Collections.singletonMap(HEART_RATE_BPM, mMockDataProvider));
         StateFloatSource dailyStepsSource =
                 StateFloatSource.newBuilder()
                         .setSourceKey(HEART_RATE_BPM.getKey())
-                        .setSourceNamespace(
-                                HEART_RATE_BPM.getNamespace())
+                        .setSourceNamespace(HEART_RATE_BPM.getNamespace())
                         .build();
         List<Float> results = new ArrayList<>();
         StateFloatSourceNode dailyStepsSourceNode =
                 new StateFloatSourceNode(
-                        platformDataStore,
-                        dailyStepsSource,
-                        new AddToListCallback<>(results));
+                        platformDataStore, dailyStepsSource, new AddToListCallback<>(results));
 
         dailyStepsSourceNode.preInit();
         dailyStepsSourceNode.init();
@@ -261,6 +345,66 @@
     }
 
     @Test
+    public void arithmeticFloat_resultIsNaN_invalidate() {
+        List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+
+        ArithmeticFloatOp protoNode =
+                ArithmeticFloatOp.newBuilder()
+                        .setOperationType(ArithmeticOpType.ARITHMETIC_OP_TYPE_DIVIDE)
+                        .build();
+
+        ArithmeticFloatNode node =
+                new ArithmeticFloatNode(protoNode, new AddToListCallback<>(results, invalidList));
+
+        float numerator = 0f;
+        FixedFloat lhsProtoNode = FixedFloat.newBuilder().setValue(numerator).build();
+        FixedFloatNode lhsNode = new FixedFloatNode(lhsProtoNode, node.getLhsIncomingCallback());
+
+        float denominator = 0f;
+        FixedFloat rhsProtoNode = FixedFloat.newBuilder().setValue(denominator).build();
+        FixedFloatNode rhsNode = new FixedFloatNode(rhsProtoNode, node.getRhsIncomingCallback());
+        lhsNode.preInit();
+        rhsNode.preInit();
+
+        lhsNode.init();
+        rhsNode.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
+    }
+
+    @Test
+    public void arithmeticFloat_resultIsInfinite_invalidate() {
+        List<Float> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+
+        ArithmeticFloatOp protoNode =
+                ArithmeticFloatOp.newBuilder()
+                        .setOperationType(ArithmeticOpType.ARITHMETIC_OP_TYPE_DIVIDE)
+                        .build();
+
+        ArithmeticFloatNode node =
+                new ArithmeticFloatNode(protoNode, new AddToListCallback<>(results, invalidList));
+
+        float numerator = 1f;
+        FixedFloat lhsProtoNode = FixedFloat.newBuilder().setValue(numerator).build();
+        FixedFloatNode lhsNode = new FixedFloatNode(lhsProtoNode, node.getLhsIncomingCallback());
+
+        float denominator = 0;
+        FixedFloat rhsProtoNode = FixedFloat.newBuilder().setValue(denominator).build();
+        FixedFloatNode rhsNode = new FixedFloatNode(rhsProtoNode, node.getRhsIncomingCallback());
+        lhsNode.preInit();
+        rhsNode.preInit();
+
+        lhsNode.init();
+        rhsNode.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
+    }
+
+    @Test
     public void int32ToFloatTest() {
         List<Float> results = new ArrayList<>();
         Int32ToFloatNode node = new Int32ToFloatNode(new AddToListCallback<>(results));
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
index 1e32dc5..0adc166 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
@@ -36,6 +36,7 @@
 import androidx.wear.protolayout.expression.PlatformDataValues;
 import androidx.wear.protolayout.expression.PlatformHealthSources;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.AnimatableFixedInt32Node;
+import androidx.wear.protolayout.expression.pipeline.Int32Nodes.ArithmeticInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.DynamicAnimatedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FixedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.GetDurationPartOpNode;
@@ -43,7 +44,9 @@
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.StateInt32SourceNode;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
 import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
+import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedInt32;
+import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticOpType;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DurationPartType;
 import androidx.wear.protolayout.expression.proto.DynamicProto.GetDurationPartOp;
 import androidx.wear.protolayout.expression.proto.DynamicProto.GetZonedDateTimePartOp;
@@ -96,6 +99,66 @@
     }
 
     @Test
+    public void testArithmeticOperation_validResult_invalidateNotCalled() {
+        List<Integer> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+
+        DynamicProto.ArithmeticInt32Op protoNode =
+                DynamicProto.ArithmeticInt32Op.newBuilder()
+                        .setOperationType(ArithmeticOpType.ARITHMETIC_OP_TYPE_DIVIDE)
+                        .build();
+
+        ArithmeticInt32Node node =
+                new ArithmeticInt32Node(protoNode, new AddToListCallback<>(results, invalidList));
+
+        int numerator = 4;
+        FixedInt32 lhsProtoNode = FixedInt32.newBuilder().setValue(numerator).build();
+        FixedInt32Node lhsNode = new FixedInt32Node(lhsProtoNode, node.getLhsIncomingCallback());
+
+        int denominator = 2;
+        FixedInt32 rhsProtoNode = FixedInt32.newBuilder().setValue(denominator).build();
+        FixedInt32Node rhsNode = new FixedInt32Node(rhsProtoNode, node.getRhsIncomingCallback());
+        lhsNode.preInit();
+        rhsNode.preInit();
+
+        lhsNode.init();
+        rhsNode.init();
+
+        assertThat(results).containsExactly(2);
+        assertThat(invalidList).isEmpty();
+    }
+
+    @Test
+    public void testArithmeticOperation_arithmeticExceptionThrown_invalidate() {
+        List<Integer> results = new ArrayList<>();
+        List<Boolean> invalidList = new ArrayList<>();
+
+        DynamicProto.ArithmeticInt32Op protoNode =
+                DynamicProto.ArithmeticInt32Op.newBuilder()
+                        .setOperationType(ArithmeticOpType.ARITHMETIC_OP_TYPE_DIVIDE)
+                        .build();
+
+        ArithmeticInt32Node node =
+                new ArithmeticInt32Node(protoNode, new AddToListCallback<>(results, invalidList));
+
+        int numerator = 0;
+        FixedInt32 lhsProtoNode = FixedInt32.newBuilder().setValue(numerator).build();
+        FixedInt32Node lhsNode = new FixedInt32Node(lhsProtoNode, node.getLhsIncomingCallback());
+
+        int denominator = 0;
+        FixedInt32 rhsProtoNode = FixedInt32.newBuilder().setValue(denominator).build();
+        FixedInt32Node rhsNode = new FixedInt32Node(rhsProtoNode, node.getRhsIncomingCallback());
+        lhsNode.preInit();
+        rhsNode.preInit();
+
+        lhsNode.init();
+        rhsNode.init();
+
+        assertThat(results).isEmpty();
+        assertThat(invalidList).containsExactly(true);
+    }
+
+    @Test
     public void testGetDurationPartOpNode_positiveDuration() {
 
         // Equivalent to 1day and 10h:17m:36s
diff --git a/wear/protolayout/protolayout-expression/api/current.txt b/wear/protolayout/protolayout-expression/api/current.txt
index 2caea55..f309942 100644
--- a/wear/protolayout/protolayout-expression/api/current.txt
+++ b/wear/protolayout/protolayout-expression/api/current.txt
@@ -8,9 +8,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class AnimationParameterBuilders.AnimationParameters {
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public long getDelayMillis();
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public long getDurationMillis();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing? getEasing();
+    method @IntRange(from=0) public long getDelayMillis();
+    method @IntRange(from=0) public long getDurationMillis();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing? getEasing();
   }
 
   public static final class AnimationParameterBuilders.AnimationParameters.Builder {
@@ -22,34 +22,34 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class AnimationParameterBuilders.AnimationSpec {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getAnimationParameters();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable? getRepeatable();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getAnimationParameters();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable? getRepeatable();
   }
 
   public static final class AnimationParameterBuilders.AnimationSpec.Builder {
     ctor public AnimationParameterBuilders.AnimationSpec.Builder();
     method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec build();
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setAnimationParameters(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setRepeatable(androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setRepeatable(androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface AnimationParameterBuilders.Easing {
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing cubicBezier(float, float, float, float);
     method public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing fromByteArray(byte[]);
     method public default byte[] toEasingByteArray();
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_LINEAR_IN_EASING;
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_SLOW_IN_EASING;
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing LINEAR_OUT_SLOW_IN_EASING;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_LINEAR_IN_EASING;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_SLOW_IN_EASING;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing LINEAR_OUT_SLOW_IN_EASING;
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class AnimationParameterBuilders.Repeatable {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getForwardRepeatOverride();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getIterations();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getRepeatMode();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getReverseRepeatOverride();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getForwardRepeatOverride();
+    method public int getIterations();
+    method public int getRepeatMode();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getReverseRepeatOverride();
     method public boolean hasInfiniteIteration();
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_RESTART;
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_REVERSE;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_RESTART;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_REVERSE;
   }
 
   public static final class AnimationParameterBuilders.Repeatable.Builder {
@@ -82,98 +82,98 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicBool extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicBoolByteArray();
     method public default int toDynamicBoolByteArray(byte[]);
     method public default int toDynamicBoolByteArray(byte[], int, int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicColorByteArray();
     method public default int toDynamicColorByteArray(byte[]);
     method public default int toDynamicColorByteArray(byte[], int, int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!,java.time.Duration!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!,java.time.Duration!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicDurationByteArray();
     method public default int toDynamicDurationByteArray(byte[]);
     method public default int toDynamicDurationByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration withSecondsPrecision(java.time.Duration);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration withSecondsPrecision(java.time.Duration);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat constant(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat constant(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(float);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!,java.lang.Float!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!,java.lang.Float!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
     method public default byte[] toDynamicFloatByteArray();
     method public default int toDynamicFloatByteArray(byte[]);
     method public default int toDynamicFloatByteArray(byte[], int, int);
@@ -189,79 +189,79 @@
   public static final class DynamicBuilders.DynamicFloat.FloatFormatter.Builder {
     ctor public DynamicBuilders.DynamicFloat.FloatFormatter.Builder();
     method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter build();
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setGroupingUsed(boolean);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMaxFractionDigits(@IntRange(from=0) int);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinFractionDigits(@IntRange(from=0) int);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setGroupingUsed(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMaxFractionDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinFractionDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[], int, int);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfMonth(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfWeek(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHour(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinute(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMonth(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecond(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getYear(java.time.ZoneId);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!,java.time.Instant!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfMonth(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfWeek(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHour(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinute(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMonth(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecond(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getYear(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!,java.time.Instant!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
     method public default byte[] toDynamicInstantByteArray();
     method public default int toDynamicInstantByteArray(byte[]);
     method public default int toDynamicInstantByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 constant(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 constant(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(int);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(int);
     method public default byte[] toDynamicInt32ByteArray();
     method public default int toDynamicInt32ByteArray(byte[]);
     method public default int toDynamicInt32ByteArray(byte[], int, int);
@@ -275,17 +275,17 @@
   public static final class DynamicBuilders.DynamicInt32.IntFormatter.Builder {
     ctor public DynamicBuilders.DynamicInt32.IntFormatter.Builder();
     method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter build();
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setGroupingUsed(boolean);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setGroupingUsed(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicStringByteArray();
     method public default int toDynamicStringByteArray(byte[]);
     method public default int toDynamicStringByteArray(byte[], int, int);
@@ -298,15 +298,15 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicDataBuilders.DynamicDataValue<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!> fromBool(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!> fromBool(boolean);
     method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!> fromColor(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!> fromDuration(java.time.Duration);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> fromFloat(float);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!> fromInstant(java.time.Instant);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> fromInt(int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!> fromString(String);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!> fromColor(@ColorInt int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!> fromDuration(java.time.Duration);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> fromFloat(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!> fromInstant(java.time.Instant);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> fromInt(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!> fromString(String);
     method public default boolean getBoolValue();
     method @ColorInt public default int getColorValue();
     method public default java.time.Duration getDurationValue();
@@ -350,12 +350,12 @@
   }
 
   public class PlatformHealthSources {
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyCalories();
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyDistanceMeters();
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyFloors();
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
-    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy heartRateAccuracy();
-    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyCalories();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyDistanceMeters();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyFloors();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy heartRateAccuracy();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
     field public static final int HEART_RATE_ACCURACY_HIGH = 5; // 0x5
     field public static final int HEART_RATE_ACCURACY_LOW = 3; // 0x3
     field public static final int HEART_RATE_ACCURACY_MEDIUM = 4; // 0x4
@@ -365,8 +365,8 @@
   }
 
   public static final class PlatformHealthSources.DynamicHeartRateAccuracy implements androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 {
-    method public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy constant(int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> dynamicDataValueOf(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy constant(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> dynamicDataValueOf(int);
   }
 
   public static class PlatformHealthSources.Keys {
@@ -389,9 +389,10 @@
   public final class VersionBuilders {
   }
 
-  @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class VersionBuilders.VersionInfo {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getMajor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getMinor();
+  @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class VersionBuilders.VersionInfo implements java.lang.Comparable<androidx.wear.protolayout.expression.VersionBuilders.VersionInfo> {
+    method public int compareTo(androidx.wear.protolayout.expression.VersionBuilders.VersionInfo);
+    method public int getMajor();
+    method public int getMinor();
   }
 
   public static final class VersionBuilders.VersionInfo.Builder {
diff --git a/wear/protolayout/protolayout-expression/api/restricted_current.txt b/wear/protolayout/protolayout-expression/api/restricted_current.txt
index 2caea55..f309942 100644
--- a/wear/protolayout/protolayout-expression/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression/api/restricted_current.txt
@@ -8,9 +8,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class AnimationParameterBuilders.AnimationParameters {
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public long getDelayMillis();
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public long getDurationMillis();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing? getEasing();
+    method @IntRange(from=0) public long getDelayMillis();
+    method @IntRange(from=0) public long getDurationMillis();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing? getEasing();
   }
 
   public static final class AnimationParameterBuilders.AnimationParameters.Builder {
@@ -22,34 +22,34 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class AnimationParameterBuilders.AnimationSpec {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getAnimationParameters();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable? getRepeatable();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getAnimationParameters();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable? getRepeatable();
   }
 
   public static final class AnimationParameterBuilders.AnimationSpec.Builder {
     ctor public AnimationParameterBuilders.AnimationSpec.Builder();
     method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec build();
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setAnimationParameters(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setRepeatable(androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setRepeatable(androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface AnimationParameterBuilders.Easing {
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing cubicBezier(float, float, float, float);
     method public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing fromByteArray(byte[]);
     method public default byte[] toEasingByteArray();
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_LINEAR_IN_EASING;
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_SLOW_IN_EASING;
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing LINEAR_OUT_SLOW_IN_EASING;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_LINEAR_IN_EASING;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_SLOW_IN_EASING;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing LINEAR_OUT_SLOW_IN_EASING;
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class AnimationParameterBuilders.Repeatable {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getForwardRepeatOverride();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getIterations();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getRepeatMode();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getReverseRepeatOverride();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getForwardRepeatOverride();
+    method public int getIterations();
+    method public int getRepeatMode();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getReverseRepeatOverride();
     method public boolean hasInfiniteIteration();
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_RESTART;
-    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_REVERSE;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_RESTART;
+    field @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_REVERSE;
   }
 
   public static final class AnimationParameterBuilders.Repeatable.Builder {
@@ -82,98 +82,98 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicBool extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicBoolByteArray();
     method public default int toDynamicBoolByteArray(byte[]);
     method public default int toDynamicBoolByteArray(byte[], int, int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicColorByteArray();
     method public default int toDynamicColorByteArray(byte[]);
     method public default int toDynamicColorByteArray(byte[], int, int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!,java.time.Duration!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!,java.time.Duration!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicDurationByteArray();
     method public default int toDynamicDurationByteArray(byte[]);
     method public default int toDynamicDurationByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration withSecondsPrecision(java.time.Duration);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration withSecondsPrecision(java.time.Duration);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat constant(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat constant(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(float);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!,java.lang.Float!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!,java.lang.Float!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
     method public default byte[] toDynamicFloatByteArray();
     method public default int toDynamicFloatByteArray(byte[]);
     method public default int toDynamicFloatByteArray(byte[], int, int);
@@ -189,79 +189,79 @@
   public static final class DynamicBuilders.DynamicFloat.FloatFormatter.Builder {
     ctor public DynamicBuilders.DynamicFloat.FloatFormatter.Builder();
     method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter build();
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setGroupingUsed(boolean);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMaxFractionDigits(@IntRange(from=0) int);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinFractionDigits(@IntRange(from=0) int);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setGroupingUsed(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMaxFractionDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinFractionDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[], int, int);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfMonth(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfWeek(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHour(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinute(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMonth(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecond(java.time.ZoneId);
-    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getYear(java.time.ZoneId);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!,java.time.Instant!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfMonth(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getDayOfWeek(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHour(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinute(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMonth(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecond(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getYear(java.time.ZoneId);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!,java.time.Instant!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
     method public default byte[] toDynamicInstantByteArray();
     method public default int toDynamicInstantByteArray(byte[]);
     method public default int toDynamicInstantByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 constant(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 constant(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[], int, int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(int);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(int);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(int);
     method public default byte[] toDynamicInt32ByteArray();
     method public default int toDynamicInt32ByteArray(byte[]);
     method public default int toDynamicInt32ByteArray(byte[], int, int);
@@ -275,17 +275,17 @@
   public static final class DynamicBuilders.DynamicInt32.IntFormatter.Builder {
     ctor public DynamicBuilders.DynamicInt32.IntFormatter.Builder();
     method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter build();
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setGroupingUsed(boolean);
-    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setGroupingUsed(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
-    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicStringByteArray();
     method public default int toDynamicStringByteArray(byte[]);
     method public default int toDynamicStringByteArray(byte[], int, int);
@@ -298,15 +298,15 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static interface DynamicDataBuilders.DynamicDataValue<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!> fromBool(boolean);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!> fromBool(boolean);
     method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[]);
     method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[], int, int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!> fromColor(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!> fromDuration(java.time.Duration);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> fromFloat(float);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!> fromInstant(java.time.Instant);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> fromInt(int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!> fromString(String);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!> fromColor(@ColorInt int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!> fromDuration(java.time.Duration);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> fromFloat(float);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!> fromInstant(java.time.Instant);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> fromInt(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!> fromString(String);
     method public default boolean getBoolValue();
     method @ColorInt public default int getColorValue();
     method public default java.time.Duration getDurationValue();
@@ -350,12 +350,12 @@
   }
 
   public class PlatformHealthSources {
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyCalories();
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyDistanceMeters();
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyFloors();
-    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
-    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy heartRateAccuracy();
-    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyCalories();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyDistanceMeters();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyFloors();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy heartRateAccuracy();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
     field public static final int HEART_RATE_ACCURACY_HIGH = 5; // 0x5
     field public static final int HEART_RATE_ACCURACY_LOW = 3; // 0x3
     field public static final int HEART_RATE_ACCURACY_MEDIUM = 4; // 0x4
@@ -365,8 +365,8 @@
   }
 
   public static final class PlatformHealthSources.DynamicHeartRateAccuracy implements androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 {
-    method public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy constant(int);
-    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> dynamicDataValueOf(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy constant(int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> dynamicDataValueOf(int);
   }
 
   public static class PlatformHealthSources.Keys {
@@ -389,9 +389,10 @@
   public final class VersionBuilders {
   }
 
-  @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class VersionBuilders.VersionInfo {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getMajor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getMinor();
+  @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class VersionBuilders.VersionInfo implements java.lang.Comparable<androidx.wear.protolayout.expression.VersionBuilders.VersionInfo> {
+    method public int compareTo(androidx.wear.protolayout.expression.VersionBuilders.VersionInfo);
+    method public int getMajor();
+    method public int getMinor();
   }
 
   public static final class VersionBuilders.VersionInfo.Builder {
diff --git a/wear/protolayout/protolayout-expression/build.gradle b/wear/protolayout/protolayout-expression/build.gradle
index 599d2a9..909c7ee 100644
--- a/wear/protolayout/protolayout-expression/build.gradle
+++ b/wear/protolayout/protolayout-expression/build.gradle
@@ -29,6 +29,9 @@
     implementation("androidx.collection:collection:1.2.0")
     implementation(project(path: ":wear:protolayout:protolayout-proto", configuration: "shadow"))
 
+    lintChecks(project(":wear:protolayout:protolayout-lint"))
+    lintPublish(project(":wear:protolayout:protolayout-lint"))
+
     testImplementation(libs.testExtJunit)
     testImplementation(libs.testExtTruth)
     testImplementation(libs.testRunner)
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AnimationParameterBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AnimationParameterBuilders.java
index f1fecde..44eb9a7 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AnimationParameterBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AnimationParameterBuilders.java
@@ -67,7 +67,6 @@
         }
 
         /** Gets animation parameters including duration, easing and repeat delay. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationParameters getAnimationParameters() {
             if (mImpl.hasAnimationParameters()) {
@@ -81,7 +80,6 @@
          * Gets the repeatable mode to be used for specifying repetition parameters for the
          * animation.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public Repeatable getRepeatable() {
             if (mImpl.hasRepeatable()) {
@@ -160,7 +158,6 @@
              * Sets the repeatable mode to be used for specifying repetition parameters for the
              * animation. If not set, animation won't be repeated.
              */
-            @RequiresSchemaVersion(major = 1, minor = 200)
             @NonNull
             public Builder setRepeatable(@NonNull Repeatable repeatable) {
                 mImpl.setRepeatable(repeatable.toProto());
@@ -191,14 +188,12 @@
         }
 
         /** Gets the duration of the animation in milliseconds. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @IntRange(from = 0)
         public long getDurationMillis() {
             return mImpl.getDurationMillis();
         }
 
         /** Gets the easing to be used for adjusting an animation's fraction. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public Easing getEasing() {
             if (mImpl.hasEasing()) {
@@ -213,7 +208,6 @@
          * the animation in milliseconds. When set inside repeatable, this is the delay before
          * repeating animation in milliseconds.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @IntRange(from = 0)
         public long getDelayMillis() {
             return mImpl.getDelayMillis();
@@ -349,7 +343,9 @@
          *
          * <p>This is equivalent to the Compose {@code FastOutSlowInEasing}.
          */
-        @NonNull Easing FAST_OUT_SLOW_IN_EASING = cubicBezier(0.4f, 0.0f, 0.2f, 1.0f);
+        @RequiresSchemaVersion(major = 1, minor = 200)
+        @NonNull
+        Easing FAST_OUT_SLOW_IN_EASING = cubicBezier(0.4f, 0.0f, 0.2f, 1.0f);
 
         /**
          * Incoming elements are animated using deceleration easing, which starts a transition at
@@ -357,7 +353,9 @@
          *
          * <p>This is equivalent to the Compose {@code LinearOutSlowInEasing}.
          */
-        @NonNull Easing LINEAR_OUT_SLOW_IN_EASING = cubicBezier(0.0f, 0.0f, 0.2f, 1.0f);
+        @RequiresSchemaVersion(major = 1, minor = 200)
+        @NonNull
+        Easing LINEAR_OUT_SLOW_IN_EASING = cubicBezier(0.0f, 0.0f, 0.2f, 1.0f);
 
         /**
          * Elements exiting a screen use acceleration easing, where they start at rest and end at
@@ -365,7 +363,9 @@
          *
          * <p>This is equivalent to the Compose {@code FastOutLinearInEasing}.
          */
-        @NonNull Easing FAST_OUT_LINEAR_IN_EASING = cubicBezier(0.4f, 0.0f, 1.0f, 1.0f);
+        @RequiresSchemaVersion(major = 1, minor = 200)
+        @NonNull
+        Easing FAST_OUT_LINEAR_IN_EASING = cubicBezier(0.4f, 0.0f, 1.0f, 1.0f);
 
         /** Get the protocol buffer representation of this object. */
         @RestrictTo(Scope.LIBRARY_GROUP)
@@ -440,7 +440,6 @@
          * Gets the x coordinate of the first control point. The line through the point (0, 0) and
          * the first control point is tangent to the easing at the point (0, 0).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getX1() {
             return mImpl.getX1();
         }
@@ -449,7 +448,6 @@
          * Gets the y coordinate of the first control point. The line through the point (0, 0) and
          * the first control point is tangent to the easing at the point (0, 0).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getY1() {
             return mImpl.getY1();
         }
@@ -458,7 +456,6 @@
          * Gets the x coordinate of the second control point. The line through the point (1, 1) and
          * the second control point is tangent to the easing at the point (1, 1).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getX2() {
             return mImpl.getX2();
         }
@@ -467,7 +464,6 @@
          * Gets the y coordinate of the second control point. The line through the point (1, 1) and
          * the second control point is tangent to the easing at the point (1, 1).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getY2() {
             return mImpl.getY2();
         }
@@ -594,10 +590,12 @@
         /**
          * An infinite {@link Repeatable} where animation restarts from the beginning when repeated.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         public static final Repeatable INFINITE_REPEATABLE_WITH_RESTART =
                 new Repeatable.Builder().setRepeatMode(REPEAT_MODE_RESTART).build();
 
         /** An infinite {@link Repeatable} where animation is played in reverse when repeated. */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         public static final Repeatable INFINITE_REPEATABLE_WITH_REVERSE =
                 new Repeatable.Builder().setRepeatMode(REPEAT_MODE_REVERSE).build();
 
@@ -615,7 +613,6 @@
          *
          * @throws IllegalStateException if {@link #hasInfiniteIteration()} is true.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public int getIterations() {
             if (hasInfiniteIteration()) {
                 throw new IllegalStateException("Repeatable has infinite iteration.");
@@ -629,14 +626,12 @@
         }
 
         /** Gets the repeat mode to specify how animation will behave when repeated. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @RepeatMode
         public int getRepeatMode() {
             return mImpl.getRepeatMode().getNumber();
         }
 
         /** Gets optional custom parameters for the forward passes of animation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationParameters getForwardRepeatOverride() {
             if (mImpl.hasForwardRepeatOverride()) {
@@ -647,7 +642,6 @@
         }
 
         /** Gets optional custom parameters for the reverse passes of animation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationParameters getReverseRepeatOverride() {
             if (mImpl.hasReverseRepeatOverride()) {
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
index 3c3a0dd3..904183f 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
@@ -26,7 +26,6 @@
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec;
@@ -380,7 +379,6 @@
         }
 
         /** Gets the source to load data from. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @PlatformInt32SourceType
         public int getSourceType() {
             return mImpl.getSourceType().getNumber();
@@ -468,7 +466,6 @@
         }
 
         /** Gets left hand side of the arithmetic operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInputLhs() {
             if (mImpl.hasInputLhs()) {
@@ -479,7 +476,6 @@
         }
 
         /** Gets right hand side of the arithmetic operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInputRhs() {
             if (mImpl.hasInputRhs()) {
@@ -490,7 +486,6 @@
         }
 
         /** Gets the type of operation to carry out. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ArithmeticOpType
         public int getOperationType() {
             return mImpl.getOperationType().getNumber();
@@ -602,14 +597,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
@@ -710,7 +703,6 @@
         }
 
         /** Gets the condition to use. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
@@ -721,7 +713,6 @@
         }
 
         /** Gets the integer to yield if condition is true. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getValueIfTrue() {
             if (mImpl.hasValueIfTrue()) {
@@ -732,7 +723,6 @@
         }
 
         /** Gets the integer to yield if condition is false. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getValueIfFalse() {
             if (mImpl.hasValueIfFalse()) {
@@ -854,7 +844,6 @@
         }
 
         /** Gets the condition to use. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
@@ -865,7 +854,6 @@
         }
 
         /** Gets the float to yield if condition is true. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getValueIfTrue() {
             if (mImpl.hasValueIfTrue()) {
@@ -876,7 +864,6 @@
         }
 
         /** Gets the float to yield if condition is false. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getValueIfFalse() {
             if (mImpl.hasValueIfFalse()) {
@@ -993,7 +980,6 @@
         }
 
         /** Gets the float to round. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInput() {
             if (mImpl.hasInput()) {
@@ -1004,7 +990,6 @@
         }
 
         /** Gets the rounding mode to use. Defaults to ROUND_MODE_FLOOR if not specified. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @FloatToInt32RoundMode
         public int getRoundMode() {
             return mImpl.getRoundMode().getNumber();
@@ -1102,19 +1087,16 @@
         }
 
         /** Gets the value to start animating from. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public int getFromValue() {
             return mImpl.getFromValue();
         }
 
         /** Gets the value to animate to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public int getToValue() {
             return mImpl.getToValue();
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -1236,7 +1218,6 @@
         }
 
         /** Gets the value to watch, and animate when it changes. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInput() {
             if (mImpl.hasInput()) {
@@ -1247,7 +1228,6 @@
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -1438,6 +1418,7 @@
 
         /** Creates a constant-valued {@link DynamicInt32}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicInt32 constant(int constant) {
             return new FixedInt32.Builder().setValue(constant).build();
         }
@@ -1448,6 +1429,7 @@
          * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicInt32 from(@NonNull DynamicDataKey<DynamicInt32> dynamicDataKey) {
             return new StateInt32Source.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -1461,6 +1443,7 @@
          * @param start The start value of the range.
          * @param end The end value of the range.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         static DynamicInt32 animate(int start, int end) {
             return new AnimatableFixedInt32.Builder().setFromValue(start).setToValue(end).build();
@@ -1474,6 +1457,7 @@
          * @param end The end value of the range.
          * @param animationSpec The animation parameters.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         static DynamicInt32 animate(int start, int end, @NonNull AnimationSpec animationSpec) {
             return new AnimatableFixedInt32.Builder()
@@ -1490,6 +1474,7 @@
          *
          * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         static DynamicInt32 animate(@NonNull DynamicDataKey<DynamicInt32> dynamicDataKey) {
             return new AnimatableDynamicInt32.Builder().setInput(from(dynamicDataKey)).build();
@@ -1503,6 +1488,7 @@
          * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value
          * @param animationSpec The animation parameters.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         static DynamicInt32 animate(
                 @NonNull DynamicDataKey<DynamicInt32> dynamicDataKey,
@@ -1520,6 +1506,7 @@
          *
          * @param animationSpec The animation parameters.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicInt32 animate(@NonNull AnimationSpec animationSpec) {
             return new AnimatableDynamicInt32.Builder()
@@ -1533,6 +1520,7 @@
          * and every time its value is changing, it animates from its current value to the new
          * value.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicInt32 animate() {
             return new AnimatableDynamicInt32.Builder().setInput(this).build();
@@ -1541,6 +1529,7 @@
         /**
          * Convert the value represented by this {@link DynamicInt32} into a {@link DynamicFloat}.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicFloat asFloat() {
             return new Int32ToFloatOp.Builder().setInput(this).build();
@@ -1552,6 +1541,7 @@
          * ConditionScopes.IfTrueScope#elseUse} depending on the value yielded from {@code
          * condition}.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         static ConditionScope<DynamicInt32, Integer> onCondition(@NonNull DynamicBool condition) {
             return new ConditionScopes.ConditionScope<>(
@@ -1579,6 +1569,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 plus(@NonNull DynamicInt32 other) {
@@ -1604,6 +1595,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat plus(@NonNull DynamicFloat other) {
@@ -1628,6 +1620,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 plus(int other) {
@@ -1653,6 +1646,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat plus(float other) {
@@ -1678,6 +1672,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 minus(@NonNull DynamicInt32 other) {
@@ -1703,6 +1698,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat minus(@NonNull DynamicFloat other) {
@@ -1728,6 +1724,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 minus(int other) {
@@ -1753,6 +1750,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat minus(float other) {
@@ -1778,6 +1776,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 times(@NonNull DynamicInt32 other) {
@@ -1803,6 +1802,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat times(@NonNull DynamicFloat other) {
@@ -1828,6 +1828,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 times(int other) {
@@ -1853,6 +1854,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat times(float other) {
@@ -1878,6 +1880,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 div(@NonNull DynamicInt32 other) {
@@ -1903,6 +1906,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat div(@NonNull DynamicFloat other) {
@@ -1928,6 +1932,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 div(int other) {
@@ -1953,6 +1958,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat div(float other) {
@@ -1978,6 +1984,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 rem(@NonNull DynamicInt32 other) {
@@ -2003,6 +2010,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat rem(@NonNull DynamicFloat other) {
@@ -2028,6 +2036,7 @@
          *
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicInt32 rem(int other) {
@@ -2053,6 +2062,7 @@
          *
          * @return a new instance of {@link DynamicFloat} containing the result of the operation.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("KotlinOperator")
         @NonNull
         default DynamicFloat rem(float other) {
@@ -2067,6 +2077,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
          * {@code other} are equal, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool eq(@NonNull DynamicInt32 other) {
             return new ComparisonInt32Op.Builder()
@@ -2080,6 +2091,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
          * {@code other} are equal, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool eq(int other) {
             return new ComparisonInt32Op.Builder()
@@ -2093,6 +2105,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
          * {@code other} are not equal, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool ne(@NonNull DynamicInt32 other) {
             return new ComparisonInt32Op.Builder()
@@ -2106,6 +2119,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} and
          * {@code other} are not equal, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool ne(int other) {
             return new ComparisonInt32Op.Builder()
@@ -2119,6 +2133,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * less than {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool lt(@NonNull DynamicInt32 other) {
             return new ComparisonInt32Op.Builder()
@@ -2132,6 +2147,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * less than {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool lt(int other) {
             return new ComparisonInt32Op.Builder()
@@ -2145,6 +2161,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * less than or equal to {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool lte(@NonNull DynamicInt32 other) {
             return new ComparisonInt32Op.Builder()
@@ -2158,6 +2175,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * less than or equal to {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool lte(int other) {
             return new ComparisonInt32Op.Builder()
@@ -2171,6 +2189,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * greater than {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool gt(@NonNull DynamicInt32 other) {
             return new ComparisonInt32Op.Builder()
@@ -2184,6 +2203,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * greater than {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool gt(int other) {
             return new ComparisonInt32Op.Builder()
@@ -2197,6 +2217,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * greater than or equal to {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool gte(@NonNull DynamicInt32 other) {
             return new ComparisonInt32Op.Builder()
@@ -2210,6 +2231,7 @@
          * Returns a {@link DynamicBool} that is true if the value of this {@link DynamicInt32} is
          * greater than or equal to {@code other}, otherwise it's false.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicBool gte(int other) {
             return new ComparisonInt32Op.Builder()
@@ -2230,6 +2252,7 @@
          *
          * The resulted {@link DynamicString} is subject to being truncated if it's too long.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicString format() {
             return new IntFormatter.Builder().build().getInt32FormatOp(this);
@@ -2251,6 +2274,7 @@
          *
          * @param formatter The formatting parameter.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         default DynamicString format(@NonNull IntFormatter formatter) {
             return formatter.getInt32FormatOp(this);
@@ -2267,6 +2291,7 @@
             }
 
             @NonNull
+            @RequiresSchemaVersion(major = 1, minor = 200)
             Int32FormatOp getInt32FormatOp(@NonNull DynamicInt32 dynamicInt32) {
                 return mInt32FormatOpBuilder.setInput(dynamicInt32).build();
             }
@@ -2297,6 +2322,7 @@
                  * will not appear.
                  */
                 @NonNull
+                @RequiresSchemaVersion(major = 1, minor = 200)
                 public Builder setMinIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
                     mBuilder.setMinIntegerDigits(minIntegerDigits);
                     return this;
@@ -2317,6 +2343,7 @@
                  * </pre>
                  */
                 @NonNull
+                @RequiresSchemaVersion(major = 1, minor = 200)
                 public Builder setGroupingUsed(boolean groupingUsed) {
                     mBuilder.setGroupingUsed(groupingUsed);
                     return this;
@@ -2419,7 +2446,6 @@
         }
 
         /** Gets the source of Int32 data to convert to a string. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInput() {
             if (mImpl.hasInput()) {
@@ -2434,7 +2460,6 @@
          * applying minIntegerDigits constraint. If not defined, defaults to one. For example, for
          * locale en_US, applying minIntegerDigit=4 to 12 would yield "0012".
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @IntRange(from = 0)
         public int getMinIntegerDigits() {
             return mImpl.getMinIntegerDigits();
@@ -2445,7 +2470,6 @@
          * locale. If not defined, defaults to false. For example, for locale en_US, using grouping
          * with 1234 would yield "1,234".
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public boolean getGroupingUsed() {
             return mImpl.getGroupingUsed();
         }
@@ -2561,14 +2585,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
@@ -2668,7 +2690,6 @@
         }
 
         /** Gets the condition to use. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
@@ -2679,7 +2700,6 @@
         }
 
         /** Gets the string to yield if condition is true. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicString getValueIfTrue() {
             if (mImpl.hasValueIfTrue()) {
@@ -2690,7 +2710,6 @@
         }
 
         /** Gets the string to yield if condition is false. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicString getValueIfFalse() {
             if (mImpl.hasValueIfFalse()) {
@@ -2806,7 +2825,6 @@
         }
 
         /** Gets left hand side of the concatenation operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicString getInputLhs() {
             if (mImpl.hasInputLhs()) {
@@ -2817,7 +2835,6 @@
         }
 
         /** Gets right hand side of the concatenation operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicString getInputRhs() {
             if (mImpl.hasInputRhs()) {
@@ -2919,7 +2936,6 @@
         }
 
         /** Gets the source of Float data to convert to a string. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInput() {
             if (mImpl.hasInput()) {
@@ -2935,7 +2951,6 @@
          * must be <= maximumFractionDigits. If the condition is not satisfied, then
          * minimumFractionDigits will be used for both fields.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @IntRange(from = 0)
         public int getMaxFractionDigits() {
             return mImpl.getMaxFractionDigits();
@@ -2947,7 +2962,6 @@
          * maximumFractionDigits. If the condition is not satisfied, then minimumFractionDigits will
          * be used for both fields.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @IntRange(from = 0)
         public int getMinFractionDigits() {
             return mImpl.getMinFractionDigits();
@@ -2958,7 +2972,6 @@
          * applying minIntegerDigits constraint. If not defined, defaults to one. For example, for
          * locale en_US, applying minIntegerDigit=4 to 12.34 would yield "0012.34".
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @IntRange(from = 0)
         public int getMinIntegerDigits() {
             return mImpl.getMinIntegerDigits();
@@ -2969,7 +2982,6 @@
          * locale. If not defined, defaults to false. For example, for locale en_US, using grouping
          * with 1234.56 would yield "1,234.56".
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public boolean getGroupingUsed() {
             return mImpl.getGroupingUsed();
         }
@@ -3191,6 +3203,7 @@
          * subject to being truncated if it's too long.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicString constant(@NonNull String constant) {
             return new FixedString.Builder().setValue(constant).build();
         }
@@ -3202,6 +3215,7 @@
          * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a string value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicString from(@NonNull DynamicDataKey<DynamicString> dynamicDataKey) {
             return new StateStringSource.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -3218,6 +3232,7 @@
          * @param condition The value used for evaluting this condition.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static ConditionScope<DynamicString, String> onCondition(@NonNull DynamicBool condition) {
             return new ConditionScopes.ConditionScope<>(
                     (trueValue, falseValue) ->
@@ -3237,6 +3252,7 @@
          * @param other The right hand side operand of the concatenation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicString concat(@NonNull DynamicString other) {
             return new DynamicBuilders.ConcatStringOp.Builder()
                     .setInputLhs(this)
@@ -3312,7 +3328,6 @@
         }
 
         /** Gets left hand side of the arithmetic operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInputLhs() {
             if (mImpl.hasInputLhs()) {
@@ -3323,7 +3338,6 @@
         }
 
         /** Gets right hand side of the arithmetic operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInputRhs() {
             if (mImpl.hasInputRhs()) {
@@ -3334,7 +3348,6 @@
         }
 
         /** Gets the type of operation to carry out. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ArithmeticOpType
         public int getOperationType() {
             return mImpl.getOperationType().getNumber();
@@ -3446,14 +3459,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
@@ -3549,7 +3560,6 @@
         }
 
         /** Gets the input Int32 to convert to a Float. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInput() {
             if (mImpl.hasInput()) {
@@ -3637,19 +3647,16 @@
         }
 
         /** Gets the number to start animating from. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getFromValue() {
             return mImpl.getFromValue();
         }
 
         /** Gets the number to animate to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getToValue() {
             return mImpl.getToValue();
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -3771,7 +3778,6 @@
         }
 
         /** Gets the value to watch, and animate when it changes. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInput() {
             if (mImpl.hasInput()) {
@@ -3782,7 +3788,6 @@
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -3979,6 +3984,7 @@
          * delivered through {@link DynamicTypeValueReceiver<T>#onInvalidate()}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicFloat constant(float constant) {
             return new FixedFloat.Builder().setValue(constant).build();
         }
@@ -3989,6 +3995,7 @@
          * @param dynamicDataKey The data source to a {@link DynamicDataValue} with a float value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicFloat from(@NonNull DynamicDataKey<DynamicFloat> dynamicDataKey) {
             return new StateFloatSource.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -4004,6 +4011,7 @@
          * @param end The end value of the range.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicFloat animate(float start, float end) {
             return new AnimatableFixedFloat.Builder().setFromValue(start).setToValue(end).build();
         }
@@ -4017,6 +4025,7 @@
          * @param animationSpec The animation parameters.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicFloat animate(float start, float end, @NonNull AnimationSpec animationSpec) {
             return new AnimatableFixedFloat.Builder()
                     .setFromValue(start)
@@ -4033,6 +4042,7 @@
          * @param dynamicDataKey The data source to a {@link DynamicDataValue} with a float value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicFloat animate(@NonNull DynamicDataKey<DynamicFloat> dynamicDataKey) {
             return new AnimatableDynamicFloat.Builder().setInput(from(dynamicDataKey)).build();
         }
@@ -4046,6 +4056,7 @@
          * @param animationSpec The animation parameters.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicFloat animate(
                 @NonNull DynamicDataKey<DynamicFloat> dynamicDataKey,
                 @NonNull AnimationSpec animationSpec) {
@@ -4063,6 +4074,7 @@
          * @param animationSpec The animation parameters.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat animate(@NonNull AnimationSpec animationSpec) {
             return new AnimatableDynamicFloat.Builder()
                     .setInput(this)
@@ -4076,6 +4088,7 @@
          * value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat animate() {
             return new AnimatableDynamicFloat.Builder().setInput(this).build();
         }
@@ -4090,6 +4103,7 @@
          * through {@link DynamicTypeValueReceiver<T>#onInvalidate()}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 asInt() {
             return new FloatToInt32Op.Builder()
                     .setRoundMode(DynamicBuilders.ROUND_MODE_FLOOR)
@@ -4114,6 +4128,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat plus(@NonNull DynamicFloat other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4139,6 +4154,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat plus(float other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4164,6 +4180,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat plus(@NonNull DynamicInt32 other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4189,6 +4206,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat minus(@NonNull DynamicFloat other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4214,6 +4232,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat minus(float other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4239,6 +4258,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat minus(@NonNull DynamicInt32 other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4264,6 +4284,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat times(@NonNull DynamicFloat other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4289,6 +4310,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat times(float other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4314,6 +4336,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat times(@NonNull DynamicInt32 other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4339,6 +4362,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat div(@NonNull DynamicFloat other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4364,6 +4388,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat div(float other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4389,6 +4414,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat div(@NonNull DynamicInt32 other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4414,6 +4440,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat rem(@NonNull DynamicFloat other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4439,6 +4466,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat rem(float other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4464,6 +4492,7 @@
          */
         @SuppressWarnings("KotlinOperator")
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicFloat rem(@NonNull DynamicInt32 other) {
             return new ArithmeticFloatOp.Builder()
                     .setInputLhs(this)
@@ -4477,6 +4506,7 @@
          * {@code other} are equal, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool eq(@NonNull DynamicFloat other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4490,6 +4520,7 @@
          * {@code other} are equal, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool eq(float other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4503,6 +4534,7 @@
          * {@code other} are not equal, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool ne(@NonNull DynamicFloat other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4516,6 +4548,7 @@
          * {@code other} are not equal, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool ne(float other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4529,6 +4562,7 @@
          * less than {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool lt(@NonNull DynamicFloat other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4542,6 +4576,7 @@
          * less than {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool lt(float other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4555,6 +4590,7 @@
          * less than or equal to {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool lte(@NonNull DynamicFloat other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4568,6 +4604,7 @@
          * less than or equal to {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool lte(float other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4581,6 +4618,7 @@
          * greater than {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool gt(@NonNull DynamicFloat other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4594,6 +4632,7 @@
          * greater than {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool gt(float other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4607,6 +4646,7 @@
          * greater than or equal to {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool gte(@NonNull DynamicFloat other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4620,6 +4660,7 @@
          * greater than or equal to {@code other}, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool gte(float other) {
             return new ComparisonFloatOp.Builder()
                     .setInputLhs(this)
@@ -4635,6 +4676,7 @@
          * condition}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static ConditionScope<DynamicFloat, Float> onCondition(@NonNull DynamicBool condition) {
             return new ConditionScopes.ConditionScope<>(
                     (trueValue, falseValue) ->
@@ -4658,6 +4700,7 @@
          * The resulted {@link DynamicString} is subject to being truncated if it's too long.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicString format() {
             return new FloatFormatter.Builder().build().getFloatFormatOp(this);
         }
@@ -4679,6 +4722,7 @@
          * @param formatter The formatting parameter.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicString format(@NonNull FloatFormatter formatter) {
             return formatter.getFloatFormatOp(this);
         }
@@ -4693,6 +4737,7 @@
                 mFloatFormatOp = floatFormatOpBuilder.build();
             }
 
+            @RequiresSchemaVersion(major = 1, minor = 200)
             @NonNull
             FloatFormatOp getFloatFormatOp(@NonNull DynamicFloat dynamicFloat) {
                 return mFloatFormatOpBuilder.setInput(dynamicFloat).build();
@@ -4738,6 +4783,7 @@
                  * fields.
                  */
                 @NonNull
+                @RequiresSchemaVersion(major = 1, minor = 200)
                 public Builder setMinFractionDigits(@IntRange(from = 0) int minFractionDigits) {
                     mBuilder.setMinFractionDigits(minFractionDigits);
                     return this;
@@ -4750,6 +4796,7 @@
                  * fields.
                  */
                 @NonNull
+                @RequiresSchemaVersion(major = 1, minor = 200)
                 public Builder setMaxFractionDigits(@IntRange(from = 0) int maxFractionDigits) {
                     mBuilder.setMaxFractionDigits(maxFractionDigits);
                     return this;
@@ -4761,6 +4808,7 @@
                  * will not appear.
                  */
                 @NonNull
+                @RequiresSchemaVersion(major = 1, minor = 200)
                 public Builder setMinIntegerDigits(@IntRange(from = 0) int minIntegerDigits) {
                     mBuilder.setMinIntegerDigits(minIntegerDigits);
                     return this;
@@ -4781,6 +4829,7 @@
                  * </pre>
                  */
                 @NonNull
+                @RequiresSchemaVersion(major = 1, minor = 200)
                 public Builder setGroupingUsed(boolean groupingUsed) {
                     mBuilder.setGroupingUsed(groupingUsed);
                     return this;
@@ -4881,14 +4930,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
@@ -4990,7 +5037,6 @@
         }
 
         /** Gets the left hand side of the comparison operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInputLhs() {
             if (mImpl.hasInputLhs()) {
@@ -5001,7 +5047,6 @@
         }
 
         /** Gets the right hand side of the comparison operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInt32 getInputRhs() {
             if (mImpl.hasInputRhs()) {
@@ -5012,7 +5057,6 @@
         }
 
         /** Gets the type of the operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ComparisonOpType
         public int getOperationType() {
             return mImpl.getOperationType().getNumber();
@@ -5129,7 +5173,6 @@
         }
 
         /** Gets the left hand side of the comparison operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInputLhs() {
             if (mImpl.hasInputLhs()) {
@@ -5140,7 +5183,6 @@
         }
 
         /** Gets the right hand side of the comparison operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getInputRhs() {
             if (mImpl.hasInputRhs()) {
@@ -5151,7 +5193,6 @@
         }
 
         /** Gets the type of the operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ComparisonOpType
         public int getOperationType() {
             return mImpl.getOperationType().getNumber();
@@ -5263,7 +5304,6 @@
         }
 
         /** Gets the input, whose value to negate. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getInput() {
             if (mImpl.hasInput()) {
@@ -5353,7 +5393,6 @@
         }
 
         /** Gets the left hand side of the logical operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getInputLhs() {
             if (mImpl.hasInputLhs()) {
@@ -5364,7 +5403,6 @@
         }
 
         /** Gets the right hand side of the logical operation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getInputRhs() {
             if (mImpl.hasInputRhs()) {
@@ -5375,7 +5413,6 @@
         }
 
         /** Gets the operation type to apply to LHS/RHS. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @LogicalOpType
         public int getOperationType() {
             return mImpl.getOperationType().getNumber();
@@ -5551,6 +5588,7 @@
 
         /** Creates a constant-valued {@link DynamicBool}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicBool constant(boolean constant) {
             return new FixedBool.Builder().setValue(constant).build();
         }
@@ -5561,6 +5599,7 @@
          * @param dynamicDataKey The key to a {@link DynamicDataValue} with a boolean value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicBool from(@NonNull DynamicDataKey<DynamicBool> dynamicDataKey) {
             return new StateBoolSource.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -5573,6 +5612,7 @@
          * i.e. {code result = !this}
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool negate() {
             return new NotBoolOp.Builder().setInput(this).build();
         }
@@ -5584,6 +5624,7 @@
          * @param input The right hand operand of the "and" operation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool and(@NonNull DynamicBool input) {
             return new LogicalBoolOp.Builder()
                     .setInputLhs(this)
@@ -5599,6 +5640,7 @@
          * @param input The right hand operand of the "or" operation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool or(@NonNull DynamicBool input) {
             return new LogicalBoolOp.Builder()
                     .setInputLhs(this)
@@ -5612,6 +5654,7 @@
          * {@code other} are equal, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool eq(@NonNull DynamicBool other) {
             return new LogicalBoolOp.Builder()
                     .setInputLhs(this)
@@ -5625,6 +5668,7 @@
          * {@code other} are not equal, otherwise it's false.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicBool ne(@NonNull DynamicBool other) {
             return new LogicalBoolOp.Builder()
                     .setInputLhs(this)
@@ -5696,14 +5740,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
@@ -5800,21 +5842,18 @@
         }
 
         /** Gets the color value (in ARGB format) to start animating from. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ColorInt
         public int getFromArgb() {
             return mImpl.getFromArgb();
         }
 
         /** Gets the color value (in ARGB format) to animate to. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ColorInt
         public int getToArgb() {
             return mImpl.getToArgb();
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -5936,7 +5975,6 @@
         }
 
         /** Gets the value to watch, and animate when it changes. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicColor getInput() {
             if (mImpl.hasInput()) {
@@ -5947,7 +5985,6 @@
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -6059,7 +6096,6 @@
         }
 
         /** Gets the condition to use. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
@@ -6070,7 +6106,6 @@
         }
 
         /** Gets the color to yield if condition is true. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicColor getValueIfTrue() {
             if (mImpl.hasValueIfTrue()) {
@@ -6081,7 +6116,6 @@
         }
 
         /** Gets the color to yield if condition is false. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicColor getValueIfFalse() {
             if (mImpl.hasValueIfFalse()) {
@@ -6262,6 +6296,7 @@
 
         /** Creates a constant-valued {@link DynamicColor}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicColor constant(@ColorInt int constant) {
             return new FixedColor.Builder().setArgb(constant).build();
         }
@@ -6272,6 +6307,7 @@
          * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicColor from(@NonNull DynamicDataKey<DynamicColor> dynamicDataKey) {
             return new StateColorSource.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -6287,6 +6323,7 @@
          * @param end The end value of the range.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicColor animate(@ColorInt int start, @ColorInt int end) {
             return new AnimatableFixedColor.Builder().setFromArgb(start).setToArgb(end).build();
         }
@@ -6300,6 +6337,7 @@
          * @param animationSpec The animation parameters.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicColor animate(
                 @ColorInt int start, @ColorInt int end, @NonNull AnimationSpec animationSpec) {
             return new AnimatableFixedColor.Builder()
@@ -6317,6 +6355,7 @@
          * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicColor animate(@NonNull DynamicDataKey<DynamicColor> dynamicDataKey) {
             return new AnimatableDynamicColor.Builder().setInput(from(dynamicDataKey)).build();
         }
@@ -6330,6 +6369,7 @@
          * @param animationSpec The animation parameters.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicColor animate(
                 @NonNull DynamicDataKey<DynamicColor> dynamicDataKey,
                 @NonNull AnimationSpec animationSpec) {
@@ -6347,6 +6387,7 @@
          * @param animationSpec The animation parameters.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicColor animate(@NonNull AnimationSpec animationSpec) {
             return new AnimatableDynamicColor.Builder()
                     .setInput(this)
@@ -6360,6 +6401,7 @@
          * value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicColor animate() {
             return new AnimatableDynamicColor.Builder().setInput(this).build();
         }
@@ -6371,6 +6413,7 @@
          * condition}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static ConditionScope<DynamicColor, Integer> onCondition(@NonNull DynamicBool condition) {
             return new ConditionScopes.ConditionScope<>(
                     (trueValue, falseValue) ->
@@ -6517,7 +6560,6 @@
         }
 
         /** Gets the condition to use. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
@@ -6528,7 +6570,6 @@
         }
 
         /** Gets the instant to yield if condition is true. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInstant getValueIfTrue() {
             if (mImpl.hasValueIfTrue()) {
@@ -6539,7 +6580,6 @@
         }
 
         /** Gets the instant to yield if condition is false. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInstant getValueIfFalse() {
             if (mImpl.hasValueIfFalse()) {
@@ -6731,6 +6771,7 @@
          *     Instant} value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         static DynamicInstant from(@NonNull DynamicDataKey<DynamicInstant> dynamicDataKey) {
             return new StateInstantSource.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -6744,6 +6785,7 @@
          * dropped.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicInstant withSecondsPrecision(@NonNull Instant instant) {
             return new FixedInstant.Builder().setEpochSeconds(instant.getEpochSecond()).build();
         }
@@ -6753,6 +6795,7 @@
          * time.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicInstant platformTimeWithSecondsPrecision() {
             return new PlatformTimeSource.Builder().build();
         }
@@ -6771,6 +6814,7 @@
          * @return a new instance of {@link DynamicDuration} containing the result of the operation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicDuration durationUntil(@NonNull DynamicInstant to) {
             return new BetweenDuration.Builder()
                     .setStartInclusive(this)
@@ -6787,7 +6831,7 @@
          *      .getYear(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getYear(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getYear();
@@ -6802,7 +6846,7 @@
          *      .getMonth(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getMonth(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getMonth();
@@ -6817,7 +6861,7 @@
          *      .getDayOfMonth(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getDayOfMonth(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getDayOfMonth();
@@ -6833,7 +6877,7 @@
          *      .getDayOfWeek(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getDayOfWeek(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getDayOfWeek();
@@ -6848,7 +6892,7 @@
          *      .getHour(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getHour(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getHour();
@@ -6863,7 +6907,7 @@
          *      .getMinute(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getMinute(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getMinute();
@@ -6878,7 +6922,7 @@
          *      .getSecond(ZoneId.of("Europe/London"));
          * </pre>
          */
-        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        @RequiresSchemaVersion(major=1,minor=300)
         @NonNull
         default DynamicInt32 getSecond(@NonNull ZoneId zoneId) {
             return this.atZone(zoneId).getSecond();
@@ -6899,6 +6943,7 @@
          */
         @RestrictTo(Scope.LIBRARY)
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicZonedDateTime atZone(@NonNull ZoneId zoneId) {
             return new InstantToZonedDateTimeOp.Builder()
                     .setInstant(this)
@@ -6913,6 +6958,7 @@
          * condition}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static ConditionScope<DynamicInstant, Instant> onCondition(@NonNull DynamicBool condition) {
             return new ConditionScopes.ConditionScope<>(
                     (trueValue, falseValue) ->
@@ -7067,6 +7113,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getYear() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7085,6 +7132,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getMonth() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7103,6 +7151,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getDayOfMonth() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7122,6 +7171,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getDayOfWeek() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7140,6 +7190,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getHour() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7158,6 +7209,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getMinute() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7176,6 +7228,7 @@
          * </pre>
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         default DynamicInt32 getSecond() {
             return new GetZonedDateTimePartOp.Builder()
                     .setInput(this)
@@ -7235,7 +7288,6 @@
         }
 
         /** Gets the instant to convert. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @Nullable
         public DynamicInstant getInstant() {
             if (mImpl.hasInstant()) {
@@ -7246,7 +7298,6 @@
         }
 
         /** Gets the ZoneId following the time-zone ID format used by java {@link ZoneId}. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public String getZoneId() {
             return mImpl.getZoneId();
@@ -7353,7 +7404,6 @@
         }
 
         /** Gets the zoned date-time input. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @Nullable
         public DynamicZonedDateTime getInput() {
             if (mImpl.hasInput()) {
@@ -7364,7 +7414,6 @@
         }
 
         /** Gets the date-time part to retrieve. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @ZonedDateTimePartType
         public int getPartType() {
             return mImpl.getPartType().getNumber();
@@ -7465,7 +7514,6 @@
         }
 
         /** Gets the time instant value marking the start of the duration. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInstant getStartInclusive() {
             if (mImpl.hasStartInclusive()) {
@@ -7476,7 +7524,6 @@
         }
 
         /** Gets the time instant value marking the end of the duration. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicInstant getEndExclusive() {
             if (mImpl.hasEndExclusive()) {
@@ -7586,7 +7633,6 @@
         }
 
         /** Gets the condition to use. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
@@ -7597,7 +7643,6 @@
         }
 
         /** Gets the duration to yield if condition is true. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicDuration getValueIfTrue() {
             if (mImpl.hasValueIfTrue()) {
@@ -7608,7 +7653,6 @@
         }
 
         /** Gets the duration to yield if condition is false. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicDuration getValueIfFalse() {
             if (mImpl.hasValueIfFalse()) {
@@ -7795,6 +7839,7 @@
          *     Duration} value.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         static DynamicDuration from(@NonNull DynamicDataKey<DynamicDuration> dynamicDataKey) {
             return new StateDurationSource.Builder()
                     .setSourceKey(dynamicDataKey.getKey())
@@ -7808,6 +7853,7 @@
          * be dropped.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicDuration withSecondsPrecision(@NonNull Duration duration) {
             return new FixedDuration.Builder().setSeconds(duration.getSeconds()).build();
         }
@@ -7829,6 +7875,7 @@
          *     Integer#MAX_VALUE}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 toIntDays() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7852,6 +7899,7 @@
          *     Integer#MAX_VALUE}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 toIntHours() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7875,6 +7923,7 @@
          *     Integer#MAX_VALUE}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 toIntMinutes() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7898,6 +7947,7 @@
          *     Integer#MAX_VALUE}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 toIntSeconds() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7922,6 +7972,7 @@
          *     Integer#MAX_VALUE}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 getIntDaysPart() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7944,6 +7995,7 @@
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 getHoursPart() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7966,6 +8018,7 @@
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 getMinutesPart() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -7988,6 +8041,7 @@
          * @return a new instance of {@link DynamicInt32} containing the result of the operation.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         default DynamicInt32 getSecondsPart() {
             return new GetDurationPartOp.Builder()
                     .setInput(this)
@@ -8002,6 +8056,7 @@
          * condition}.
          */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static ConditionScope<DynamicDuration, Duration> onCondition(
                 @NonNull DynamicBool condition) {
             return new ConditionScopes.ConditionScope<>(
@@ -8075,7 +8130,6 @@
         }
 
         /** Gets the duration input. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicDuration getInput() {
             if (mImpl.hasInput()) {
@@ -8086,7 +8140,6 @@
         }
 
         /** Gets the duration part to retrieve. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @DurationPartType
         public int getDurationPart() {
             return mImpl.getDurationPart().getNumber();
@@ -8184,14 +8237,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
@@ -8290,14 +8341,12 @@
         }
 
         /** Gets the key in the state to bind to. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public String getSourceKey() {
             return mImpl.getSourceKey();
         }
 
         /** Gets the namespace for the state key. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public String getSourceNamespace() {
             return mImpl.getSourceNamespace();
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
index 7ef7727..69c88e3 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
@@ -130,42 +130,49 @@
 
         /** Creates a boolean {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicDataValue<DynamicBool> fromBool(boolean constant) {
             return new FixedBool.Builder().setValue(constant).build();
         }
 
         /** Creates a int {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicDataValue<DynamicInt32> fromInt(int constant) {
             return new FixedInt32.Builder().setValue(constant).build();
         }
 
         /** Creates a float {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicDataValue<DynamicFloat> fromFloat(float constant) {
             return new FixedFloat.Builder().setValue(constant).build();
         }
 
         /** Creates a color {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicDataValue<DynamicColor> fromColor(@ColorInt int constant) {
             return new FixedColor.Builder().setArgb(constant).build();
         }
 
         /** Creates a string {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         static DynamicDataValue<DynamicString> fromString(@NonNull String constant) {
             return new FixedString.Builder().setValue(constant).build();
         }
 
         /** Creates an {@link Instant} {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         static DynamicDataValue<DynamicInstant> fromInstant(@NonNull Instant constant) {
             return new FixedInstant.Builder().setEpochSeconds(constant.getEpochSecond()).build();
         }
 
         /** Creates a {@link Duration} {@link DynamicDataValue}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 300)
         static DynamicDataValue<DynamicDuration> fromDuration(@NonNull Duration constant) {
             return new FixedDuration.Builder().setSeconds(constant.getSeconds()).build();
         }
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
index e1ebe55..3f676f5 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
@@ -51,7 +51,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public int getValue() {
             return mImpl.getValue();
         }
@@ -163,7 +162,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getValue() {
             return mImpl.getValue();
@@ -282,7 +280,6 @@
          * node will have an invalid value delivered via {@link
          * DynamicTypeValueReceiver<T>#onInvalidate()}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public float getValue() {
             return mImpl.getValue();
         }
@@ -398,7 +395,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public boolean getValue() {
             return mImpl.getValue();
         }
@@ -511,7 +507,6 @@
         }
 
         /** Gets the color value, in ARGB format. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ColorInt
         public int getArgb() {
             return mImpl.getArgb();
@@ -624,7 +619,6 @@
         }
 
         /** Gets the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public long getEpochSeconds() {
             return mImpl.getEpochSeconds();
         }
@@ -739,7 +733,6 @@
         }
 
         /** Gets duration in seconds. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public long getSeconds() {
             return mImpl.getSeconds();
         }
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
index f5b767b..5424cf7 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
@@ -16,9 +16,6 @@
 
 package androidx.wear.protolayout.expression;
 
-import static androidx.wear.protolayout.expression.DynamicBuilders.PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE;
-import static androidx.wear.protolayout.expression.DynamicBuilders.PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT;
-
 import android.Manifest;
 
 import androidx.annotation.IntDef;
@@ -28,7 +25,6 @@
 import androidx.annotation.RestrictTo;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
-import androidx.wear.protolayout.expression.DynamicBuilders.PlatformInt32Source;
 import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 
@@ -51,14 +47,19 @@
 
     /** Heart rate accuracy is unknown. */
     public static final int HEART_RATE_ACCURACY_UNKNOWN = 0;
+
     /** Heart rate cannot be acquired because the sensor is not properly contacting skin. */
     public static final int HEART_RATE_ACCURACY_NO_CONTACT = 1;
+
     /** Heart rate data is currently too unreliable to be used. */
     public static final int HEART_RATE_ACCURACY_UNRELIABLE = 2;
+
     /** Heart rate data is available but the accuracy is low. */
     public static final int HEART_RATE_ACCURACY_LOW = 3;
+
     /** Heart rate data is available and the accuracy is medium. */
     public static final int HEART_RATE_ACCURACY_MEDIUM = 4;
+
     /** Heart rate data is available with high accuracy. */
     public static final int HEART_RATE_ACCURACY_HIGH = 5;
 
@@ -80,6 +81,7 @@
         @RequiresPermission(Manifest.permission.BODY_SENSORS)
         public static final PlatformDataKey<DynamicHeartRateAccuracy> HEART_RATE_ACCURACY =
                 new PlatformDataKey<>("HeartRate Accuracy");
+
         /**
          * The data source key for daily step count data from platform health sources. This is the
          * total step count over a day and it resets when 00:00 is reached (in whatever is the
@@ -104,10 +106,10 @@
 
         /**
          * The data source key for daily calories (kcal) data from platform health sources. This is
-         * the total number of kilocalories over a day (including both BMR and active calories)
-         * and it resets when 00:00 is reached (in whatever is the timezone set at that time).
-         * This can result in the DAILY period being greater than or less than 24 hours when the
-         * timezone of the device is changed.
+         * the total number of kilocalories over a day (including both BMR and active calories) and
+         * it resets when 00:00 is reached (in whatever is the timezone set at that time). This can
+         * result in the DAILY period being greater than or less than 24 hours when the timezone of
+         * the device is changed.
          */
         @NonNull
         @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
@@ -136,6 +138,7 @@
      */
     @RequiresPermission(Manifest.permission.BODY_SENSORS)
     @NonNull
+    @RequiresSchemaVersion(major = 1, minor = 200)
     public static DynamicFloat heartRateBpm() {
         return DynamicFloat.from(Keys.HEART_RATE_BPM);
     }
@@ -148,6 +151,7 @@
      */
     @RequiresPermission(Manifest.permission.BODY_SENSORS)
     @NonNull
+    @RequiresSchemaVersion(major = 1, minor = 200)
     public static DynamicHeartRateAccuracy heartRateAccuracy() {
         return new DynamicHeartRateAccuracy(
                 new DynamicBuilders.StateInt32Source.Builder()
@@ -167,6 +171,7 @@
      */
     @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
     @NonNull
+    @RequiresSchemaVersion(major = 1, minor = 200)
     public static DynamicInt32 dailySteps() {
         return DynamicInt32.from(Keys.DAILY_STEPS);
     }
@@ -179,6 +184,7 @@
      */
     @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
     @NonNull
+    @RequiresSchemaVersion(major = 1, minor = 200)
     public static DynamicFloat dailyFloors() {
         return DynamicFloat.from(Keys.DAILY_FLOORS);
     }
@@ -192,6 +198,7 @@
      */
     @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
     @NonNull
+    @RequiresSchemaVersion(major = 1, minor = 200)
     public static DynamicFloat dailyCalories() {
         return DynamicFloat.from(Keys.DAILY_CALORIES);
     }
@@ -204,6 +211,7 @@
      */
     @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
     @NonNull
+    @RequiresSchemaVersion(major = 1, minor = 200)
     public static DynamicFloat dailyDistanceMeters() {
         return DynamicFloat.from(Keys.DAILY_DISTANCE_METERS);
     }
@@ -218,6 +226,7 @@
 
         /** Creates a constant-valued {@link DynamicHeartRateAccuracy}. */
         @NonNull
+        @RequiresSchemaVersion(major = 1, minor = 200)
         public static DynamicHeartRateAccuracy constant(@HeartRateAccuracy int val) {
             return new DynamicHeartRateAccuracy(DynamicInt32.constant(val));
         }
@@ -225,6 +234,7 @@
         /** Creates a value to be provided from a {@code PlatformDataProvider}. */
         @NonNull
         @SuppressWarnings("unchecked") // DynamicHeartRateAccuracy acts like DynamicInt32.
+        @RequiresSchemaVersion(major = 1, minor = 200)
         public static DynamicDataValue<DynamicHeartRateAccuracy> dynamicDataValueOf(
                 @HeartRateAccuracy int val) {
             return (DynamicDataValue<DynamicHeartRateAccuracy>)
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/RequiresSchemaVersion.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/RequiresSchemaVersion.java
index e5a748e..6041b9f 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/RequiresSchemaVersion.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/RequiresSchemaVersion.java
@@ -27,7 +27,13 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
-/** Indicates the minimum schema version the annotated type is supported at. */
+/**
+ * Indicates the minimum schema version the annotated type is supported at. {@link #major()} and
+ * {@link #minor()} correspond to {@link VersionBuilders.VersionInfo#getMajor()} and {@link
+ * VersionBuilders.VersionInfo#getMinor()} values reported by renderers/evaluators of ProtoLayout.
+ *
+ * <p>Note that {@link #minor()} version is usually in the form of {@code x00} such as 100, 200, ...
+ */
 @MustBeDocumented
 @Retention(CLASS)
 @Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/VersionBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/VersionBuilders.java
index 24f0bce..7c0196c 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/VersionBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/VersionBuilders.java
@@ -22,6 +22,8 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.expression.proto.VersionProto;
 
+import java.util.Objects;
+
 /** Builders for the schema version information of a layout (or an expression). */
 public final class VersionBuilders {
     private VersionBuilders() {}
@@ -31,7 +33,7 @@
      * layout).
      */
     @RequiresSchemaVersion(major = 1, minor = 0)
-    public static final class VersionInfo {
+    public static final class VersionInfo implements Comparable<VersionInfo> {
         private final VersionProto.VersionInfo mImpl;
         @Nullable private final Fingerprint mFingerprint;
 
@@ -44,7 +46,6 @@
          * Gets major version. Incremented on breaking changes (i.e. compatibility is not guaranteed
          * across major versions).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public int getMajor() {
             return mImpl.getMajor();
         }
@@ -53,7 +54,6 @@
          * Gets minor version. Incremented on non-breaking changes (e.g. schema additions). Anything
          * consuming a payload can safely consume anything with a lower minor version.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public int getMinor() {
             return mImpl.getMinor();
         }
@@ -96,6 +96,28 @@
             return "VersionInfo{" + "major=" + getMajor() + ", minor=" + getMinor() + "}";
         }
 
+        @Override
+        public int compareTo(@NonNull VersionInfo other) {
+            if (this.getMajor() == other.getMajor()) {
+                return Integer.compare(this.getMinor(), other.getMinor());
+            }
+            return Integer.compare(this.getMajor(), other.getMajor());
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(getMajor(), getMinor());
+        }
+
+        @Override
+        public boolean equals(@Nullable Object obj) {
+            if (obj instanceof VersionInfo) {
+                VersionInfo that = (VersionInfo) obj;
+                return this.getMajor() == that.getMajor() && this.getMinor() == that.getMinor();
+            }
+            return false;
+        }
+
         /** Builder for {@link VersionInfo} */
         public static final class Builder {
             private final VersionProto.VersionInfo.Builder mImpl =
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/VersionInfoTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/VersionInfoTest.java
index cc5c2b8..6ae2b23 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/VersionInfoTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/VersionInfoTest.java
@@ -18,10 +18,16 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import androidx.wear.protolayout.expression.VersionBuilders.VersionInfo;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 @RunWith(RobolectricTestRunner.class)
 public final class VersionInfoTest {
     @Test
@@ -29,10 +35,22 @@
         int major = 10;
         int minor = 20;
 
-        VersionBuilders.VersionInfo versionInfo =
-                new VersionBuilders.VersionInfo.Builder().setMajor(major).setMinor(minor).build();
+        VersionInfo versionInfo = new VersionInfo.Builder().setMajor(major).setMinor(minor).build();
 
         assertThat(versionInfo.toProto().getMajor()).isEqualTo(major);
         assertThat(versionInfo.toProto().getMinor()).isEqualTo(minor);
     }
+
+    @Test
+    public void versionInfoComparison() {
+        VersionInfo v1_0 = new VersionInfo.Builder().setMajor(1).setMinor(0).build();
+        VersionInfo v1_1 = new VersionInfo.Builder().setMajor(1).setMinor(1).build();
+        VersionInfo v2_0 = new VersionInfo.Builder().setMajor(2).setMinor(0).build();
+        VersionInfo v2_1 = new VersionInfo.Builder().setMajor(2).setMinor(1).build();
+        List<VersionInfo> versions = Arrays.asList(v2_1, v2_0, v1_1, v2_0, v1_0);
+
+        Collections.sort(versions);
+
+        assertThat(versions).containsExactly(v1_0, v1_1, v2_0, v2_0, v2_1).inOrder();
+    }
 }
diff --git a/wear/protolayout/protolayout-lint/build.gradle b/wear/protolayout/protolayout-lint/build.gradle
index ded2b3d..dbe2777 100644
--- a/wear/protolayout/protolayout-lint/build.gradle
+++ b/wear/protolayout/protolayout-lint/build.gradle
@@ -22,7 +22,7 @@
 }
 
 dependencies {
-    compileOnly(libs.androidLintMinApi)
+    compileOnly(libs.androidLintApi)
     compileOnly(libs.kotlinStdlib)
 
     testImplementation(libs.kotlinStdlib)
diff --git a/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutIssueRegistry.kt b/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutIssueRegistry.kt
index fe0c181..d47fe85 100644
--- a/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutIssueRegistry.kt
+++ b/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutIssueRegistry.kt
@@ -19,19 +19,17 @@
 import com.android.tools.lint.client.api.IssueRegistry
 import com.android.tools.lint.client.api.Vendor
 import com.android.tools.lint.detector.api.CURRENT_API
-import com.android.tools.lint.detector.api.Issue
 
-/**
- * Issue Registry containing ProtoLayout specific lint Issues.
- */
+/** Issue Registry containing ProtoLayout specific lint Issues. */
 @Suppress("UnstableApiUsage")
 class ProtoLayoutIssueRegistry : IssueRegistry() {
     override val api = 14
     override val minApi = CURRENT_API
-    override val issues get() = emptyList<Issue>()
-    override val vendor = Vendor(
-        feedbackUrl = "https://issuetracker.google.com/issues/new?component=1112273",
-        identifier = "androidx.wear.protolayout",
-        vendorName = "Android Open Source Project",
-    )
+    override val issues = listOf(ProtoLayoutMinSchemaDetector.ISSUE)
+    override val vendor =
+        Vendor(
+            feedbackUrl = "https://issuetracker.google.com/issues/new?component=1112273",
+            identifier = "androidx.wear.protolayout",
+            vendorName = "Android Open Source Project",
+        )
 }
diff --git a/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutMinSchemaDetector.kt b/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutMinSchemaDetector.kt
new file mode 100644
index 0000000..026b328
--- /dev/null
+++ b/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/ProtoLayoutMinSchemaDetector.kt
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+@file:Suppress("UnstableApiUsage")
+
+package androidx.wear.protolayout.lint
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.ApiConstraint
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.ConstantEvaluator
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.VersionChecks.Companion.isPrecededByVersionCheckExit
+import com.android.tools.lint.detector.api.VersionChecks.Companion.isWithinVersionCheckConditional
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiModifierListOwner
+import org.jetbrains.uast.UAnnotated
+import org.jetbrains.uast.UAnnotation
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UResolvable
+import org.jetbrains.uast.getContainingUMethod
+import org.jetbrains.uast.getContainingUVariable
+
+// TODO: b/308552481 - Add support for empty Builder construction (right now only setters are
+// annotated).
+
+/**
+ * The linter for detecting usage of ProtoLayout APIs (newer than schema 1.0) without properly
+ * checking the availability of them. Currently it relies on SDK checks that correspond to each
+ * ProtoLayout schema version.
+ *
+ * All **method** calls (where the callee has RequiresSchemaVersion annotation) are inspected to see
+ * if the call site meets the condition for the schema version. This means the caller have to either
+ * have a compatible RequiresSchemaVersion annotation (with greater than or equal version to the one
+ * needed), or the call to be within the scope of SDK version that matches the schema version. For
+ * example if the call is inside a SDK 34 version check, calls to schema versions including 1.300
+ * and below are all allowed.
+ *
+ * Note that RequiresSchemaVersion annotations on class are ignored (except for Builder classes).
+ */
+class ProtoLayoutMinSchemaDetector : Detector(), Detector.UastScanner {
+    override fun getApplicableUastTypes() = listOf(UCallExpression::class.java)
+
+    override fun createUastHandler(context: JavaContext) =
+        object : UElementHandler() {
+            override fun visitCallExpression(node: UCallExpression) {
+                val method = node.resolve() ?: return
+                checkMethodCall(context, node, method)
+            }
+        }
+
+    internal fun checkMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        // Does the callee have a RequiredSchemaVersion annotation?
+        val calleeAnnotation = method.getSchemaVersionAnnotation(context) ?: return
+        val callerSchemaAnnotation =
+            (node.getContainingUMethod() ?: node.getContainingUVariable())
+                ?.getSchemaVersionAnnotation(context)
+
+        if (calleeAnnotation.major <= 1 && calleeAnnotation.minor <= 100) {
+            // We only care about 1.2 and above
+            return
+        }
+
+        // Check callers RequiresSchemaVersion annotation and TargetApi/RequiresApi annotation.
+        if (
+            !calleeAnnotation.isCoveredBySchemaAnnotation(callerSchemaAnnotation) &&
+                !calleeAnnotation.isCoveredByTargetApi(context, node)
+        ) {
+            context.report(
+                issue = ISSUE,
+                location = context.getLocation(node),
+                message =
+                    "This API is not guaranteed to be available on the device" +
+                        " (requires schema $calleeAnnotation).",
+            )
+        }
+    }
+
+    private fun PsiModifierListOwner.getSchemaVersionAnnotation(
+        context: JavaContext
+    ): SchemaAnnotation? {
+        return if (this is UAnnotated) {
+            findAnnotation(REQUIRES_SCHEMA_ANNOTATION)?.asSchemaAnnotation(context)
+        } else {
+            context.evaluator
+                .getAnnotationInHierarchy(this, REQUIRES_SCHEMA_ANNOTATION)
+                ?.asSchemaAnnotation(context)
+        }
+    }
+
+    private fun UAnnotation.asSchemaAnnotation(context: JavaContext): SchemaAnnotation? {
+        val majorValue = attributeValue(context, "major")
+        val minorValue = attributeValue(context, "minor")
+        return if (majorValue != null && minorValue != null) {
+            SchemaAnnotation(majorValue, minorValue)
+        } else {
+            null
+        }
+    }
+
+    private fun UAnnotation.attributeValue(context: JavaContext, attrName: String): Int? {
+        val attrValue = findAttributeValue(attrName) ?: return null
+        val value =
+            ConstantEvaluator.evaluate(context, attrValue) ?: (attrValue as? UResolvable)?.resolve()
+        return when (value) {
+            is PsiField -> value.computeConstantValue() as Int?
+            is Int -> value
+            else -> null
+        }
+    }
+
+    private data class SchemaAnnotation(val major: Int, val minor: Int) {
+        fun isCoveredBySchemaAnnotation(other: SchemaAnnotation?): Boolean =
+            other != null && (major < other.major || (major == other.major && minor <= other.minor))
+
+        fun isCoveredByTargetApi(context: JavaContext, node: UCallExpression): Boolean {
+            val minSdkConstraint = ApiConstraint.get(toMinSdk() ?: return false)
+            return isWithinVersionCheckConditional(context, node, minSdkConstraint) ||
+                isPrecededByVersionCheckExit(context, node, minSdkConstraint) ||
+                hasAtLeastTargetApiAnnotation(context.evaluator, node, minSdkConstraint)
+        }
+
+        fun toMinSdk(): Int? =
+            when (minor) {
+                in Int.MIN_VALUE..100 -> null
+                in 101..200 -> 33
+                in 201..300 -> 34
+                else -> Int.MAX_VALUE
+            }
+
+        override fun toString() = "$major.$minor"
+    }
+
+    companion object {
+        @JvmField
+        val ISSUE =
+            Issue.create(
+                id = "ProtoLayoutMinSchema",
+                briefDescription =
+                    "ProtoLayout feature is not guaranteed to be available " +
+                        "on the target device API.",
+                explanation =
+                    """
+            Using features that are not supported by an older ProtoLayout renderer/evaluator, can lead to unexpected rendering or invalid results (for expressions).
+
+            Each Wear OS platform version has a guaranteed minimum ProtoLayout schema version.
+            On API 33, all consumers for ProtoLayout support at least Schema version 1.2 (major=1, minor=200).
+            On API 34, all consumers for ProtoLayout support at least Schema version 1.3 (major=1, minor=300).
+
+            You can use those newer features through conditional Android API checks, or by increasing the minSdk for your project.
+            You can also annotate your methods with @RequiresApi or @RequiresSchemaAnnotation if you know they require the
+            corresponding version.
+            Note that @RequiresSchemaVersion annotation on classes are mostly ignored (except for Builder classes).
+            """,
+                category = Category.CORRECTNESS,
+                priority = 3,
+                severity = Severity.ERROR,
+                androidSpecific = true,
+                implementation =
+                    Implementation(ProtoLayoutMinSchemaDetector::class.java, Scope.JAVA_FILE_SCOPE)
+            )
+
+        const val REQUIRES_SCHEMA_ANNOTATION =
+            "androidx.wear.protolayout.expression.RequiresSchemaVersion"
+    }
+}
diff --git a/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/SdkApiChecks.kt b/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/SdkApiChecks.kt
new file mode 100644
index 0000000..fce5ed8
--- /dev/null
+++ b/wear/protolayout/protolayout-lint/src/main/java/androidx/wear/protolayout/lint/SdkApiChecks.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.wear.protolayout.lint
+
+import com.android.tools.lint.client.api.JavaEvaluator
+import com.android.tools.lint.detector.api.ApiConstraint
+import com.android.tools.lint.detector.api.VersionChecks.Companion.getTargetApiAnnotation
+import org.jetbrains.uast.UElement
+
+/**
+ * Returns true if the element or one of its containing elements has an annotation that satisfies
+ * the [atLeast] constraint.
+ */
+internal fun hasAtLeastTargetApiAnnotation(
+    evaluator: JavaEvaluator,
+    element: UElement?,
+    atLeast: ApiConstraint
+): Boolean {
+    var curr = element ?: return false
+    while (true) {
+        val (outer, target) = getTargetApiAnnotation(evaluator, curr)
+        if (target != null && target.isAtLeast(atLeast)) {
+            return true
+        }
+        curr = outer?.uastParent?.uastParent ?: return false
+    }
+}
diff --git a/wear/protolayout/protolayout-lint/src/test/java/ProtoLayoutMinSchemaDetectorTest.kt b/wear/protolayout/protolayout-lint/src/test/java/ProtoLayoutMinSchemaDetectorTest.kt
new file mode 100644
index 0000000..dc2e8b6
--- /dev/null
+++ b/wear/protolayout/protolayout-lint/src/test/java/ProtoLayoutMinSchemaDetectorTest.kt
@@ -0,0 +1,418 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("UnstableApiUsage")
+
+package androidx.wear.protolayout.lint
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class ProtoLayoutMinSchemaDetectorTest : LintDetectorTest() {
+    override fun getDetector() = ProtoLayoutMinSchemaDetector()
+
+    override fun getIssues() = mutableListOf(ProtoLayoutMinSchemaDetector.ISSUE)
+
+    private val requiresSchemaAnnotationStub =
+        java(
+            """
+            package androidx.wear.protolayout.expression;
+
+            @Retention(CLASS)
+            @Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
+            public @interface RequiresSchemaVersion {
+                int major();
+                int minor();
+            }
+        """
+                .trimIndent()
+        )
+    private val requiresApiAnnotationStub =
+        kotlin(
+            """
+            package androidx.annotation
+            @Retention(AnnotationRetention.BINARY)
+            @Target(
+                AnnotationTarget.ANNOTATION_CLASS,
+                AnnotationTarget.CLASS,
+                AnnotationTarget.FUNCTION,
+                AnnotationTarget.PROPERTY_GETTER,
+                AnnotationTarget.PROPERTY_SETTER,
+                AnnotationTarget.CONSTRUCTOR,
+                AnnotationTarget.FIELD,
+                AnnotationTarget.FILE
+            )
+            public actual annotation class RequiresApi(
+                val value: Int = 1,
+                val api: Int = 1
+            )
+            """
+                .trimIndent()
+        )
+
+    @Test
+    fun `calling V1_0 API doesn't`() {
+        lint()
+            .files(
+                requiresSchemaAnnotationStub,
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            @RequiresSchemaVersion(major=1, minor=0)
+            class WithAnnotation {
+              fun unAnnotatedMethod(){}
+            }
+                """
+                    )
+                    .indented(),
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            class Bar {
+              @RequiresSchemaVersion(major=1, minor=0)
+              fun bar() {}
+
+              fun baz() { bar() }
+            }
+        """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun `calling V1_2 API requires SDK version check`() {
+        lint()
+            .files(
+                requiresSchemaAnnotationStub,
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            @RequiresSchemaVersion(major=1, minor=200)
+            class WithAnnotation {
+              fun unAnnotatedMethod(){}
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun annotatedMethod(){}
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun unreferencedMethod(){}
+
+              companion object {
+                @RequiresSchemaVersion(major=1, minor=200)
+                const val ANNOTATED_CONST = 10
+              }
+            }
+                """
+                    )
+                    .indented(),
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            class Bar {
+              private val withAnnotation = WithAnnotation()
+              private val fieldAssignment = withAnnotation.annotatedMethod()
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun bar() {}
+
+              fun baz() {
+                bar()
+                withAnnotation.unAnnotatedMethod()
+                withAnnotation.annotatedMethod()
+                //TODO: b/308552481 - This should fail
+                val b = withAnnotation.ANNOTATED_CONST
+              }
+            }
+        """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expect(
+                """
+src/foo/Bar.kt:6: Error: This API is not guaranteed to be available on the device (requires schema 1.200). [ProtoLayoutMinSchema]
+  private val fieldAssignment = withAnnotation.annotatedMethod()
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src/foo/Bar.kt:12: Error: This API is not guaranteed to be available on the device (requires schema 1.200). [ProtoLayoutMinSchema]
+    bar()
+    ~~~~~
+src/foo/Bar.kt:14: Error: This API is not guaranteed to be available on the device (requires schema 1.200). [ProtoLayoutMinSchema]
+    withAnnotation.annotatedMethod()
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3 errors, 0 warnings
+            """
+                    .trimIndent()
+            )
+
+        lint()
+            .files(
+                requiresSchemaAnnotationStub,
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            @RequiresSchemaVersion(major=1, minor=200)
+            class WithAnnotation {
+              fun unAnnotatedMethod(){}
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun annotatedMethod(){}
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun unreferencedMethod(){}
+            }
+                """
+                    )
+                    .indented(),
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+            import android.os.Build
+
+            class Bar {
+              private val withAnnotation = WithAnnotation()
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun bar() {}
+
+              fun baz() {
+                if (Build.VERSION.SDK_INT >= 33) {
+                  bar()
+                  withAnnotation.unAnnotatedMethod()
+                  withAnnotation.annotatedMethod()
+                }
+              }
+            }
+        """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun `calling V1_2 API requires SDK version check (Java)`() {
+        lint()
+            .files(
+                requiresSchemaAnnotationStub,
+                java(
+                        """
+            package foo;
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion;
+
+            class Bar {
+              @RequiresSchemaVersion(major=1, minor=200)
+              public static final int ANNOTATED_CONSTANT = 10;
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              void bar() {}
+
+              void baz() {
+                bar();
+                // TODO: b/308552481: This should fail
+                int t = ANNOTATED_CONSTANT;
+              }
+            }
+        """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expect(
+                """
+src/foo/Bar.java:12: Error: This API is not guaranteed to be available on the device (requires schema 1.200). [ProtoLayoutMinSchema]
+    bar();
+    ~~~~~
+1 errors, 0 warnings
+            """
+                    .trimIndent()
+            )
+
+        lint()
+            .files(
+                requiresSchemaAnnotationStub,
+                java(
+                        """
+            package foo;
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion;
+            import android.os.Build;
+
+            class Bar {
+              @RequiresSchemaVersion(major=1, minor=200)
+              void bar() {}
+
+              void baz() {
+                if (Build.VERSION.SDK_INT >= 33) {
+                  bar();
+                }
+              }
+            }
+        """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun `annotated call-site doesn't requires SDK version check`() {
+        lint()
+            .files(
+                requiresSchemaAnnotationStub,
+                requiresApiAnnotationStub,
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            class BarK {
+              @RequiresSchemaVersion(major=1, minor=200)
+              private val fieldAssignment = bar()
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun bar() = 1
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun baz2() { bar() }
+
+              @RequiresSchemaVersion(major=1, minor=300)
+              fun baz3() { bar() }
+            }
+            """
+                    )
+                    .indented(),
+                java(
+                        """
+            package foo;
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion;
+
+            class BarJ {
+              @RequiresSchemaVersion(major=1, minor=200)
+              private static final int fieldAssignment = bar();
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              public static int bar() { return 1;}
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              void baz2() { bar(); }
+
+              @RequiresSchemaVersion(major=1, minor=300)
+              void baz3() { bar(); }
+            }
+        """
+                    )
+                    .indented(),
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+            import androidx.annotation.RequiresApi
+
+            @RequiresApi(33)
+            class BazK {
+              private val fieldAssignment = bar()
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun bar() = 1
+
+              @RequiresApi(30)
+              fun baz2() { bar() }
+
+              @RequiresApi(34)
+              fun baz3() { BarJ.baz3() }
+            }
+            """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun `project with proper minSdk doesn't requires SDK version check`() {
+        lint()
+            .files(
+                manifest().minSdk(34),
+                requiresSchemaAnnotationStub,
+                kotlin(
+                        """
+            package foo
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion
+
+            class BarK {
+              @RequiresSchemaVersion(major=1, minor=200)
+              private val fieldAssignment = bar()
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun bar() = 1
+
+              @RequiresSchemaVersion(major=1, minor=200)
+              fun baz2() { bar() }
+
+              @RequiresSchemaVersion(major=1, minor=300)
+              fun baz3() { bar() }
+            }
+            """
+                    )
+                    .indented(),
+                java(
+                        """
+            package foo;
+            import androidx.wear.protolayout.expression.RequiresSchemaVersion;
+
+            class BarJ {
+              private static final int fieldAssignment = bar();
+
+              fun bar() {}
+
+              fun baz2() { bar(); }
+
+              fun baz3() { bar(); }
+            }
+        """
+                    )
+                    .indented()
+            )
+            .issues(ProtoLayoutMinSchemaDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/color.proto b/wear/protolayout/protolayout-proto/src/main/proto/color.proto
index ae81664..aff2220 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/color.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/color.proto
@@ -30,7 +30,10 @@
 
 // A color and an offset, determining a color position in a gradient.
 message ColorStop {
-  // The color for this stop.
+  // The color for this stop. Only opaque colors are supported. Any transparent
+  // colors will have their alpha component set to 0xFF (opaque).
+  //
+
   ColorProp color = 1;
 
   oneof optional_offset {
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
index 115c73d..96fc634 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
@@ -663,7 +663,11 @@
   StrokeCap value = 1;
 
   // The stroke cap's shadow. When set, the stroke cap will be drawn with a
-  // shadow, which allows it to be visible on top of other similarly colored elements.
+  // shadow, which allows it to be visible on top of other similarly colored
+  // elements.
+  //
+  // Only opaque colors are supported in ArcLine if a shadow is set. Any
+  // transparent colors will have their alpha component set to 0xFF (opaque).
   Shadow shadow = 2;
 }
 
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto b/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto
index 1d2a9b5..f771ea4 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto
@@ -190,18 +190,20 @@
   // underneath it.
   AnimatedVisibility content_update_animation = 7;
 
-  // Whether the attached element is hidden, or visible. If the element is
-  // hidden, then it will still consume space in the layout, but will not render
-  // any contents, nor will any children render any contents.
-  //
-  // Note that a hidden element also cannot be clickable (i.e. a Clickable
-  // modifier would be ignored).
-  //
-  // Defaults to false (i.e. not hidden).
+
+  // This field is deprecated and is only kept for backward compatibility.
   BoolProp hidden = 8;
 
   // The optional identifier for the layout element.
   string id = 9;
+
+  // Whether the attached element is visible, or hidden. If the element is
+  // hidden, then it will still consume space in the layout, but will not render
+  // any contents, nor will any children render any contents. Defaults to visible.
+  //
+  // Note that a hidden element also cannot be clickable (i.e. a Clickable
+  // modifier would be ignored).
+  BoolProp visible = 10;
 }
 
 // The content transition of an element. Any update to the element or its
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
index bf096bb..9df108f 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
@@ -195,6 +195,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.Future;
 import java.util.function.Consumer;
+import java.util.function.Function;
 
 /**
  * Renderer for ProtoLayout.
@@ -221,8 +222,7 @@
             Trigger.newBuilder().setOnLoadTrigger(OnLoadTrigger.getDefaultInstance()).build();
 
     /** The default minimal click target size, for meeting the accessibility requirement */
-    @VisibleForTesting
-    static final float DEFAULT_MIN_CLICKABLE_SIZE_DP = 48f;
+    @VisibleForTesting static final float DEFAULT_MIN_CLICKABLE_SIZE_DP = 48f;
 
     /**
      * Default maximum raw byte size for a bitmap drawable.
@@ -255,8 +255,7 @@
 
     private static final int TEXT_COLOR_DEFAULT = 0xFFFFFFFF;
     private static final int TEXT_MAX_LINES_DEFAULT = 1;
-    @VisibleForTesting
-    static final int TEXT_AUTOSIZES_LIMIT = 10;
+    @VisibleForTesting static final int TEXT_AUTOSIZES_LIMIT = 10;
     private static final int TEXT_MIN_LINES = 1;
 
     private static final ContainerDimension CONTAINER_DIMENSION_DEFAULT =
@@ -1179,9 +1178,7 @@
 
     private float toPx(SpProp spField) {
         return TypedValue.applyDimension(
-                COMPLEX_UNIT_SP,
-                spField.getValue(),
-                mUiContext.getResources().getDisplayMetrics());
+                COMPLEX_UNIT_SP, spField.getValue(), mUiContext.getResources().getDisplayMetrics());
     }
 
     private void applyFontStyle(
@@ -1210,10 +1207,10 @@
                 // value.
                 boolean atLeastOneCorrectSize =
                         sizes.stream()
-                                .mapToInt(sp -> (int) sp.getValue())
-                                .filter(sp -> sp > 0)
-                                .distinct()
-                                .count()
+                                        .mapToInt(sp -> (int) sp.getValue())
+                                        .filter(sp -> sp > 0)
+                                        .distinct()
+                                        .count()
                                 > 0;
 
                 if (atLeastOneCorrectSize) {
@@ -1244,7 +1241,9 @@
                 } else {
                     Log.w(
                             TAG,
-                            "More than " + TEXT_AUTOSIZES_LIMIT + " sizes has been added for the "
+                            "More than "
+                                    + TEXT_AUTOSIZES_LIMIT
+                                    + " sizes has been added for the "
                                     + "text autosizing. Ignoring all other sizes and using the last"
                                     + "one.");
                 }
@@ -1524,8 +1523,21 @@
             @NonNull Modifiers modifiers,
             @NonNull String posId,
             @NonNull Optional<ProtoLayoutDynamicDataPipeline.PipelineMaker> pipelineMaker) {
-        if (modifiers.hasHidden()) {
-            applyHidden(view, modifiers.getHidden(), posId, pipelineMaker);
+        if (modifiers.hasVisible()) {
+            applyVisible(
+                    view,
+                    modifiers.getVisible(),
+                    posId,
+                    pipelineMaker,
+                    visible -> visible ? VISIBLE : INVISIBLE);
+        } else if (modifiers.hasHidden()) {
+            // This is a deprecated field
+            applyVisible(
+                    view,
+                    modifiers.getHidden(),
+                    posId,
+                    pipelineMaker,
+                    hidden -> hidden ? INVISIBLE : VISIBLE);
         }
 
         if (modifiers.hasClickable()) {
@@ -1571,12 +1583,15 @@
         return view;
     }
 
-    private void applyHidden(
-            View view, BoolProp hidden, String posId,
-            Optional<ProtoLayoutDynamicDataPipeline.PipelineMaker> pipelineMaker) {
+    private void applyVisible(
+            View view,
+            BoolProp visible,
+            String posId,
+            Optional<ProtoLayoutDynamicDataPipeline.PipelineMaker> pipelineMaker,
+            Function<Boolean, Integer> toViewVisibility) {
         handleProp(
-                hidden,
-                hide -> view.setVisibility(hide ? INVISIBLE : VISIBLE),
+                visible,
+                visibility -> view.setVisibility(toViewVisibility.apply(visibility)),
                 posId,
                 pipelineMaker);
     }
@@ -1863,7 +1878,7 @@
                 return TruncateAt.MARQUEE;
             case TEXT_OVERFLOW_UNDEFINED:
             case UNRECOGNIZED:
-            // TODO(b/302531877): Implement ellipsize.
+                // TODO(b/302531877): Implement ellipsize.
             case TEXT_OVERFLOW_ELLIPSIZE:
                 return TEXT_OVERFLOW_DEFAULT;
         }
@@ -2126,11 +2141,7 @@
 
         View wrappedView =
                 applyModifiers(
-                        frame,
-                        /* wrapper= */ null,
-                        box.getModifiers(),
-                        boxPosId,
-                        pipelineMaker);
+                        frame, /* wrapper= */ null, box.getModifiers(), boxPosId, pipelineMaker);
 
         parentViewWrapper.maybeAddView(wrappedView, layoutParams);
 
@@ -2202,9 +2213,9 @@
                 updateLayoutParams(
                         parentViewWrapper.getParentProperties(),
                         layoutParams,
-                        // This doesn't copy layout constraint for dynamic fields. That is fine, because that
-                        // will be later applied to the wrapper, and this layoutParams would have dimension
-                        // reset and put into the pipeline.
+                        // This doesn't copy layout constraint for dynamic fields. That is fine,
+                        // because that will be later applied to the wrapper, and this layoutParams
+                        // would have dimension reset and put into the pipeline.
                         spacerDimensionToContainerDimension(spacer.getWidth()),
                         spacerDimensionToContainerDimension(spacer.getHeight()));
 
@@ -2247,13 +2258,17 @@
 
             int gravity =
                     (spacer.getWidth().hasLinearDimension()
-                            ? horizontalAlignmentToGravity(
-                            spacer.getWidth().getLinearDimension().getHorizontalAlignmentForLayout())
-                            : UNSET_MASK)
+                                    ? horizontalAlignmentToGravity(
+                                            spacer.getWidth()
+                                                    .getLinearDimension()
+                                                    .getHorizontalAlignmentForLayout())
+                                    : UNSET_MASK)
                             | (spacer.getHeight().hasLinearDimension()
-                            ? verticalAlignmentToGravity(
-                            spacer.getHeight().getLinearDimension().getVerticalAlignmentForLayout())
-                            : UNSET_MASK);
+                                    ? verticalAlignmentToGravity(
+                                            spacer.getHeight()
+                                                    .getLinearDimension()
+                                                    .getVerticalAlignmentForLayout())
+                                    : UNSET_MASK);
 
             // This layoutParams will override what we initially had and will be used for Spacer
             // itself. This means that the wrapper's layout params should follow the rules for
@@ -2341,7 +2356,8 @@
                 handleProp(
                         spacer.getWidth().getLinearDimension(),
                         width -> {
-                            // We still need to update layout params in case other dimension is expand, so 0 could
+                            // We still need to update layout params in case other dimension is
+                            // expand, so 0 could
                             // be miss interpreted.
                             LayoutParams lp = view.getLayoutParams();
                             if (lp == null) {
@@ -2360,8 +2376,8 @@
                 handleProp(
                         spacer.getHeight().getLinearDimension(),
                         height -> {
-                            // We still need to update layout params in case other dimension is expand, so 0 could
-                            // be miss interpreted.
+                            // We still need to update layout params in case other dimension is
+                            // expand, so 0 could be miss interpreted.
                             LayoutParams lp = view.getLayoutParams();
                             if (lp == null) {
                                 Log.e(TAG, "LayoutParams was null when updating spacer height");
@@ -2531,12 +2547,7 @@
         // Setting colours **must** go after setting the Text Appearance, otherwise it will get
         // immediately overridden.
         if (text.hasFontStyle()) {
-            applyFontStyle(
-                    text.getFontStyle(),
-                    textView,
-                    posId,
-                    pipelineMaker,
-                    isAutoSizeAllowed);
+            applyFontStyle(text.getFontStyle(), textView, posId, pipelineMaker, isAutoSizeAllowed);
         } else {
             applyFontStyle(
                     FontStyle.getDefaultInstance(),
@@ -2806,11 +2817,7 @@
         ratioViewWrapper.setAspectRatio(ratio);
         View wrappedImageView =
                 applyModifiers(
-                        imageView,
-                        ratioViewWrapper,
-                        image.getModifiers(),
-                        posId,
-                        pipelineMaker);
+                        imageView, ratioViewWrapper, image.getModifiers(), posId, pipelineMaker);
         ratioViewWrapper.addView(wrappedImageView);
 
         parentViewWrapper.maybeAddView(ratioViewWrapper, ratioWrapperLayoutParams);
@@ -3172,10 +3179,11 @@
                 Log.w(
                         TAG,
                         "Font size with multiple values has been used on Span Text. Ignoring "
-                        + "all size except the first one.");
+                                + "all size except the first one.");
             }
-            AbsoluteSizeSpan span = new AbsoluteSizeSpan(round(toPx(
-                    fontStyle.getSize(fontStyle.getSizeCount() - 1))));
+            AbsoluteSizeSpan span =
+                    new AbsoluteSizeSpan(
+                            round(toPx(fontStyle.getSize(fontStyle.getSizeCount() - 1))));
             builder.setSpan(span, start, end, Spanned.SPAN_MARK_MARK);
         }
 
@@ -3452,11 +3460,7 @@
 
         View wrappedView =
                 applyModifiers(
-                        tv,
-                        /* wrapper= */ null,
-                        spannable.getModifiers(),
-                        posId,
-                        pipelineMaker);
+                        tv, /* wrapper= */ null, spannable.getModifiers(), posId, pipelineMaker);
         parentViewWrapper.maybeAddView(wrappedView, layoutParams);
 
         return new InflatedView(
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineView.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineView.java
index 8e99e07..4089fc5 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineView.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineView.java
@@ -73,6 +73,7 @@
     private static final float DEFAULT_LINE_SWEEP_ANGLE_DEGREES = 0;
     private static final int DEFAULT_LINE_STROKE_CAP = Cap.ROUND.ordinal();
     @ColorInt private static final int DEFAULT_COLOR = 0xFFFFFFFF;
+    private static final int FULLY_OPAQUE_COLOR_MASK = 0xFF000000;
 
     /**
      * The base angle for drawings. The zero angle in Android corresponds to the "3 o clock"
@@ -257,6 +258,10 @@
 
     /** Sets the color of this arc, in ARGB format. */
     public void setColor(@ColorInt int color) {
+        // Force color to be fully opaque if stroke cap shadow is used.
+        if (mCapShadow != null) {
+            color = makeOpaque(color);
+        }
         this.mColor = color;
         updateArcDrawable();
         invalidate();
@@ -290,6 +295,8 @@
     /** Sets the parameters for the stroke cap shadow. */
     public void setStrokeCapShadow(float blurRadius, int color) {
         this.mCapShadow = new StrokeCapShadow(blurRadius, color);
+        // Re-set color.
+        this.setColor(mColor);
     }
 
     /** Clears the stroke cap shadow. */
@@ -352,6 +359,7 @@
 
         @NonNull private final List<AngularColorStop> colorStops;
 
+        /** Constructor. All colors will have their alpha channel set to 0xFF (opaque). */
         SweepGradientHelper(@NonNull ColorProto.SweepGradient sweepGradProto) {
             int numColors = sweepGradProto.getColorStopsCount();
             if (numColors < MIN_COLOR_STOPS || numColors > MAX_COLOR_STOPS) {
@@ -383,7 +391,8 @@
                                 ? stop.getOffset().getValue()
                                 : (float) i / (numColors - 1);
                 float gradAngle = gradStartAngle + offset * (gradEndAngle - gradStartAngle);
-                colorStops.add(new AngularColorStop(gradAngle, stop.getColor().getArgb()));
+                colorStops.add(
+                        new AngularColorStop(gradAngle, makeOpaque(stop.getColor().getArgb())));
             }
 
             if (offsetsRequired) {
@@ -723,6 +732,8 @@
      * elements are drawn first).
      *
      * <p>All other lower layers of the line are not visible so they are not drawn.
+     *
+     * <p>For a more detail explanation of the drawing method, see go/protolayout-arcline.
      */
     static class ArcDrawableImpl implements ArcDrawable {
         // The list of segments that compose the ArcDrawable, in the order that they should be
@@ -909,4 +920,9 @@
             this.mColor = color;
         }
     }
+
+    /** Changes the alpha channel of the color to 0xFF (fully opaque). */
+    private static int makeOpaque(int color) {
+        return color | FULLY_OPAQUE_COLOR_MASK;
+    }
 }
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
index e630c9f..0a66ff6 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
@@ -4782,6 +4782,71 @@
         assertThat(secondImage.getLeft()).isEqualTo(secondImageLeft);
     }
 
+    @Test   public void inflate_box_withVisibleModifier() {
+        final String protoResId = "android";
+        final String boolKey = "bool-key";
+
+        LayoutElement image = buildImage(protoResId, 30, 30);
+
+        BoolProp.Builder stateBoolPropBuilder =
+                BoolProp.newBuilder()
+                        .setValue(true)
+                        .setDynamicValue(
+                                DynamicBool.newBuilder()
+                                        .setStateSource(
+                                                StateBoolSource.newBuilder()
+                                                        .setSourceKey(boolKey)));
+        BoolProp.Builder alwaysTrueBoolPropBuilder =
+                BoolProp.newBuilder()
+                        .setValue(true)
+                        .setDynamicValue(
+                                DynamicBool.newBuilder()
+                                        .setFixed(FixedBool.newBuilder().setValue(true)));
+        LayoutElement.Builder boxBuilder =
+                LayoutElement.newBuilder()
+                        .setBox(
+                                Box.newBuilder()
+                                        .addContents(image)
+                                        .setModifiers(
+                                                Modifiers.newBuilder()
+                                                        .setVisible(stateBoolPropBuilder)
+                                                        // This should be ignored
+                                                        .setHidden(alwaysTrueBoolPropBuilder)));
+        LayoutElement root =
+                LayoutElement.newBuilder()
+                        .setRow(Row.newBuilder().addContents(boxBuilder).addContents(image))
+                        .build();
+
+        FrameLayout layout = renderer(fingerprintedLayout(root)).inflate();
+
+        // There should be a child ViewGroup which is a LinearLayout.
+        assertThat(layout.getChildAt(0)).isInstanceOf(ViewGroup.class);
+        ViewGroup firstChild = (ViewGroup) layout.getChildAt(0);
+        ViewGroup box = (ViewGroup) firstChild.getChildAt(0);
+        ViewGroup secondImage = (ViewGroup) firstChild.getChildAt(1);
+
+        assertThat(box.getWidth()).isGreaterThan(0);
+        assertThat(box.getVisibility()).isEqualTo(VISIBLE);
+
+        // The second image should start after the hidden (but not gone) box.
+        int secondImageLeft = secondImage.getLeft();
+        assertThat(secondImageLeft).isEqualTo(box.getWidth());
+        assertThat(box.getWidth()).isEqualTo(secondImage.getWidth());
+
+        // Try to hide the box.
+        mStateStore.setAppStateEntryValuesProto(
+                ImmutableMap.of(
+                        new AppDataKey<DynamicBuilders.DynamicBool>(boolKey),
+                        DynamicDataValue.newBuilder()
+                                .setBoolVal(FixedBool.newBuilder().setValue(false))
+                                .build()));
+
+        // The box should be hidden but still take some space (as it wraps around its inner image)
+        assertThat(box.getVisibility()).isEqualTo(INVISIBLE);
+        // The second image shouldn't move around.
+        assertThat(secondImage.getLeft()).isEqualTo(secondImageLeft);
+    }
+
     @Test
     public void enterTransition_noQuota_notPlayed() throws Exception {
         Renderer renderer =
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineViewTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineViewTest.java
index 72db5aa..532bb8e 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineViewTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/WearCurvedLineViewTest.java
@@ -180,6 +180,34 @@
         assertThat(rotatedMatrix).isEqualTo(generatedMatrix);
     }
 
+    @Test
+    public void sweepGradientHelper_colorSetToOpaque() {
+        final int color0 = 0x12666666;
+        final int color90 = 0xFD123456;
+        final int color180 = 0xFF654321;
+        final int noAlphaMask = 0x00FFFFFF;
+        SweepGradient sgProto =
+                SweepGradient.newBuilder()
+                        .addColorStops(colorStop(color0))
+                        .addColorStops(colorStop(color90))
+                        .addColorStops(colorStop(color180))
+                        .setEndAngle(degrees(180f))
+                        .build();
+        SweepGradientHelper sgHelper = new SweepGradientHelper(sgProto);
+
+        int resolvedColor0 = sgHelper.getColor(0f);
+        expect.that(Color.alpha(resolvedColor0)).isEqualTo(0xFF);
+        expect.that(resolvedColor0 & noAlphaMask).isEqualTo(color0 & noAlphaMask);
+
+        int resolvedColor90 = sgHelper.getColor(90f);
+        expect.that(Color.alpha(resolvedColor90)).isEqualTo(0xFF);
+        expect.that(resolvedColor90 & noAlphaMask).isEqualTo(color90 & noAlphaMask);
+
+        int resolvedColor180 = sgHelper.getColor(180f);
+        expect.that(Color.alpha(resolvedColor180)).isEqualTo(0xFF);
+        expect.that(resolvedColor180 & noAlphaMask).isEqualTo(color180 & noAlphaMask);
+    }
+
     /** Gradient with colors [Red, Blue, Green] at offsets [0, 0.5, 1] and given angles. */
     private SweepGradient basicSweepGradientProto(float startAngle, float endAngle) {
         return SweepGradient.newBuilder()
diff --git a/wear/protolayout/protolayout/api/current.txt b/wear/protolayout/protolayout/api/current.txt
index d43713d..a4ba9ae 100644
--- a/wear/protolayout/protolayout/api/current.txt
+++ b/wear/protolayout/protolayout/api/current.txt
@@ -15,9 +15,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidActivity {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getClassName();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getPackageName();
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
   }
 
   public static final class ActionBuilders.AndroidActivity.Builder {
@@ -29,7 +29,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public boolean getValue();
+    method public boolean getValue();
   }
 
   public static final class ActionBuilders.AndroidBooleanExtra.Builder {
@@ -39,7 +39,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public double getValue();
+    method public double getValue();
   }
 
   public static final class ActionBuilders.AndroidDoubleExtra.Builder {
@@ -52,7 +52,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class ActionBuilders.AndroidIntExtra.Builder {
@@ -62,7 +62,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public long getValue();
+    method public long getValue();
   }
 
   public static final class ActionBuilders.AndroidLongExtra.Builder {
@@ -72,7 +72,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getValue();
+    method public String getValue();
   }
 
   public static final class ActionBuilders.AndroidStringExtra.Builder {
@@ -82,7 +82,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.LaunchAction implements androidx.wear.protolayout.ActionBuilders.Action {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ActionBuilders.AndroidActivity? getAndroidActivity();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity? getAndroidActivity();
   }
 
   public static final class ActionBuilders.LaunchAction.Builder {
@@ -92,7 +92,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.LoadAction implements androidx.wear.protolayout.ActionBuilders.Action {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.StateBuilders.State? getRequestState();
+    method public androidx.wear.protolayout.StateBuilders.State? getRequestState();
   }
 
   public static final class ActionBuilders.LoadAction.Builder {
@@ -109,8 +109,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ColorBuilders.ColorProp {
-    method @ColorInt @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getArgb();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor? getDynamicValue();
+    method @ColorInt public int getArgb();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor? getDynamicValue();
   }
 
   public static final class ColorBuilders.ColorProp.Builder {
@@ -124,14 +124,14 @@
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static final class ColorBuilders.ColorStop {
     ctor @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public ColorBuilders.ColorStop(androidx.wear.protolayout.ColorBuilders.ColorProp);
     ctor @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public ColorBuilders.ColorStop(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.TypeBuilders.FloatProp);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.TypeBuilders.FloatProp? getOffset();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp? getOffset();
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static final class ColorBuilders.SweepGradient implements androidx.wear.protolayout.ColorBuilders.Brush {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public java.util.List<androidx.wear.protolayout.ColorBuilders.ColorStop!> getColorStops();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DegreesProp getEndAngle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DegreesProp getStartAngle();
+    method public java.util.List<androidx.wear.protolayout.ColorBuilders.ColorStop!> getColorStops();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getEndAngle();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getStartAngle();
   }
 
   public static final class ColorBuilders.SweepGradient.Builder {
@@ -150,7 +150,7 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DeviceParametersBuilders.Capabilities {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public long getMinimumFreshnessLimitMillis();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public long getMinimumFreshnessLimitMillis();
   }
 
   public static final class DeviceParametersBuilders.Capabilities.Builder {
@@ -160,14 +160,14 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DeviceParametersBuilders.DeviceParameters {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities? getCapabilities();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getDevicePlatform();
-    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getFontScale();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo getRendererSchemaVersion();
-    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getScreenDensity();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getScreenHeightDp();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getScreenShape();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getScreenWidthDp();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities? getCapabilities();
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getFontScale();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo getRendererSchemaVersion();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
   }
 
   public static final class DeviceParametersBuilders.DeviceParameters.Builder {
@@ -195,8 +195,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DimensionBuilders.AngularLayoutConstraint {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAngularAlignment();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getValue();
+    method public int getAngularAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
   }
 
   public static final class DimensionBuilders.AngularLayoutConstraint.Builder {
@@ -209,8 +209,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.DegreesProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
   }
 
   public static final class DimensionBuilders.DegreesProp.Builder {
@@ -222,8 +222,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.DpProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ExtensionDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension androidx.wear.protolayout.DimensionBuilders.SpacerDimension {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
   }
 
   public static final class DimensionBuilders.DpProp.Builder {
@@ -235,7 +235,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.EmProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public float getValue();
   }
 
   public static final class DimensionBuilders.EmProp.Builder {
@@ -245,7 +245,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension androidx.wear.protolayout.DimensionBuilders.SpacerDimension {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TypeBuilders.FloatProp? getLayoutWeight();
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp? getLayoutWeight();
   }
 
   public static final class DimensionBuilders.ExpandedDimensionProp.Builder {
@@ -258,8 +258,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DimensionBuilders.HorizontalLayoutConstraint {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getHorizontalAlignment();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getValue();
+    method public int getHorizontalAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
   }
 
   public static final class DimensionBuilders.HorizontalLayoutConstraint.Builder {
@@ -272,8 +272,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ImageDimension {
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getAspectRatioHeight();
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getAspectRatioWidth();
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
   }
 
   public static final class DimensionBuilders.ProportionalDimensionProp.Builder {
@@ -284,7 +284,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.SpProp {
-    method @Dimension(unit=androidx.annotation.Dimension.SP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
   }
 
   public static final class DimensionBuilders.SpProp.Builder {
@@ -297,8 +297,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DimensionBuilders.VerticalLayoutConstraint {
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getVerticalAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+    method public int getVerticalAlignment();
   }
 
   public static final class DimensionBuilders.VerticalLayoutConstraint.Builder {
@@ -308,7 +308,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.DpProp? getMinimumSize();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getMinimumSize();
   }
 
   public static final class DimensionBuilders.WrappedDimensionProp.Builder {
@@ -366,7 +366,7 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class LayoutElementBuilders.AndroidTextStyle {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public boolean getExcludeFontPadding();
+    method public boolean getExcludeFontPadding();
   }
 
   public static final class LayoutElementBuilders.AndroidTextStyle.Builder {
@@ -376,11 +376,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Arc implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getAnchorAngle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
   }
 
   public static final class LayoutElementBuilders.Arc.Builder {
@@ -396,8 +396,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getRotateContents();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRotateContents();
   }
 
   public static final class LayoutElementBuilders.ArcAdapter.Builder {
@@ -409,7 +409,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcAnchorTypeProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
@@ -422,13 +422,13 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcLine implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ColorBuilders.Brush? getBrush();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicLength();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp? getStrokeCap();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+    method public androidx.wear.protolayout.ColorBuilders.Brush? getBrush();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicLength();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp? getStrokeCap();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
   }
 
   public static final class LayoutElementBuilders.ArcLine.Builder {
@@ -445,9 +445,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
   }
 
   public static final class LayoutElementBuilders.ArcSpacer.Builder {
@@ -459,9 +459,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcText implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
   }
 
   public static final class LayoutElementBuilders.ArcText.Builder {
@@ -474,12 +474,12 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Box implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Box.Builder {
@@ -496,7 +496,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ColorFilter {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getTint();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getTint();
   }
 
   public static final class LayoutElementBuilders.ColorFilter.Builder {
@@ -506,11 +506,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Column implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Column.Builder {
@@ -525,7 +525,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ContentScaleModeProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
@@ -535,10 +535,10 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ExperimentalProtoLayoutExtensionApi @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class LayoutElementBuilders.ExtensionLayoutElement implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public String getExtensionId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public byte[] getPayload();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getWidth();
+    method public String getExtensionId();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getHeight();
+    method public byte[] getPayload();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.ExtensionLayoutElement.Builder {
@@ -551,14 +551,14 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.FontStyle {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getItalic();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.EmProp? getLetterSpacing();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpProp? getSize();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public java.util.List<androidx.wear.protolayout.DimensionBuilders.SpProp!> getSizes();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getUnderline();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp? getVariant();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp? getWeight();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getSize();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public java.util.List<androidx.wear.protolayout.DimensionBuilders.SpProp!> getSizes();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getUnderline();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp? getVariant();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp? getWeight();
   }
 
   public static final class LayoutElementBuilders.FontStyle.Builder {
@@ -569,7 +569,7 @@
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.protolayout.DimensionBuilders.EmProp);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.protolayout.DimensionBuilders.SpProp);
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSizes(androidx.wear.protolayout.DimensionBuilders.SpProp!...);
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSizes(@Dimension(unit=androidx.annotation.Dimension.SP) @IntRange(from=1) int...);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.protolayout.TypeBuilders.BoolProp);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp);
@@ -593,7 +593,7 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.FontVariantProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.FontVariantProp.Builder {
@@ -603,7 +603,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.FontWeightProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.FontWeightProp.Builder {
@@ -613,7 +613,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.HorizontalAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
@@ -623,12 +623,12 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Image implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter? getColorFilter();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getWidth();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter? getColorFilter();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Image.Builder {
@@ -647,7 +647,7 @@
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Layout {
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.LayoutElementBuilders.Layout? fromByteArray(byte[]);
     method public static androidx.wear.protolayout.LayoutElementBuilders.Layout fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getRoot();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getRoot();
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public byte[] toByteArray();
   }
 
@@ -661,11 +661,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Row implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Row.Builder {
@@ -680,11 +680,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Spacer implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint? getLayoutConstraintsForDynamicHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint? getLayoutConstraintsForDynamicWidth();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getWidth();
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint? getLayoutConstraintsForDynamicHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint? getLayoutConstraintsForDynamicWidth();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Spacer.Builder {
@@ -701,11 +701,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.SpanImage implements androidx.wear.protolayout.LayoutElementBuilders.Span {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
   }
 
   public static final class LayoutElementBuilders.SpanImage.Builder {
@@ -721,10 +721,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.SpanText implements androidx.wear.protolayout.LayoutElementBuilders.Span {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
   }
 
   public static final class LayoutElementBuilders.SpanText.Builder {
@@ -738,7 +738,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
@@ -748,13 +748,13 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Spannable implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
-    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getMarqueeIterations();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.Span!> getSpans();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.Span!> getSpans();
   }
 
   public static final class LayoutElementBuilders.Spannable.Builder {
@@ -773,8 +773,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class LayoutElementBuilders.StrokeCapProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ModifiersBuilders.Shadow? getShadow();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getValue();
+    method public androidx.wear.protolayout.ModifiersBuilders.Shadow? getShadow();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.StrokeCapProp.Builder {
@@ -785,16 +785,16 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Text implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint? getLayoutConstraintsForDynamicText();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
-    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getMarqueeIterations();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint? getLayoutConstraintsForDynamicText();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
   }
 
   public static final class LayoutElementBuilders.Text.Builder {
@@ -817,7 +817,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.TextAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
@@ -827,7 +827,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.TextOverflowProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.TextOverflowProp.Builder {
@@ -837,7 +837,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.VerticalAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
@@ -864,8 +864,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.AnimatedVisibility {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.EnterTransition? getEnterTransition();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.ExitTransition? getExitTransition();
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition? getEnterTransition();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition? getExitTransition();
   }
 
   public static final class ModifiersBuilders.AnimatedVisibility.Builder {
@@ -876,8 +876,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.ArcModifiers {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
   }
 
   public static final class ModifiersBuilders.ArcModifiers.Builder {
@@ -888,8 +888,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Background {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Corner? getCorner();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner? getCorner();
   }
 
   public static final class ModifiersBuilders.Background.Builder {
@@ -900,8 +900,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Border {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
   }
 
   public static final class ModifiersBuilders.Border.Builder {
@@ -912,10 +912,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Clickable {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableWidth();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ActionBuilders.Action? getOnClick();
+    method public String getId();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableWidth();
+    method public androidx.wear.protolayout.ActionBuilders.Action? getOnClick();
   }
 
   public static final class ModifiersBuilders.Clickable.Builder {
@@ -928,7 +928,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Corner {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getRadius();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getRadius();
   }
 
   public static final class ModifiersBuilders.Corner.Builder {
@@ -938,16 +938,16 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.DefaultContentTransitions {
-    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeIn();
-    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeInSlideIn(@SuppressCompatibility int);
-    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOut();
-    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOutSlideOut(@SuppressCompatibility int);
-    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition slideIn(@SuppressCompatibility int);
-    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition slideOut(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeIn();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeInSlideIn(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOut();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOutSlideOut(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition slideIn(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition slideOut(@SuppressCompatibility int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.ElementMetadata {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public byte[] getTagData();
+    method public byte[] getTagData();
   }
 
   public static final class ModifiersBuilders.ElementMetadata.Builder {
@@ -957,8 +957,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.EnterTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition? getFadeIn();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition? getSlideIn();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition? getFadeIn();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition? getSlideIn();
   }
 
   public static final class ModifiersBuilders.EnterTransition.Builder {
@@ -969,8 +969,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.ExitTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition? getFadeOut();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition? getSlideOut();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition? getFadeOut();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition? getSlideOut();
   }
 
   public static final class ModifiersBuilders.ExitTransition.Builder {
@@ -981,8 +981,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.FadeInTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @FloatRange(from=0.0, to=1.0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getInitialAlpha();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getInitialAlpha();
   }
 
   public static final class ModifiersBuilders.FadeInTransition.Builder {
@@ -993,26 +993,26 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.FadeOutTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @FloatRange(from=0.0, to=1.0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getTargetAlpha();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getTargetAlpha();
   }
 
   public static final class ModifiersBuilders.FadeOutTransition.Builder {
     ctor public ModifiersBuilders.FadeOutTransition.Builder();
     method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition build();
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setTargetAlpha(@FloatRange(from=0.0, to=1.0) float);
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setTargetAlpha(@FloatRange(from=0.0, to=1.0) float);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Modifiers {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Background? getBackground();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Border? getBorder();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility? getContentUpdateAnimation();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.TypeBuilders.BoolProp? getHidden();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata? getMetadata();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Padding? getPadding();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+    method public androidx.wear.protolayout.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility? getContentUpdateAnimation();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata? getMetadata();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.TypeBuilders.BoolProp isVisible();
   }
 
   public static final class ModifiersBuilders.Modifiers.Builder {
@@ -1022,18 +1022,18 @@
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.protolayout.ModifiersBuilders.Border);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setContentUpdateAnimation(androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility);
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setHidden(androidx.wear.protolayout.TypeBuilders.BoolProp);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setMetadata(androidx.wear.protolayout.ModifiersBuilders.ElementMetadata);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.protolayout.ModifiersBuilders.Padding);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.protolayout.ModifiersBuilders.Semantics);
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setVisible(androidx.wear.protolayout.TypeBuilders.BoolProp);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Padding {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getBottom();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getEnd();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getRtlAware();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getStart();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getTop();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getTop();
   }
 
   public static final class ModifiersBuilders.Padding.Builder {
@@ -1049,9 +1049,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Semantics {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getRole();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TypeBuilders.StringProp? getStateDescription();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public int getRole();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getStateDescription();
   }
 
   public static final class ModifiersBuilders.Semantics.Builder {
@@ -1064,8 +1064,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static final class ModifiersBuilders.Shadow {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DpProp getBlurRadius();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getBlurRadius();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
   }
 
   public static final class ModifiersBuilders.Shadow.Builder {
@@ -1079,9 +1079,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.SlideInTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getDirection();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getInitialSlideBound();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @SuppressCompatibility public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getInitialSlideBound();
   }
 
   public static final class ModifiersBuilders.SlideInTransition.Builder {
@@ -1093,9 +1093,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.SlideOutTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getDirection();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getTargetSlideBound();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @SuppressCompatibility public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getTargetSlideBound();
   }
 
   public static final class ModifiersBuilders.SlideOutTransition.Builder {
@@ -1103,11 +1103,11 @@
     method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition build();
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setDirection(@SuppressCompatibility int);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setTargetSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setTargetSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.SlideParentBound implements androidx.wear.protolayout.ModifiersBuilders.SlideBound {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getSnapTo();
+    method @SuppressCompatibility public int getSnapTo();
   }
 
   public static final class ModifiersBuilders.SlideParentBound.Builder {
@@ -1117,7 +1117,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.SpanModifiers {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
   }
 
   public static final class ModifiersBuilders.SpanModifiers.Builder {
@@ -1135,9 +1135,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAnimatedImageFormat();
-    method @DrawableRes @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getResourceId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
   }
 
   public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
@@ -1149,7 +1149,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.AndroidImageResourceByResId {
-    method @DrawableRes @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getResourceId();
+    method @DrawableRes public int getResourceId();
   }
 
   public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
@@ -1159,9 +1159,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAnimatedImageFormat();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
-    method @DrawableRes @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getResourceId();
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
   }
 
   public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
@@ -1173,10 +1173,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.ImageResource {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
   }
 
   public static final class ResourceBuilders.ImageResource.Builder {
@@ -1189,10 +1189,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.InlineImageResource {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public byte[] getData();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getFormat();
-    method @Dimension(unit=androidx.annotation.Dimension.PX) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getHeightPx();
-    method @Dimension(unit=androidx.annotation.Dimension.PX) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getWidthPx();
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
   }
 
   public static final class ResourceBuilders.InlineImageResource.Builder {
@@ -1205,8 +1205,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.Resources {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getVersion();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
   }
 
   public static final class ResourceBuilders.Resources.Builder {
@@ -1220,8 +1220,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class StateBuilders.State {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getKeyToValueMapping();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getLastClickableId();
+    method public java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getKeyToValueMapping();
+    method public String getLastClickableId();
     method public static int getMaxStateEntryCount();
   }
 
@@ -1235,8 +1235,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TimelineBuilders.TimeInterval {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public long getEndMillis();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public long getStartMillis();
+    method public long getEndMillis();
+    method public long getStartMillis();
   }
 
   public static final class TimelineBuilders.TimeInterval.Builder {
@@ -1248,7 +1248,7 @@
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TimelineBuilders.Timeline {
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static androidx.wear.protolayout.TimelineBuilders.Timeline fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+    method public java.util.List<androidx.wear.protolayout.TimelineBuilders.TimelineEntry!> getTimelineEntries();
   }
 
   public static final class TimelineBuilders.Timeline.Builder {
@@ -1259,8 +1259,8 @@
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TimelineBuilders.TimelineEntry {
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static androidx.wear.protolayout.TimelineBuilders.TimelineEntry fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.Layout? getLayout();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TimelineBuilders.TimeInterval? getValidity();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval? getValidity();
   }
 
   public static final class TimelineBuilders.TimelineEntry.Builder {
@@ -1271,7 +1271,7 @@
   }
 
   public final class TriggerBuilders {
-    method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnLoadTrigger();
   }
 
@@ -1282,8 +1282,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.BoolProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public boolean getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getDynamicValue();
+    method public boolean getValue();
   }
 
   public static final class TypeBuilders.BoolProp.Builder {
@@ -1295,8 +1295,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.FloatProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
   }
 
   public static final class TypeBuilders.FloatProp.Builder {
@@ -1308,7 +1308,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.Int32Prop {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class TypeBuilders.Int32Prop.Builder {
@@ -1318,8 +1318,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class TypeBuilders.StringLayoutConstraint {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public String getPatternForLayout();
+    method public int getAlignment();
+    method public String getPatternForLayout();
   }
 
   public static final class TypeBuilders.StringLayoutConstraint.Builder {
@@ -1329,8 +1329,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.StringProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicString? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicString? getDynamicValue();
+    method public String getValue();
   }
 
   public static final class TypeBuilders.StringProp.Builder {
diff --git a/wear/protolayout/protolayout/api/restricted_current.txt b/wear/protolayout/protolayout/api/restricted_current.txt
index d43713d..a4ba9ae 100644
--- a/wear/protolayout/protolayout/api/restricted_current.txt
+++ b/wear/protolayout/protolayout/api/restricted_current.txt
@@ -15,9 +15,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidActivity {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getClassName();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getPackageName();
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
   }
 
   public static final class ActionBuilders.AndroidActivity.Builder {
@@ -29,7 +29,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public boolean getValue();
+    method public boolean getValue();
   }
 
   public static final class ActionBuilders.AndroidBooleanExtra.Builder {
@@ -39,7 +39,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public double getValue();
+    method public double getValue();
   }
 
   public static final class ActionBuilders.AndroidDoubleExtra.Builder {
@@ -52,7 +52,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class ActionBuilders.AndroidIntExtra.Builder {
@@ -62,7 +62,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public long getValue();
+    method public long getValue();
   }
 
   public static final class ActionBuilders.AndroidLongExtra.Builder {
@@ -72,7 +72,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getValue();
+    method public String getValue();
   }
 
   public static final class ActionBuilders.AndroidStringExtra.Builder {
@@ -82,7 +82,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.LaunchAction implements androidx.wear.protolayout.ActionBuilders.Action {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ActionBuilders.AndroidActivity? getAndroidActivity();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity? getAndroidActivity();
   }
 
   public static final class ActionBuilders.LaunchAction.Builder {
@@ -92,7 +92,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ActionBuilders.LoadAction implements androidx.wear.protolayout.ActionBuilders.Action {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.StateBuilders.State? getRequestState();
+    method public androidx.wear.protolayout.StateBuilders.State? getRequestState();
   }
 
   public static final class ActionBuilders.LoadAction.Builder {
@@ -109,8 +109,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ColorBuilders.ColorProp {
-    method @ColorInt @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getArgb();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor? getDynamicValue();
+    method @ColorInt public int getArgb();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor? getDynamicValue();
   }
 
   public static final class ColorBuilders.ColorProp.Builder {
@@ -124,14 +124,14 @@
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static final class ColorBuilders.ColorStop {
     ctor @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public ColorBuilders.ColorStop(androidx.wear.protolayout.ColorBuilders.ColorProp);
     ctor @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public ColorBuilders.ColorStop(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.TypeBuilders.FloatProp);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.TypeBuilders.FloatProp? getOffset();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp? getOffset();
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static final class ColorBuilders.SweepGradient implements androidx.wear.protolayout.ColorBuilders.Brush {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public java.util.List<androidx.wear.protolayout.ColorBuilders.ColorStop!> getColorStops();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DegreesProp getEndAngle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DegreesProp getStartAngle();
+    method public java.util.List<androidx.wear.protolayout.ColorBuilders.ColorStop!> getColorStops();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getEndAngle();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getStartAngle();
   }
 
   public static final class ColorBuilders.SweepGradient.Builder {
@@ -150,7 +150,7 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DeviceParametersBuilders.Capabilities {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public long getMinimumFreshnessLimitMillis();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public long getMinimumFreshnessLimitMillis();
   }
 
   public static final class DeviceParametersBuilders.Capabilities.Builder {
@@ -160,14 +160,14 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DeviceParametersBuilders.DeviceParameters {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities? getCapabilities();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getDevicePlatform();
-    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getFontScale();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo getRendererSchemaVersion();
-    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getScreenDensity();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getScreenHeightDp();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getScreenShape();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getScreenWidthDp();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities? getCapabilities();
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getFontScale();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo getRendererSchemaVersion();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
   }
 
   public static final class DeviceParametersBuilders.DeviceParameters.Builder {
@@ -195,8 +195,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DimensionBuilders.AngularLayoutConstraint {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAngularAlignment();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getValue();
+    method public int getAngularAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
   }
 
   public static final class DimensionBuilders.AngularLayoutConstraint.Builder {
@@ -209,8 +209,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.DegreesProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
   }
 
   public static final class DimensionBuilders.DegreesProp.Builder {
@@ -222,8 +222,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.DpProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ExtensionDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension androidx.wear.protolayout.DimensionBuilders.SpacerDimension {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
   }
 
   public static final class DimensionBuilders.DpProp.Builder {
@@ -235,7 +235,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.EmProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public float getValue();
   }
 
   public static final class DimensionBuilders.EmProp.Builder {
@@ -245,7 +245,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension androidx.wear.protolayout.DimensionBuilders.SpacerDimension {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TypeBuilders.FloatProp? getLayoutWeight();
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp? getLayoutWeight();
   }
 
   public static final class DimensionBuilders.ExpandedDimensionProp.Builder {
@@ -258,8 +258,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DimensionBuilders.HorizontalLayoutConstraint {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getHorizontalAlignment();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getValue();
+    method public int getHorizontalAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
   }
 
   public static final class DimensionBuilders.HorizontalLayoutConstraint.Builder {
@@ -272,8 +272,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ImageDimension {
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getAspectRatioHeight();
-    method @IntRange(from=0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getAspectRatioWidth();
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
   }
 
   public static final class DimensionBuilders.ProportionalDimensionProp.Builder {
@@ -284,7 +284,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.SpProp {
-    method @Dimension(unit=androidx.annotation.Dimension.SP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
   }
 
   public static final class DimensionBuilders.SpProp.Builder {
@@ -297,8 +297,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class DimensionBuilders.VerticalLayoutConstraint {
-    method @Dimension(unit=androidx.annotation.Dimension.DP) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getVerticalAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+    method public int getVerticalAlignment();
   }
 
   public static final class DimensionBuilders.VerticalLayoutConstraint.Builder {
@@ -308,7 +308,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.DpProp? getMinimumSize();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getMinimumSize();
   }
 
   public static final class DimensionBuilders.WrappedDimensionProp.Builder {
@@ -366,7 +366,7 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class LayoutElementBuilders.AndroidTextStyle {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public boolean getExcludeFontPadding();
+    method public boolean getExcludeFontPadding();
   }
 
   public static final class LayoutElementBuilders.AndroidTextStyle.Builder {
@@ -376,11 +376,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Arc implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getAnchorAngle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
   }
 
   public static final class LayoutElementBuilders.Arc.Builder {
@@ -396,8 +396,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getRotateContents();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRotateContents();
   }
 
   public static final class LayoutElementBuilders.ArcAdapter.Builder {
@@ -409,7 +409,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcAnchorTypeProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
@@ -422,13 +422,13 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcLine implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ColorBuilders.Brush? getBrush();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicLength();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp? getStrokeCap();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+    method public androidx.wear.protolayout.ColorBuilders.Brush? getBrush();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicLength();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp? getStrokeCap();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
   }
 
   public static final class LayoutElementBuilders.ArcLine.Builder {
@@ -445,9 +445,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
   }
 
   public static final class LayoutElementBuilders.ArcSpacer.Builder {
@@ -459,9 +459,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ArcText implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
   }
 
   public static final class LayoutElementBuilders.ArcText.Builder {
@@ -474,12 +474,12 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Box implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Box.Builder {
@@ -496,7 +496,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ColorFilter {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getTint();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getTint();
   }
 
   public static final class LayoutElementBuilders.ColorFilter.Builder {
@@ -506,11 +506,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Column implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Column.Builder {
@@ -525,7 +525,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.ContentScaleModeProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
@@ -535,10 +535,10 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ExperimentalProtoLayoutExtensionApi @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class LayoutElementBuilders.ExtensionLayoutElement implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public String getExtensionId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public byte[] getPayload();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getWidth();
+    method public String getExtensionId();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getHeight();
+    method public byte[] getPayload();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.ExtensionLayoutElement.Builder {
@@ -551,14 +551,14 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.FontStyle {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getItalic();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.EmProp? getLetterSpacing();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpProp? getSize();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public java.util.List<androidx.wear.protolayout.DimensionBuilders.SpProp!> getSizes();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getUnderline();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp? getVariant();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp? getWeight();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getSize();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public java.util.List<androidx.wear.protolayout.DimensionBuilders.SpProp!> getSizes();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getUnderline();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp? getVariant();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp? getWeight();
   }
 
   public static final class LayoutElementBuilders.FontStyle.Builder {
@@ -569,7 +569,7 @@
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.protolayout.DimensionBuilders.EmProp);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.protolayout.DimensionBuilders.SpProp);
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSizes(androidx.wear.protolayout.DimensionBuilders.SpProp!...);
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSizes(@Dimension(unit=androidx.annotation.Dimension.SP) @IntRange(from=1) int...);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.protolayout.TypeBuilders.BoolProp);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp);
@@ -593,7 +593,7 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.FontVariantProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.FontVariantProp.Builder {
@@ -603,7 +603,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.FontWeightProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.FontWeightProp.Builder {
@@ -613,7 +613,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.HorizontalAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
@@ -623,12 +623,12 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Image implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter? getColorFilter();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getWidth();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter? getColorFilter();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Image.Builder {
@@ -647,7 +647,7 @@
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Layout {
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.LayoutElementBuilders.Layout? fromByteArray(byte[]);
     method public static androidx.wear.protolayout.LayoutElementBuilders.Layout fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getRoot();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getRoot();
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public byte[] toByteArray();
   }
 
@@ -661,11 +661,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Row implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Row.Builder {
@@ -680,11 +680,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Spacer implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint? getLayoutConstraintsForDynamicHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint? getLayoutConstraintsForDynamicWidth();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getWidth();
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint? getLayoutConstraintsForDynamicHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint? getLayoutConstraintsForDynamicWidth();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getWidth();
   }
 
   public static final class LayoutElementBuilders.Spacer.Builder {
@@ -701,11 +701,11 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.SpanImage implements androidx.wear.protolayout.LayoutElementBuilders.Span {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
   }
 
   public static final class LayoutElementBuilders.SpanImage.Builder {
@@ -721,10 +721,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.SpanText implements androidx.wear.protolayout.LayoutElementBuilders.Span {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
   }
 
   public static final class LayoutElementBuilders.SpanText.Builder {
@@ -738,7 +738,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
@@ -748,13 +748,13 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Spannable implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
-    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getMarqueeIterations();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.Span!> getSpans();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.Span!> getSpans();
   }
 
   public static final class LayoutElementBuilders.Spannable.Builder {
@@ -773,8 +773,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class LayoutElementBuilders.StrokeCapProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ModifiersBuilders.Shadow? getShadow();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getValue();
+    method public androidx.wear.protolayout.ModifiersBuilders.Shadow? getShadow();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.StrokeCapProp.Builder {
@@ -785,16 +785,16 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.Text implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint? getLayoutConstraintsForDynamicText();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
-    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getMarqueeIterations();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint? getLayoutConstraintsForDynamicText();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @SuppressCompatibility @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
   }
 
   public static final class LayoutElementBuilders.Text.Builder {
@@ -817,7 +817,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.TextAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
@@ -827,7 +827,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.TextOverflowProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.TextOverflowProp.Builder {
@@ -837,7 +837,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class LayoutElementBuilders.VerticalAlignmentProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
@@ -864,8 +864,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.AnimatedVisibility {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.EnterTransition? getEnterTransition();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.ExitTransition? getExitTransition();
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition? getEnterTransition();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition? getExitTransition();
   }
 
   public static final class ModifiersBuilders.AnimatedVisibility.Builder {
@@ -876,8 +876,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.ArcModifiers {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
   }
 
   public static final class ModifiersBuilders.ArcModifiers.Builder {
@@ -888,8 +888,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Background {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Corner? getCorner();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner? getCorner();
   }
 
   public static final class ModifiersBuilders.Background.Builder {
@@ -900,8 +900,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Border {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
   }
 
   public static final class ModifiersBuilders.Border.Builder {
@@ -912,10 +912,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Clickable {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableHeight();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableWidth();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ActionBuilders.Action? getOnClick();
+    method public String getId();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getMinimumClickableWidth();
+    method public androidx.wear.protolayout.ActionBuilders.Action? getOnClick();
   }
 
   public static final class ModifiersBuilders.Clickable.Builder {
@@ -928,7 +928,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Corner {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getRadius();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getRadius();
   }
 
   public static final class ModifiersBuilders.Corner.Builder {
@@ -938,16 +938,16 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.DefaultContentTransitions {
-    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeIn();
-    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeInSlideIn(@SuppressCompatibility int);
-    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOut();
-    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOutSlideOut(@SuppressCompatibility int);
-    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition slideIn(@SuppressCompatibility int);
-    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition slideOut(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeIn();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeInSlideIn(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOut();
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOutSlideOut(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition slideIn(@SuppressCompatibility int);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition slideOut(@SuppressCompatibility int);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.ElementMetadata {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public byte[] getTagData();
+    method public byte[] getTagData();
   }
 
   public static final class ModifiersBuilders.ElementMetadata.Builder {
@@ -957,8 +957,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.EnterTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition? getFadeIn();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition? getSlideIn();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition? getFadeIn();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition? getSlideIn();
   }
 
   public static final class ModifiersBuilders.EnterTransition.Builder {
@@ -969,8 +969,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.ExitTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition? getFadeOut();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition? getSlideOut();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition? getFadeOut();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition? getSlideOut();
   }
 
   public static final class ModifiersBuilders.ExitTransition.Builder {
@@ -981,8 +981,8 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.FadeInTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @FloatRange(from=0.0, to=1.0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getInitialAlpha();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getInitialAlpha();
   }
 
   public static final class ModifiersBuilders.FadeInTransition.Builder {
@@ -993,26 +993,26 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.FadeOutTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @FloatRange(from=0.0, to=1.0) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public float getTargetAlpha();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getTargetAlpha();
   }
 
   public static final class ModifiersBuilders.FadeOutTransition.Builder {
     ctor public ModifiersBuilders.FadeOutTransition.Builder();
     method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition build();
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setTargetAlpha(@FloatRange(from=0.0, to=1.0) float);
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setTargetAlpha(@FloatRange(from=0.0, to=1.0) float);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Modifiers {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Background? getBackground();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Border? getBorder();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility? getContentUpdateAnimation();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.TypeBuilders.BoolProp? getHidden();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata? getMetadata();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Padding? getPadding();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+    method public androidx.wear.protolayout.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility? getContentUpdateAnimation();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata? getMetadata();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.TypeBuilders.BoolProp isVisible();
   }
 
   public static final class ModifiersBuilders.Modifiers.Builder {
@@ -1022,18 +1022,18 @@
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.protolayout.ModifiersBuilders.Border);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
     method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setContentUpdateAnimation(androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility);
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setHidden(androidx.wear.protolayout.TypeBuilders.BoolProp);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setMetadata(androidx.wear.protolayout.ModifiersBuilders.ElementMetadata);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.protolayout.ModifiersBuilders.Padding);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.protolayout.ModifiersBuilders.Semantics);
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setVisible(androidx.wear.protolayout.TypeBuilders.BoolProp);
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Padding {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getBottom();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getEnd();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.BoolProp? getRtlAware();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getStart();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.DimensionBuilders.DpProp? getTop();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getTop();
   }
 
   public static final class ModifiersBuilders.Padding.Builder {
@@ -1049,9 +1049,9 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.Semantics {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getRole();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TypeBuilders.StringProp? getStateDescription();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public int getRole();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getStateDescription();
   }
 
   public static final class ModifiersBuilders.Semantics.Builder {
@@ -1064,8 +1064,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public static final class ModifiersBuilders.Shadow {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.DimensionBuilders.DpProp getBlurRadius();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=300) public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getBlurRadius();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
   }
 
   public static final class ModifiersBuilders.Shadow.Builder {
@@ -1079,9 +1079,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.SlideInTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getDirection();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getInitialSlideBound();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @SuppressCompatibility public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getInitialSlideBound();
   }
 
   public static final class ModifiersBuilders.SlideInTransition.Builder {
@@ -1093,9 +1093,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.SlideOutTransition {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getDirection();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getTargetSlideBound();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @SuppressCompatibility public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getTargetSlideBound();
   }
 
   public static final class ModifiersBuilders.SlideOutTransition.Builder {
@@ -1103,11 +1103,11 @@
     method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition build();
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setDirection(@SuppressCompatibility int);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setTargetSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setTargetSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ModifiersBuilders.SlideParentBound implements androidx.wear.protolayout.ModifiersBuilders.SlideBound {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getSnapTo();
+    method @SuppressCompatibility public int getSnapTo();
   }
 
   public static final class ModifiersBuilders.SlideParentBound.Builder {
@@ -1117,7 +1117,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ModifiersBuilders.SpanModifiers {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
   }
 
   public static final class ModifiersBuilders.SpanModifiers.Builder {
@@ -1135,9 +1135,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAnimatedImageFormat();
-    method @DrawableRes @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getResourceId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
   }
 
   public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
@@ -1149,7 +1149,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.AndroidImageResourceByResId {
-    method @DrawableRes @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getResourceId();
+    method @DrawableRes public int getResourceId();
   }
 
   public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
@@ -1159,9 +1159,9 @@
   }
 
   @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAnimatedImageFormat();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
-    method @DrawableRes @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getResourceId();
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
   }
 
   public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
@@ -1173,10 +1173,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.ImageResource {
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
-    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method @SuppressCompatibility @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
   }
 
   public static final class ResourceBuilders.ImageResource.Builder {
@@ -1189,10 +1189,10 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.InlineImageResource {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public byte[] getData();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getFormat();
-    method @Dimension(unit=androidx.annotation.Dimension.PX) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getHeightPx();
-    method @Dimension(unit=androidx.annotation.Dimension.PX) @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getWidthPx();
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
   }
 
   public static final class ResourceBuilders.InlineImageResource.Builder {
@@ -1205,8 +1205,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class ResourceBuilders.Resources {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getVersion();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
   }
 
   public static final class ResourceBuilders.Resources.Builder {
@@ -1220,8 +1220,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class StateBuilders.State {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getKeyToValueMapping();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getLastClickableId();
+    method public java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getKeyToValueMapping();
+    method public String getLastClickableId();
     method public static int getMaxStateEntryCount();
   }
 
@@ -1235,8 +1235,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TimelineBuilders.TimeInterval {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public long getEndMillis();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public long getStartMillis();
+    method public long getEndMillis();
+    method public long getStartMillis();
   }
 
   public static final class TimelineBuilders.TimeInterval.Builder {
@@ -1248,7 +1248,7 @@
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TimelineBuilders.Timeline {
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static androidx.wear.protolayout.TimelineBuilders.Timeline fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public java.util.List<androidx.wear.protolayout.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+    method public java.util.List<androidx.wear.protolayout.TimelineBuilders.TimelineEntry!> getTimelineEntries();
   }
 
   public static final class TimelineBuilders.Timeline.Builder {
@@ -1259,8 +1259,8 @@
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TimelineBuilders.TimelineEntry {
     method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static androidx.wear.protolayout.TimelineBuilders.TimelineEntry fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.LayoutElementBuilders.Layout? getLayout();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public androidx.wear.protolayout.TimelineBuilders.TimeInterval? getValidity();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval? getValidity();
   }
 
   public static final class TimelineBuilders.TimelineEntry.Builder {
@@ -1271,7 +1271,7 @@
   }
 
   public final class TriggerBuilders {
-    method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnLoadTrigger();
   }
 
@@ -1282,8 +1282,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.BoolProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public boolean getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool? getDynamicValue();
+    method public boolean getValue();
   }
 
   public static final class TypeBuilders.BoolProp.Builder {
@@ -1295,8 +1295,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.FloatProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public float getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
   }
 
   public static final class TypeBuilders.FloatProp.Builder {
@@ -1308,7 +1308,7 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.Int32Prop {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public int getValue();
+    method public int getValue();
   }
 
   public static final class TypeBuilders.Int32Prop.Builder {
@@ -1318,8 +1318,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public static final class TypeBuilders.StringLayoutConstraint {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public int getAlignment();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public String getPatternForLayout();
+    method public int getAlignment();
+    method public String getPatternForLayout();
   }
 
   public static final class TypeBuilders.StringLayoutConstraint.Builder {
@@ -1329,8 +1329,8 @@
   }
 
   @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public static final class TypeBuilders.StringProp {
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=200) public androidx.wear.protolayout.expression.DynamicBuilders.DynamicString? getDynamicValue();
-    method @androidx.wear.protolayout.expression.RequiresSchemaVersion(major=1, minor=0) public String getValue();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicString? getDynamicValue();
+    method public String getValue();
   }
 
   public static final class TypeBuilders.StringProp.Builder {
diff --git a/wear/protolayout/protolayout/build.gradle b/wear/protolayout/protolayout/build.gradle
index 3c2633d..8459d38 100644
--- a/wear/protolayout/protolayout/build.gradle
+++ b/wear/protolayout/protolayout/build.gradle
@@ -29,6 +29,9 @@
     implementation(project(path: ":wear:protolayout:protolayout-proto", configuration: "shadow"))
     api(project(":wear:protolayout:protolayout-expression"))
 
+    lintChecks(project(":wear:protolayout:protolayout-lint"))
+    lintPublish(project(":wear:protolayout:protolayout-lint"))
+
     testImplementation(libs.testExtJunit)
     testImplementation(libs.testExtTruth)
     testImplementation(libs.testRunner)
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
index 52b14f0..ad80dba 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
@@ -110,7 +110,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getValue() {
             return mImpl.getValue();
@@ -195,7 +194,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public int getValue() {
             return mImpl.getValue();
         }
@@ -279,7 +277,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public long getValue() {
             return mImpl.getValue();
         }
@@ -363,7 +360,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public double getValue() {
             return mImpl.getValue();
         }
@@ -448,7 +444,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public boolean getValue() {
             return mImpl.getValue();
         }
@@ -587,7 +582,6 @@
         }
 
         /** Gets the package name to send the intent to, for example, "com.example.weather". */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getPackageName() {
             return mImpl.getPackageName();
@@ -597,14 +591,12 @@
          * Gets the fully qualified class name (including the package) to send the intent to, for
          * example, "com.example.weather.WeatherOverviewActivity".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getClassName() {
             return mImpl.getClassName();
         }
 
         /** Gets the extras to be included in the intent. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public Map<String, AndroidExtra> getKeyToExtraMapping() {
             Map<String, AndroidExtra> map = new HashMap<>();
@@ -720,7 +712,6 @@
         }
 
         /** Gets an action to launch an Android activity. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public AndroidActivity getAndroidActivity() {
             if (mImpl.hasAndroidActivity()) {
@@ -814,7 +805,6 @@
          * sent after this action is invoked by a {@link
          * androidx.wear.protolayout.ModifiersBuilders.Clickable}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public State getRequestState() {
             if (mImpl.hasRequestState()) {
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ColorBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ColorBuilders.java
index 69adf7b..c8c3b1c 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ColorBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ColorBuilders.java
@@ -65,7 +65,6 @@
          * ignored. If the static value is not specified, zero (equivalent to {@link
          * Color#TRANSPARENT}) will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @ColorInt
         public int getArgb() {
             return mImpl.getArgb();
@@ -76,7 +75,6 @@
          * required to be set to support older renderers that only read the static value. If {@code
          * dynamicValue} has an invalid result, the provided static value will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicColor getDynamicValue() {
             if (mImpl.hasDynamicValue()) {
@@ -197,8 +195,10 @@
             this.mFingerprint = fingerprint;
         }
 
-        /** Gets the color for this stop. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
+        /**
+         * Gets the color for this stop. Only opaque colors are supported. Any transparent colors
+         * will have their alpha component set to 0xFF (opaque).
+         */
         @NonNull
         public ColorProp getColor() {
             return ColorProp.fromProto(mImpl.getColor());
@@ -208,7 +208,6 @@
          * Gets the relative offset for this color, between 0 and 1. This determines where the color
          * is positioned relative to a gradient space.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @Nullable
         public FloatProp getOffset() {
             if (mImpl.hasOffset()) {
@@ -292,7 +291,8 @@
             public Builder() {}
 
             /**
-             * Sets the color for this stop.
+             * Sets the color for this stop. Only opaque colors are supported. Any transparent
+             * colors will have their alpha component set to 0xFF (opaque).
              *
              * <p>Note that this field only supports static values.
              */
@@ -373,7 +373,6 @@
          *
          * <p>If offset values are not set, the colors are evenly distributed in the gradient.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public List<ColorStop> getColorStops() {
             List<ColorStop> list = new ArrayList<>();
@@ -392,7 +391,6 @@
          * length span. Values greater than 360 degrees correspond to upper layers of the arc line
          * as it wraps over itself.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public DegreesProp getStartAngle() {
             if (mImpl.hasStartAngle()) {
@@ -411,7 +409,6 @@
          * length span. Values greater than 360 degrees correspond to upper layers of the arc line
          * as it wraps over itself.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public DegreesProp getEndAngle() {
             if (mImpl.hasEndAngle()) {
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DeviceParametersBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DeviceParametersBuilders.java
index 7f38b54..64dcf08 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DeviceParametersBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DeviceParametersBuilders.java
@@ -85,14 +85,12 @@
         }
 
         /** Gets width of the device's screen in DP. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Dimension(unit = DP)
         public int getScreenWidthDp() {
             return mImpl.getScreenWidthDp();
         }
 
         /** Gets height of the device's screen in DP. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Dimension(unit = DP)
         public int getScreenHeightDp() {
             return mImpl.getScreenHeightDp();
@@ -102,7 +100,6 @@
          * Gets density of the display. This value is the scaling factor to get from DP to Pixels
          * (px = dp * density).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @FloatRange(from = 0.0, fromInclusive = false, toInclusive = false)
         public float getScreenDensity() {
             return mImpl.getScreenDensity();
@@ -112,21 +109,18 @@
          * Gets current user preference for the scaling factor for fonts displayed on the display.
          * This value is used to get from SP to DP (dp = sp * font_scale).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @FloatRange(from = 0.0, fromInclusive = false, toInclusive = false)
         public float getFontScale() {
             return mImpl.getFontScale();
         }
 
         /** Gets the platform of the device. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @DevicePlatform
         public int getDevicePlatform() {
             return mImpl.getDevicePlatform().getNumber();
         }
 
         /** Gets the shape of the device's screen. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @ScreenShape
         public int getScreenShape() {
             return mImpl.getScreenShape().getNumber();
@@ -137,7 +131,6 @@
          * that uses features not available on schema version 1.0 , this can be used to
          * conditionally choose which feature to use.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public VersionInfo getRendererSchemaVersion() {
             if (mImpl.hasRendererSchemaVersion()) {
@@ -148,7 +141,6 @@
         }
 
         /** Gets renderer supported {@link Capabilities}. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         @Nullable
         public Capabilities getCapabilities() {
@@ -314,7 +306,6 @@
          * on various factors. Any freshness request lower than the current limit will be replaced
          * by that limit. A value of 0 here signifies that the minimum freshness limit in unknown.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         public long getMinimumFreshnessLimitMillis() {
             return mImpl.getMinimumFreshnessLimitMillis();
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java
index 471b831..4c53afb 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/DimensionBuilders.java
@@ -137,7 +137,6 @@
          * dynamic values for the corresponding field, this static value will be ignored. If the
          * static value is not specified, zero will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Dimension(unit = DP)
         public float getValue() {
             return mImpl.getValue();
@@ -149,7 +148,6 @@
          * {@code dynamicValue} has an invalid result, the provided static value will be used
          * instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getDynamicValue() {
             if (mImpl.hasDynamicValue()) {
@@ -307,7 +305,6 @@
          * Constrains the layout so that components are not changing size or location regardless of
          * the dynamic value that is being provided.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @SuppressWarnings("Unused")
         @Dimension(unit = DP)
         public float getValue() {
@@ -374,7 +371,6 @@
         /**
          * Gets the horizontal alignment of the actual content within the space reserved by value.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @LayoutElementBuilders.HorizontalAlignment
         public int getHorizontalAlignment() {
             return mImpl.getHorizontalAlignmentForLayoutValue();
@@ -431,7 +427,6 @@
         }
 
         /** Gets the vertical alignment of the actual content within the space reserved by value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @LayoutElementBuilders.VerticalAlignment
         public int getVerticalAlignment() {
             return mImpl.getVerticalAlignmentForLayoutValue();
@@ -489,7 +484,6 @@
         }
 
         /** Gets the value, in sp. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Dimension(unit = SP)
         public float getValue() {
             return mImpl.getValue();
@@ -565,7 +559,6 @@
         }
 
         /** Gets the value, in em. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public float getValue() {
             return mImpl.getValue();
         }
@@ -644,7 +637,6 @@
          * supports dynamic values for the corresponding field, this static value will be ignored.
          * If the static value is not specified, zero will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public float getValue() {
             return mImpl.getValue();
         }
@@ -655,7 +647,6 @@
          * If {@code dynamicValue} has an invalid result, the provided static value will be used
          * instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getDynamicValue() {
             if (mImpl.hasDynamicValue()) {
@@ -789,14 +780,12 @@
          * Gets the fixed value to reserve the space when used on a layout-changing data bind. If
          * not set defaults to the static value of the associated {@link DegreesProp} field.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Dimension(unit = DP)
         public float getValue() {
             return mImpl.getValueForLayout();
         }
 
         /** Gets angular alignment of the actual content within the space reserved by value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @LayoutElementBuilders.AngularAlignment
         public int getAngularAlignment() {
             return mImpl.getAngularAlignmentForLayoutValue();
@@ -892,7 +881,6 @@
          * have equal weight. Where applicable, the width or height of the element is proportional
          * to the sum of the weights of its siblings.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public FloatProp getLayoutWeight() {
             if (mImpl.hasLayoutWeight()) {
@@ -1021,7 +1009,6 @@
         }
 
         /** Gets the minimum size of this dimension. If not set, then there is no minimum size. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DpProp getMinimumSize() {
             if (mImpl.hasMinimumSize()) {
@@ -1132,14 +1119,12 @@
         }
 
         /** Gets the width to be used when calculating the aspect ratio to preserve. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @IntRange(from = 0)
         public int getAspectRatioWidth() {
             return mImpl.getAspectRatioWidth();
         }
 
         /** Gets the height to be used when calculating the aspect ratio ratio to preserve. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @IntRange(from = 0)
         public int getAspectRatioHeight() {
             return mImpl.getAspectRatioHeight();
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
index 7b0a86c..dd99305 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
@@ -16,10 +16,14 @@
 
 package androidx.wear.protolayout;
 
+import static androidx.wear.protolayout.DimensionBuilders.sp;
 import static androidx.wear.protolayout.expression.Preconditions.checkNotNull;
 
 import android.annotation.SuppressLint;
+import android.graphics.Color;
+import android.util.Log;
 
+import androidx.annotation.Dimension;
 import androidx.annotation.IntDef;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
@@ -55,6 +59,7 @@
 import androidx.wear.protolayout.expression.ProtoLayoutExperimental;
 import androidx.wear.protolayout.expression.RequiresSchemaVersion;
 import androidx.wear.protolayout.proto.AlignmentProto;
+import androidx.wear.protolayout.proto.ColorProto;
 import androidx.wear.protolayout.proto.DimensionProto;
 import androidx.wear.protolayout.proto.FingerprintProto;
 import androidx.wear.protolayout.proto.FingerprintProto.TreeFingerprint;
@@ -306,7 +311,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @FontWeight
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -386,7 +390,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @FontVariant
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -466,7 +469,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @SpanVerticalAlignment
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -548,7 +550,6 @@
          * Gets whether the text should be rendered in a italic typeface. If not specified, defaults
          * to "false".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public BoolProp getItalic() {
             if (mImpl.hasItalic()) {
@@ -562,7 +563,6 @@
          * Gets whether the text should be rendered with an underline. If not specified, defaults to
          * "false".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public BoolProp getUnderline() {
             if (mImpl.hasUnderline()) {
@@ -578,7 +578,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ColorProp getColor() {
             if (mImpl.hasColor()) {
@@ -593,7 +592,6 @@
          * nearest supported value will be used. If not defined, or when set to an invalid value,
          * defaults to "normal".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public FontWeightProp getWeight() {
             if (mImpl.hasWeight()) {
@@ -607,7 +605,6 @@
          * Gets the text letter-spacing. Positive numbers increase the space between letters while
          * negative numbers tighten the space. If not specified, defaults to 0.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public EmProp getLetterSpacing() {
             if (mImpl.hasLetterSpacing()) {
@@ -621,7 +618,6 @@
          * Gets the variant of a font. Some renderers may use different fonts for title and body
          * text, which can be selected using this field. If not specified, defaults to "body".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @ProtoLayoutExperimental
         @Nullable
         public FontVariantProp getVariant() {
@@ -636,7 +632,6 @@
          * Gets the size of the font, in scaled pixels (sp). If more than one size was originally
          * added, it will return the last one.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpProp getSize() {
             List<DimensionProto.SpProp> sizes = mImpl.getSizeList();
@@ -644,7 +639,6 @@
         }
 
         /** Gets the available sizes of the font, in scaled pixels (sp). */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         @ProtoLayoutExperimental
         public List<SpProp> getSizes() {
@@ -717,10 +711,16 @@
             /**
              * Sets whether the text should be rendered in a italic typeface. If not specified,
              * defaults to "false".
+             *
+             * <p>Note that this field only supports static values.
              */
             @RequiresSchemaVersion(major = 1, minor = 0)
             @NonNull
             public Builder setItalic(@NonNull BoolProp italic) {
+                if (italic.getDynamicValue() != null) {
+                    throw new IllegalArgumentException(
+                            "FontStyle.Builder.setItalic doesn't support dynamic values.");
+                }
                 mImpl.setItalic(italic.toProto());
                 mFingerprint.recordPropertyUpdate(
                         2, checkNotNull(italic.getFingerprint()).aggregateValueAsInt());
@@ -741,10 +741,16 @@
             /**
              * Sets whether the text should be rendered with an underline. If not specified,
              * defaults to "false".
+             *
+             * <p>Note that this field only supports static values.
              */
             @RequiresSchemaVersion(major = 1, minor = 0)
             @NonNull
             public Builder setUnderline(@NonNull BoolProp underline) {
+                if (underline.getDynamicValue() != null) {
+                    throw new IllegalArgumentException(
+                            "FontStyle.Builder.setUnderline doesn't support dynamic values.");
+                }
                 mImpl.setUnderline(underline.toProto());
                 mFingerprint.recordPropertyUpdate(
                         3, checkNotNull(underline.getFingerprint()).aggregateValueAsInt());
@@ -854,15 +860,15 @@
              * words, the largest size from the specified preset sizes that can fit the most text
              * within the parent bounds will be used.
              *
-             * <p>The specified sizes don't have to be sorted, but they need to contain at least one
-             * positive value. The maximum number of sizes used is limited to 10.
+             * <p>The specified sizes don't have to be sorted, but they need to contain only
+             * positive values. The maximum number of sizes used is limited to 10.
              *
              * <p>Note that, if multiple sizes are set, the parent of the {@link Text} element this
              * corresponds to shouldn't have its width and height set to wrapped, as it can lead to
              * unexpected results.
              *
              * <p>If this {@link FontStyle} is set to any other element besides {@link Text} or that
-             * {@link Text} element has dynamic field, only the last added size will be use.
+             * {@link Text} element has dynamic field, only the last added size will be used.
              *
              * <p>Any previously added values with this method or {@link #setSize} will be cleared.
              *
@@ -871,28 +877,32 @@
              * values to automatically scale text. Renderers who don't support this version will use
              * the last size among multiple values.
              *
-             * @throws IllegalArgumentException if the number of available sizes is larger than 10.
+             * @throws IllegalArgumentException if the number of available sizes is larger than 10
+             * or one of the sizes is not a positive value.
              */
             @RequiresSchemaVersion(major = 1, minor = 300)
             @NonNull
             @ProtoLayoutExperimental
-            public Builder setSizes(@NonNull SpProp... sizes) {
+            public Builder setSizes(
+                    @NonNull @IntRange(from = 1) @Dimension(unit = Dimension.SP) int... sizes) {
                 if (sizes.length > TEXT_SIZES_LIMIT) {
                     throw new IllegalArgumentException(
                             "Number of available sizes of the font style can't be larger than 10.");
                 }
 
                 mImpl.clearSize();
-                for (SpProp size : sizes) {
-                    if (size.getValue() <= 0) {
+                for (int size : sizes) {
+                    if (size <= 0) {
                         throw new IllegalArgumentException(
                                 "Available sizes of the font style must contain only positive "
                                         + "value.");
                     }
 
-                    mImpl.addSize(size.toProto());
+                    SpProp spPropSize = sp(size);
+                    mImpl.addSize(spPropSize.toProto());
                     mFingerprint.recordPropertyUpdate(
-                            1, checkNotNull(size.getFingerprint()).aggregateValueAsInt());
+                            1,
+                            checkNotNull(spPropSize.getFingerprint()).aggregateValueAsInt());
                 }
                 return this;
             }
@@ -934,7 +944,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @TextOverflow
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -1017,7 +1026,6 @@
          * Gets the number of times to repeat the Marquee animation. Set to -1 to repeat
          * indefinitely. Defaults to repeat indefinitely.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         public int getIterations() {
             return mImpl.getIterations();
@@ -1106,7 +1114,6 @@
          * Gets whether the {@link Text} excludes padding specified by the font, i.e. extra top and
          * bottom padding above the normal ascent and descent. The default is false.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         public boolean getExcludeFontPadding() {
             return mImpl.getExcludeFontPadding();
         }
@@ -1192,7 +1199,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public StringProp getText() {
             if (mImpl.hasText()) {
@@ -1206,7 +1212,6 @@
          * Gets the style of font to use (size, bold etc). If not specified, defaults to the
          * platform's default body font.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public FontStyle getFontStyle() {
             if (mImpl.hasFontStyle()) {
@@ -1217,7 +1222,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -1231,7 +1235,6 @@
          * Gets the maximum number of lines that can be represented by the {@link Text} element. If
          * not defined, the {@link Text} element will be treated as a single-line element.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Int32Prop getMaxLines() {
             if (mImpl.hasMaxLines()) {
@@ -1248,7 +1251,6 @@
          * the alignment of lines relative to the {@link Text} element bounds. If not defined,
          * defaults to TEXT_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public TextAlignmentProp getMultilineAlignment() {
             if (mImpl.hasMultilineAlignment()) {
@@ -1265,7 +1267,6 @@
          * which cannot fit inside its container will be truncated. If not defined, defaults to
          * TEXT_OVERFLOW_TRUNCATE.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public TextOverflowProp getOverflow() {
             if (mImpl.hasOverflow()) {
@@ -1280,7 +1281,6 @@
          * distance between subsequent baselines. If not specified, defaults the font's recommended
          * interline spacing.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpProp getLineHeight() {
             if (mImpl.hasLineHeight()) {
@@ -1294,7 +1294,6 @@
          * Gets an Android platform specific text style configuration options for styling and
          * compatibility.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         @Nullable
         public AndroidTextStyle getAndroidTextStyle() {
@@ -1309,7 +1308,6 @@
          * Gets the number of times to repeat the Marquee animation. Only applies when overflow is
          * TEXT_OVERFLOW_MARQUEE. Set to -1 to repeat indefinitely. Defaults to repeat indefinitely.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         @IntRange(from = -1)
         public int getMarqueeIterations() {
@@ -1320,7 +1318,6 @@
          * Gets the bounding constraints for the layout affected by the dynamic value from {@link
          * #getText()}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public StringLayoutConstraint getLayoutConstraintsForDynamicText() {
             if (mImpl.hasText()) {
@@ -1617,7 +1614,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @ContentScaleMode
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -1706,7 +1702,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ColorProp getTint() {
             if (mImpl.hasTint()) {
@@ -1807,7 +1802,6 @@
          * Gets the resource_id of the image to render. This must exist in the supplied resource
          * bundle.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public StringProp getResourceId() {
             if (mImpl.hasResourceId()) {
@@ -1818,7 +1812,6 @@
         }
 
         /** Gets the width of this image. If not defined, the image will not be rendered. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ImageDimension getWidth() {
             if (mImpl.hasWidth()) {
@@ -1829,7 +1822,6 @@
         }
 
         /** Gets the height of this image. If not defined, the image will not be rendered. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ImageDimension getHeight() {
             if (mImpl.hasHeight()) {
@@ -1843,7 +1835,6 @@
          * Gets how to scale the image resource inside the bounds specified by width/height if its
          * size does not match those bounds. Defaults to CONTENT_SCALE_MODE_FIT.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContentScaleModeProp getContentScaleMode() {
             if (mImpl.hasContentScaleMode()) {
@@ -1854,7 +1845,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -1865,7 +1855,6 @@
         }
 
         /** Gets filtering parameters for this image. If not specified, defaults to no filtering. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ColorFilter getColorFilter() {
             if (mImpl.hasColorFilter()) {
@@ -2061,7 +2050,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpacerDimension getWidth() {
             if (mImpl.hasWidth()) {
@@ -2077,7 +2065,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpacerDimension getHeight() {
             if (mImpl.hasHeight()) {
@@ -2088,7 +2075,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -2102,7 +2088,6 @@
          * Gets the bounding constraints for the layout affected by the dynamic value from {@link
          * #getWidth()}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public HorizontalLayoutConstraint getLayoutConstraintsForDynamicWidth() {
             if (mImpl.getWidth().hasLinearDimension()) {
@@ -2116,7 +2101,6 @@
          * Gets the bounding constraints for the layout affected by the dynamic value from {@link
          * #getHeight()}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public VerticalLayoutConstraint getLayoutConstraintsForDynamicHeight() {
             if (mImpl.getHeight().hasLinearDimension()) {
@@ -2317,7 +2301,6 @@
         }
 
         /** Gets the child element(s) to wrap. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public List<LayoutElement> getContents() {
             List<LayoutElement> list = new ArrayList<>();
@@ -2331,7 +2314,6 @@
          * Gets the height of this {@link Box}. If not defined, this will size itself to fit all of
          * its children (i.e. a WrappedDimension).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContainerDimension getHeight() {
             if (mImpl.hasHeight()) {
@@ -2345,7 +2327,6 @@
          * Gets the width of this {@link Box}. If not defined, this will size itself to fit all of
          * its children (i.e. a WrappedDimension).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContainerDimension getWidth() {
             if (mImpl.hasWidth()) {
@@ -2359,7 +2340,6 @@
          * Gets the horizontal alignment of the element inside this {@link Box}. If not defined,
          * defaults to HORIZONTAL_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public HorizontalAlignmentProp getHorizontalAlignment() {
             if (mImpl.hasHorizontalAlignment()) {
@@ -2373,7 +2353,6 @@
          * Gets the vertical alignment of the element inside this {@link Box}. If not defined,
          * defaults to VERTICAL_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public VerticalAlignmentProp getVerticalAlignment() {
             if (mImpl.hasVerticalAlignment()) {
@@ -2384,7 +2363,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -2580,7 +2558,6 @@
         }
 
         /** Gets the text to render. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public StringProp getText() {
             if (mImpl.hasText()) {
@@ -2594,7 +2571,6 @@
          * Gets the style of font to use (size, bold etc). If not specified, defaults to the
          * platform's default body font.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public FontStyle getFontStyle() {
             if (mImpl.hasFontStyle()) {
@@ -2605,7 +2581,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpanModifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -2619,7 +2594,6 @@
          * Gets an Android platform specific text style configuration options for styling and
          * compatibility.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         @Nullable
         public AndroidTextStyle getAndroidTextStyle() {
@@ -2782,7 +2756,6 @@
          * Gets the resource_id of the image to render. This must exist in the supplied resource
          * bundle.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public StringProp getResourceId() {
             if (mImpl.hasResourceId()) {
@@ -2793,7 +2766,6 @@
         }
 
         /** Gets the width of this image. If not defined, the image will not be rendered. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getWidth() {
             if (mImpl.hasWidth()) {
@@ -2804,7 +2776,6 @@
         }
 
         /** Gets the height of this image. If not defined, the image will not be rendered. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getHeight() {
             if (mImpl.hasHeight()) {
@@ -2815,7 +2786,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpanModifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -2829,7 +2799,6 @@
          * Gets alignment of this image within the line height of the surrounding {@link Spannable}.
          * If undefined, defaults to SPAN_VERTICAL_ALIGN_BOTTOM.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpanVerticalAlignmentProp getAlignment() {
             if (mImpl.hasAlignment()) {
@@ -3071,7 +3040,6 @@
         }
 
         /** Gets the {@link Span} elements that form this {@link Spannable}. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public List<Span> getSpans() {
             List<Span> list = new ArrayList<>();
@@ -3082,7 +3050,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -3097,7 +3064,6 @@
          * element. If not defined, the {@link Spannable} element will be treated as a single-line
          * element.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Int32Prop getMaxLines() {
             if (mImpl.hasMaxLines()) {
@@ -3114,7 +3080,6 @@
          * content, however, this will set the alignment of lines relative to the {@link Spannable}
          * element bounds. If not defined, defaults to TEXT_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public HorizontalAlignmentProp getMultilineAlignment() {
             if (mImpl.hasMultilineAlignment()) {
@@ -3131,7 +3096,6 @@
          * content, the content which cannot fit inside its container will be truncated. If not
          * defined, defaults to TEXT_OVERFLOW_TRUNCATE.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public TextOverflowProp getOverflow() {
             if (mImpl.hasOverflow()) {
@@ -3146,7 +3110,6 @@
          * distance between subsequent baselines. If not specified, defaults the font's recommended
          * interline spacing.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public SpProp getLineHeight() {
             if (mImpl.hasLineHeight()) {
@@ -3160,7 +3123,6 @@
          * Gets the number of times to repeat the Marquee animation. Only applies when overflow is
          * TEXT_OVERFLOW_MARQUEE. Set to -1 to repeat indefinitely. Defaults to repeat indefinitely.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         @IntRange(from = -1)
         public int getMarqueeIterations() {
@@ -3394,7 +3356,6 @@
         }
 
         /** Gets the list of child elements to place inside this {@link Column}. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public List<LayoutElement> getContents() {
             List<LayoutElement> list = new ArrayList<>();
@@ -3408,7 +3369,6 @@
          * Gets the horizontal alignment of elements inside this column, if they are narrower than
          * the resulting width of the column. If not defined, defaults to HORIZONTAL_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public HorizontalAlignmentProp getHorizontalAlignment() {
             if (mImpl.hasHorizontalAlignment()) {
@@ -3422,7 +3382,6 @@
          * Gets the width of this column. If not defined, this will size itself to fit all of its
          * children (i.e. a WrappedDimension).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContainerDimension getWidth() {
             if (mImpl.hasWidth()) {
@@ -3436,7 +3395,6 @@
          * Gets the height of this column. If not defined, this will size itself to fit all of its
          * children (i.e. a WrappedDimension).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContainerDimension getHeight() {
             if (mImpl.hasHeight()) {
@@ -3447,7 +3405,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -3624,7 +3581,6 @@
         }
 
         /** Gets the list of child elements to place inside this {@link Row}. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public List<LayoutElement> getContents() {
             List<LayoutElement> list = new ArrayList<>();
@@ -3638,7 +3594,6 @@
          * Gets the vertical alignment of elements inside this row, if they are narrower than the
          * resulting height of the row. If not defined, defaults to VERTICAL_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public VerticalAlignmentProp getVerticalAlignment() {
             if (mImpl.hasVerticalAlignment()) {
@@ -3652,7 +3607,6 @@
          * Gets the width of this row. If not defined, this will size itself to fit all of its
          * children (i.e. a WrappedDimension).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContainerDimension getWidth() {
             if (mImpl.hasWidth()) {
@@ -3666,7 +3620,6 @@
          * Gets the height of this row. If not defined, this will size itself to fit all of its
          * children (i.e. a WrappedDimension).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ContainerDimension getHeight() {
             if (mImpl.hasHeight()) {
@@ -3677,7 +3630,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -3843,7 +3795,6 @@
         }
 
         /** Gets contents of this container. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public List<ArcLayoutElement> getContents() {
             List<ArcLayoutElement> list = new ArrayList<>();
@@ -3865,7 +3816,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DegreesProp getAnchorAngle() {
             if (mImpl.hasAnchorAngle()) {
@@ -3879,7 +3829,6 @@
          * Gets how to align the contents of this container relative to anchor_angle. If not
          * defined, defaults to ARC_ANCHOR_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ArcAnchorTypeProp getAnchorType() {
             if (mImpl.hasAnchorType()) {
@@ -3895,7 +3844,6 @@
          * should be drawn towards the inner or outer edge of the arc, or drawn in the center. If
          * not defined, defaults to VERTICAL_ALIGN_CENTER.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public VerticalAlignmentProp getVerticalAlign() {
             if (mImpl.hasVerticalAlign()) {
@@ -3906,7 +3854,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Modifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -4090,7 +4037,6 @@
         }
 
         /** Gets the text to render. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public StringProp getText() {
             if (mImpl.hasText()) {
@@ -4104,7 +4050,6 @@
          * Gets the style of font to use (size, bold etc). If not specified, defaults to the
          * platform's default body font.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public FontStyle getFontStyle() {
             if (mImpl.hasFontStyle()) {
@@ -4115,7 +4060,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ArcModifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -4256,7 +4200,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DegreesProp getLength() {
             if (mImpl.hasLength()) {
@@ -4267,7 +4210,6 @@
         }
 
         /** Gets the thickness of this line. If not defined, defaults to 0. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getThickness() {
             if (mImpl.hasThickness()) {
@@ -4285,7 +4227,6 @@
          *
          * <p>If a brush is set, this color will not be used.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ColorProp getColor() {
             if (mImpl.hasColor()) {
@@ -4299,7 +4240,6 @@
          * Gets a brush used to draw this line. If set, the brush will be used instead of the color
          * provided in {@code setColor()}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @Nullable
         public Brush getBrush() {
             if (mImpl.hasBrush()) {
@@ -4310,7 +4250,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ArcModifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -4321,7 +4260,6 @@
         }
 
         /** Gets the line stroke cap. If not defined, defaults to STROKE_CAP_ROUND. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public StrokeCapProp getStrokeCap() {
             if (mImpl.hasStrokeCap()) {
@@ -4335,7 +4273,6 @@
          * Gets the bounding constraints for the layout affected by the dynamic value from {@link
          * #getLength()}.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AngularLayoutConstraint getLayoutConstraintsForDynamicLength() {
             if (mImpl.hasLength()) {
@@ -4529,6 +4466,24 @@
                             "length with dynamic value requires "
                                     + "layoutConstraintsForDynamicLength to be present.");
                 }
+
+                String onlyOpaqueMsg = "Only opaque colors are supported";
+                String alphaChangeMsg =
+                        "Any transparent colors will have their alpha component set to 0xFF"
+                            + " (opaque).";
+                for (ColorProto.ColorStop colorStop :
+                        mImpl.getBrush().getSweepGradient().getColorStopsList()) {
+                    if (Color.alpha(colorStop.getColor().getArgb()) < 0xFF) {
+                        Log.w("ArcLine", onlyOpaqueMsg + " for SweepGradient. " + alphaChangeMsg);
+                        break;
+                    }
+                }
+                if (mImpl.getStrokeCap().hasShadow()
+                        && Color.alpha(mImpl.getColor().getArgb()) < 0xFF) {
+                    Log.w(
+                            "ArcLine",
+                            onlyOpaqueMsg + " when using StrokeCap Shadow. " + alphaChangeMsg);
+                }
                 return new ArcLine(mImpl.build(), mFingerprint);
             }
         }
@@ -4546,7 +4501,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @StrokeCap
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -4555,8 +4509,10 @@
         /**
          * Gets the stroke cap's shadow. When set, the stroke cap will be drawn with a shadow, which
          * allows it to be visible on top of other similarly colored elements.
+         *
+         * <p>Only opaque colors are supported in {@link ArcLine} if a shadow is set. Any
+         * transparent colors will have their alpha component set to 0xFF (opaque).
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @Nullable
         public Shadow getShadow() {
             if (mImpl.hasShadow()) {
@@ -4621,6 +4577,9 @@
             /**
              * Sets the stroke cap's shadow. When set, the stroke cap will be drawn with a shadow,
              * which allows it to be visible on top of other similarly colored elements.
+             *
+             * <p>Only opaque colors are supported in {@link ArcLine} if a shadow is set. Any
+             * transparent colors will have their alpha component set to 0xFF (opaque).
              */
             @RequiresSchemaVersion(major = 1, minor = 300)
             @NonNull
@@ -4651,7 +4610,6 @@
         }
 
         /** Gets the length of this spacer, in degrees. If not defined, defaults to 0. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DegreesProp getLength() {
             if (mImpl.hasLength()) {
@@ -4662,7 +4620,6 @@
         }
 
         /** Gets the thickness of this spacer, in DP. If not defined, defaults to 0. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getThickness() {
             if (mImpl.hasThickness()) {
@@ -4673,7 +4630,6 @@
         }
 
         /** Gets {@link androidx.wear.protolayout.ModifiersBuilders.Modifiers} for this element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ArcModifiers getModifiers() {
             if (mImpl.hasModifiers()) {
@@ -4808,7 +4764,6 @@
         }
 
         /** Gets the element to adapt to an {@link Arc}. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public LayoutElement getContent() {
             if (mImpl.hasContent()) {
@@ -4826,7 +4781,6 @@
          * rotate_contents = false, the image will be placed at the 3 o clock position, but itself
          * will not be rotated. If not defined, defaults to false.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public BoolProp getRotateContents() {
             if (mImpl.hasRotateContents()) {
@@ -4906,10 +4860,16 @@
              * be placed at the 3 o clock position, and will be rotated clockwise through 90
              * degrees. If rotate_contents = false, the image will be placed at the 3 o clock
              * position, but itself will not be rotated. If not defined, defaults to false.
+             *
+             * <p>Note that this field only supports static values.
              */
             @RequiresSchemaVersion(major = 1, minor = 0)
             @NonNull
             public Builder setRotateContents(@NonNull BoolProp rotateContents) {
+                if (rotateContents.getDynamicValue() != null) {
+                    throw new IllegalArgumentException(
+                            "ArcAdapter.Builder.setRotateContents doesn't support dynamic values.");
+                }
                 mImpl.setRotateContents(rotateContents.toProto());
                 mFingerprint.recordPropertyUpdate(
                         2, checkNotNull(rotateContents.getFingerprint()).aggregateValueAsInt());
@@ -4965,7 +4925,6 @@
          * Gets the content of the renderer extension element. This can be any data; it is expected
          * that the renderer extension knows how to parse this field.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public byte[] getPayload() {
             return mImpl.getPayload().toByteArray();
@@ -4975,14 +4934,12 @@
          * Gets the ID of the renderer extension that should be used for rendering this layout
          * element.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getExtensionId() {
             return mImpl.getExtensionId();
         }
 
         /** Gets the width of this element. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public ExtensionDimension getWidth() {
             if (mImpl.hasWidth()) {
@@ -4993,7 +4950,6 @@
         }
 
         /** Gets the height of this element. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public ExtensionDimension getHeight() {
             if (mImpl.hasHeight()) {
@@ -5245,7 +5201,6 @@
         }
 
         /** Gets the root element in the layout. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public LayoutElement getRoot() {
             if (mImpl.hasRoot()) {
@@ -5560,7 +5515,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @HorizontalAlignment
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -5640,7 +5594,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @VerticalAlignment
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -5720,7 +5673,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @TextAlignment
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -5799,7 +5751,6 @@
         }
 
         /** Gets the value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @ArcAnchorType
         public int getValue() {
             return mImpl.getValue().getNumber();
@@ -5891,7 +5842,7 @@
         public static FontStyle.Builder display1(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 54 : 50));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 54 : 50));
         }
 
         /**
@@ -5905,7 +5856,7 @@
         public static FontStyle.Builder display2(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 44 : 40));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 44 : 40));
         }
 
         /**
@@ -5919,7 +5870,7 @@
         public static FontStyle.Builder display3(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 34 : 30));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 34 : 30));
         }
 
         /**
@@ -5933,7 +5884,7 @@
         public static FontStyle.Builder title1(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 26 : 24));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 26 : 24));
         }
 
         /**
@@ -5947,7 +5898,7 @@
         public static FontStyle.Builder title2(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 22 : 20));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 22 : 20));
         }
 
         /**
@@ -5961,7 +5912,7 @@
         public static FontStyle.Builder title3(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 18 : 16));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 18 : 16));
         }
 
         /**
@@ -5974,7 +5925,7 @@
         @Deprecated
         public static FontStyle.Builder body1(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 18 : 16));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 18 : 16));
         }
 
         /**
@@ -5987,7 +5938,7 @@
         @Deprecated
         public static FontStyle.Builder body2(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 16 : 14));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 16 : 14));
         }
 
         /**
@@ -6001,7 +5952,7 @@
         public static FontStyle.Builder button(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
                     .setWeight(FONT_WEIGHT_BOLD)
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 16 : 14));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 16 : 14));
         }
 
         /**
@@ -6014,7 +5965,7 @@
         @Deprecated
         public static FontStyle.Builder caption1(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 16 : 14));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 16 : 14));
         }
 
         /**
@@ -6027,7 +5978,7 @@
         @Deprecated
         public static FontStyle.Builder caption2(@NonNull DeviceParameters deviceParameters) {
             return new FontStyle.Builder()
-                    .setSize(DimensionBuilders.sp(isLargeScreen(deviceParameters) ? 14 : 12));
+                    .setSize(sp(isLargeScreen(deviceParameters) ? 14 : 12));
         }
 
         private FontStyles() {}
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ModifiersBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ModifiersBuilders.java
index feb7cbb..51f3c14 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ModifiersBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ModifiersBuilders.java
@@ -61,6 +61,7 @@
          * Fade in enter animation that fades in element when entering the layout, from fully
          * invisible to fully visible.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         private static final EnterTransition FADE_IN_ENTER_TRANSITION =
                 new EnterTransition.Builder().setFadeIn(FADE_IN_TRANSITION).build();
 
@@ -70,6 +71,7 @@
          *
          * @param direction The direction for sliding in transition.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         private static SlideInTransition slideInTransition(@SlideDirection int direction) {
             return new SlideInTransition.Builder().setDirection(direction).build();
         }
@@ -78,6 +80,7 @@
          * Enter content transition animation that fades in element when entering the layout, from
          * fully invisible to fully visible.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public static EnterTransition fadeIn() {
             return FADE_IN_ENTER_TRANSITION;
@@ -87,6 +90,7 @@
          * Enter content transition animation that slides in element when entering the layout into
          * its position from the parent edge in the given direction.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public static EnterTransition slideIn(@SlideDirection int slideDirection) {
             return new EnterTransition.Builder()
@@ -101,6 +105,7 @@
          *
          * @param slideDirection The direction for sliding in part of transition.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public static EnterTransition fadeInSlideIn(@SlideDirection int slideDirection) {
             return new EnterTransition.Builder()
@@ -120,6 +125,7 @@
          * Fade out exit animation that fades out element when exiting the layout, from fully
          * visible to fully invisible.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         private static final ExitTransition FADE_OUT_EXIT_TRANSITION =
                 new ExitTransition.Builder().setFadeOut(FADE_OUT_TRANSITION).build();
 
@@ -129,6 +135,7 @@
          *
          * @param direction The direction for sliding out transition.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         private static SlideOutTransition slideOutTransition(@SlideDirection int direction) {
             return new SlideOutTransition.Builder().setDirection(direction).build();
         }
@@ -137,6 +144,7 @@
          * Exit content transition animation that fades out element when exiting the layout, from
          * fully visible to fully invisible.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public static ExitTransition fadeOut() {
             return FADE_OUT_EXIT_TRANSITION;
@@ -146,6 +154,7 @@
          * Exit content transition animation that slides out element when exiting the layout from
          * its position to the parent edge in the given direction.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public static ExitTransition slideOut(@SlideDirection int slideDirection) {
             return new ExitTransition.Builder()
@@ -160,6 +169,7 @@
          *
          * @param slideDirection The direction for sliding in part of transition.
          */
+        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public static ExitTransition fadeOutSlideOut(@SlideDirection int slideDirection) {
             return new ExitTransition.Builder()
@@ -305,14 +315,12 @@
         }
 
         /** Gets the ID associated with this action. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getId() {
             return mImpl.getId();
         }
 
         /** Gets the action to perform when the element this modifier is attached to is clicked. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Action getOnClick() {
             if (mImpl.hasOnClick()) {
@@ -329,7 +337,6 @@
          * that this value does not affect the layout, so the minimum clickable width is not
          * guaranteed unless there is enough space around the element within its parent bounds.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public DpProp getMinimumClickableWidth() {
             if (mImpl.hasMinimumClickableWidth()) {
@@ -346,7 +353,6 @@
          * that this value does not affect the layout, so the minimum clickable height is not
          * guaranteed unless there is enough space around the element within its parent bounds.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public DpProp getMinimumClickableHeight() {
             if (mImpl.hasMinimumClickableHeight()) {
@@ -500,7 +506,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public StringProp getContentDescription() {
             if (mImpl.hasContentDescription()) {
@@ -514,7 +519,6 @@
          * Gets the type of user interface element. Accessibility services might use this to
          * describe the element or do customizations.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @SemanticsRole
         public int getRole() {
             return mImpl.getRole().getNumber();
@@ -526,7 +530,6 @@
          *
          * <p>This field is bindable and will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public StringProp getStateDescription() {
             if (mImpl.hasStateDescription()) {
@@ -666,7 +669,6 @@
          * Gets the padding on the end of the content, depending on the layout direction, in DP and
          * the value of "rtl_aware".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getEnd() {
             if (mImpl.hasEnd()) {
@@ -680,7 +682,6 @@
          * Gets the padding on the start of the content, depending on the layout direction, in DP
          * and the value of "rtl_aware".
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getStart() {
             if (mImpl.hasStart()) {
@@ -691,7 +692,6 @@
         }
 
         /** Gets the padding at the top, in DP. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getTop() {
             if (mImpl.hasTop()) {
@@ -702,7 +702,6 @@
         }
 
         /** Gets the padding at the bottom, in DP. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getBottom() {
             if (mImpl.hasBottom()) {
@@ -718,7 +717,6 @@
          * of the container if the device is using an RTL locale). If false, start/end will always
          * map to left/right, accordingly.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public BoolProp getRtlAware() {
             if (mImpl.hasRtlAware()) {
@@ -860,10 +858,16 @@
              * start/end will follow the layout direction (i.e. start will refer to the right hand
              * side of the container if the device is using an RTL locale). If false, start/end will
              * always map to left/right, accordingly.
+             *
+             * <p>Note that this field only supports static values.
              */
             @RequiresSchemaVersion(major = 1, minor = 0)
             @NonNull
             public Builder setRtlAware(@NonNull BoolProp rtlAware) {
+                if (rtlAware.getDynamicValue() != null) {
+                    throw new IllegalArgumentException(
+                            "Padding.Builder.setRtlAware doesn't support dynamic values.");
+                }
                 mImpl.setRtlAware(rtlAware.toProto());
                 mFingerprint.recordPropertyUpdate(
                         5, checkNotNull(rtlAware.getFingerprint()).aggregateValueAsInt());
@@ -911,7 +915,6 @@
         }
 
         /** Gets the width of the border, in DP. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getWidth() {
             if (mImpl.hasWidth()) {
@@ -927,7 +930,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ColorProp getColor() {
             if (mImpl.hasColor()) {
@@ -1031,7 +1033,6 @@
         }
 
         /** Gets the radius of the corner in DP. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public DpProp getRadius() {
             if (mImpl.hasRadius()) {
@@ -1126,7 +1127,6 @@
          * <p>While this field is statically accessible from 1.0, it's only bindable since version
          * 1.2 and renderers supporting version 1.2 will use the dynamic value (if set).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ColorProp getColor() {
             if (mImpl.hasColor()) {
@@ -1141,7 +1141,6 @@
          * if it has a background color or border. If not defined, defaults to having a square
          * corner.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Corner getCorner() {
             if (mImpl.hasCorner()) {
@@ -1249,7 +1248,6 @@
          * Gets property describing the element with which it is associated. For use by libraries
          * building higher-level components only. This can be used to track component metadata.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public byte[] getTagData() {
             return mImpl.getTagData().toByteArray();
@@ -1337,7 +1335,6 @@
          * Gets the clickable property of the modified element. It allows its wrapped element to
          * have actions associated with it, which will be executed when the element is tapped.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Clickable getClickable() {
             if (mImpl.hasClickable()) {
@@ -1351,7 +1348,6 @@
          * Gets the semantics of the modified element. This can be used to add metadata to the
          * modified element (eg. screen reader content descriptions).
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Semantics getSemantics() {
             if (mImpl.hasSemantics()) {
@@ -1362,7 +1358,6 @@
         }
 
         /** Gets the padding of the modified element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Padding getPadding() {
             if (mImpl.hasPadding()) {
@@ -1373,7 +1368,6 @@
         }
 
         /** Gets the border of the modified element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Border getBorder() {
             if (mImpl.hasBorder()) {
@@ -1384,7 +1378,6 @@
         }
 
         /** Gets the background (with optional corner radius) of the modified element. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Background getBackground() {
             if (mImpl.hasBackground()) {
@@ -1398,7 +1391,6 @@
          * Gets metadata about an element. For use by libraries building higher-level components
          * only. This can be used to track component metadata.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public ElementMetadata getMetadata() {
             if (mImpl.hasMetadata()) {
@@ -1412,7 +1404,6 @@
          * Gets the content transition of an element. Any update to the element or its children will
          * trigger this animation for this element and everything underneath it.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @ProtoLayoutExperimental
         @Nullable
         public AnimatedVisibility getContentUpdateAnimation() {
@@ -1424,20 +1415,17 @@
         }
 
         /**
-         * Gets whether the attached element is hidden, or visible. If the element is hidden, then
+         * Gets whether the attached element is visible, or hidden. If the element is hidden, then
          * it will still consume space in the layout, but will not render any contents, nor will any
-         * children render any contents.
-         *
-         * <p>Note that a hidden element also cannot be clickable (i.e. a {@link Clickable} modifier
-         * would be ignored).
+         * children render any contents. Defaults to visible.
          */
         @ProtoLayoutExperimental
-        @Nullable
-        public BoolProp getHidden() {
-            if (mImpl.hasHidden()) {
-                return BoolProp.fromProto(mImpl.getHidden());
+        @NonNull
+        public BoolProp isVisible() {
+            if (mImpl.hasVisible()) {
+                return BoolProp.fromProto(mImpl.getVisible());
             } else {
-                return null;
+                return new BoolProp.Builder(true).build();
             }
         }
 
@@ -1492,8 +1480,8 @@
                     + getMetadata()
                     + ", contentUpdateAnimation="
                     + getContentUpdateAnimation()
-                    + ", hidden="
-                    + getHidden()
+                    + ", visible="
+                    + isVisible()
                     + "}";
         }
 
@@ -1593,22 +1581,23 @@
             }
 
             /**
-             * Sets whether the attached element is hidden, or visible. If the element is hidden,
+             * Sets whether the attached element is visible, or hidden. If the element is hidden,
              * then it will still consume space in the layout, but will not render any contents, nor
-             * will any children render any contents.
+             * will any children render any contents. Defaults to visible.
              *
              * <p>Note that a hidden element also cannot be clickable (i.e. a {@link Clickable}
              * modifier would be ignored).
              *
-             * <p>Defaults to false (i.e. not hidden).
+             * <p>This field is bindable and will use the dynamic value (if set).
              */
             @RequiresSchemaVersion(major = 1, minor = 300)
             @ProtoLayoutExperimental
+            @SuppressLint("MissingGetterMatchingBuilder")
             @NonNull
-            public Builder setHidden(@NonNull BoolProp hidden) {
-                mImpl.setHidden(hidden.toProto());
+            public Builder setVisible(@NonNull BoolProp visible) {
+                mImpl.setVisible(visible.toProto());
                 mFingerprint.recordPropertyUpdate(
-                        8, checkNotNull(hidden.getFingerprint()).aggregateValueAsInt());
+                        10, checkNotNull(visible.getFingerprint()).aggregateValueAsInt());
                 return this;
             }
 
@@ -1637,7 +1626,6 @@
         }
 
         /** Gets the content transition that is triggered when element enters the layout. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public EnterTransition getEnterTransition() {
             if (mImpl.hasEnterTransition()) {
@@ -1651,7 +1639,6 @@
          * Gets the content transition that is triggered when element exits the layout. Note that
          * indefinite exit animations are ignored.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public ExitTransition getExitTransition() {
             if (mImpl.hasExitTransition()) {
@@ -1756,7 +1743,6 @@
          * Gets the fading in animation for content transition of an element and its children
          * happening when entering the layout.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public FadeInTransition getFadeIn() {
             if (mImpl.hasFadeIn()) {
@@ -1770,7 +1756,6 @@
          * Gets the sliding in animation for content transition of an element and its children
          * happening when entering the layout.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public SlideInTransition getSlideIn() {
             if (mImpl.hasSlideIn()) {
@@ -1875,14 +1860,12 @@
          * Gets the starting alpha of the fade in transition. It should be between 0 and 1. If not
          * set, defaults to fully transparent, i.e. 0.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @FloatRange(from = 0.0, to = 1.0)
         public float getInitialAlpha() {
             return mImpl.getInitialAlpha();
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -1987,7 +1970,6 @@
          * point to its destination in the layout. If not set, defaults to horizontal from left to
          * the right.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @SlideDirection
         public int getDirection() {
             return mImpl.getDirection().getNumber();
@@ -1999,7 +1981,6 @@
          * Note that sliding from the screen boundaries can only be achieved if all parent's sizes
          * are big enough to accommodate it.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public SlideBound getInitialSlideBound() {
             if (mImpl.hasInitialSlideBound()) {
@@ -2010,7 +1991,6 @@
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -2132,7 +2112,6 @@
          * Gets the fading out animation for content transition of an element and its children
          * happening when exiting the layout.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public FadeOutTransition getFadeOut() {
             if (mImpl.hasFadeOut()) {
@@ -2146,7 +2125,6 @@
          * Gets the sliding out animation for content transition of an element and its children
          * happening when exiting the layout.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public SlideOutTransition getSlideOut() {
             if (mImpl.hasSlideOut()) {
@@ -2257,14 +2235,12 @@
          * Gets the target alpha of the fade out transition. It should be between 0 and 1. If not
          * set, defaults to fully invisible, i.e. 0.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @FloatRange(from = 0.0, to = 1.0)
         public float getTargetAlpha() {
             return mImpl.getTargetAlpha();
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -2326,7 +2302,6 @@
              * Sets the target alpha of the fade out transition. It should be between 0 and 1. If
              * not set, defaults to fully invisible, i.e. 0.
              */
-            @RequiresSchemaVersion(major = 1, minor = 200)
             @NonNull
             public Builder setTargetAlpha(@FloatRange(from = 0.0, to = 1.0) float targetAlpha) {
                 mImpl.setTargetAlpha(targetAlpha);
@@ -2370,7 +2345,6 @@
          * in the layout to the specified point. If not set, defaults to horizontal from right to
          * the left.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @SlideDirection
         public int getDirection() {
             return mImpl.getDirection().getNumber();
@@ -2382,7 +2356,6 @@
          * that sliding from the screen boundaries can only be achieved if all parent's sizes are
          * big enough to accommodate it.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public SlideBound getTargetSlideBound() {
             if (mImpl.hasTargetSlideBound()) {
@@ -2393,7 +2366,6 @@
         }
 
         /** Gets the animation parameters for duration, delay, etc. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public AnimationSpec getAnimationSpec() {
             if (mImpl.hasAnimationSpec()) {
@@ -2472,7 +2444,6 @@
              * Note that sliding from the screen boundaries can only be achieved if all parent's
              * sizes are big enough to accommodate it.
              */
-            @RequiresSchemaVersion(major = 1, minor = 200)
             @NonNull
             public Builder setTargetSlideBound(@NonNull SlideBound targetSlideBound) {
                 mImpl.setTargetSlideBound(targetSlideBound.toSlideBoundProto());
@@ -2557,7 +2528,6 @@
          * Gets the snap options to use when sliding using parent boundaries. Defaults to
          * SLIDE_PARENT_SNAP_TO_INSIDE if not specified.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @SlideParentSnapOption
         public int getSnapTo() {
             return mImpl.getSnapTo().getNumber();
@@ -2652,7 +2622,6 @@
          * Gets allows its wrapped element to have actions associated with it, which will be
          * executed when the element is tapped.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Clickable getClickable() {
             if (mImpl.hasClickable()) {
@@ -2666,7 +2635,6 @@
          * Gets adds metadata for the modified element, for example, screen reader content
          * descriptions.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Semantics getSemantics() {
             if (mImpl.hasSemantics()) {
@@ -2776,7 +2744,6 @@
          * Gets allows its wrapped element to have actions associated with it, which will be
          * executed when the element is tapped.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Clickable getClickable() {
             if (mImpl.hasClickable()) {
@@ -2864,7 +2831,6 @@
          * Gets the blur radius of the shadow. It controls the size of the blur that is drawn. When
          * set to zero, the shadow is not drawn. Defaults to zero.
          */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public DpProp getBlurRadius() {
             if (mImpl.hasBlurRadius()) {
@@ -2875,7 +2841,6 @@
         }
 
         /** Gets the color used in the shadow. Defaults to Black. */
-        @RequiresSchemaVersion(major = 1, minor = 300)
         @NonNull
         public ColorProp getColor() {
             if (mImpl.hasColor()) {
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java
index 040ead2..8fdc539 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ResourceBuilders.java
@@ -101,7 +101,6 @@
          * Gets the Android resource ID of this image. This must refer to a drawable under
          * R.drawable.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @DrawableRes
         public int getResourceId() {
             return mImpl.getResourceId();
@@ -168,7 +167,6 @@
         }
 
         /** Gets the byte array representing the image. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public byte[] getData() {
             return mImpl.getData().toByteArray();
@@ -178,7 +176,6 @@
          * Gets the native width of the image, in pixels. Only required for formats (e.g.
          * IMAGE_FORMAT_RGB_565) where the image data does not include size.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Dimension(unit = PX)
         public int getWidthPx() {
             return mImpl.getWidthPx();
@@ -188,7 +185,6 @@
          * Gets the native height of the image, in pixels. Only required for formats (e.g.
          * IMAGE_FORMAT_RGB_565) where the image data does not include size.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Dimension(unit = PX)
         public int getHeightPx() {
             return mImpl.getHeightPx();
@@ -200,7 +196,6 @@
          * from the raw image data. If the platform does not support the format, the image will not
          * be decoded or displayed.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @ImageFormat
         public int getFormat() {
             return mImpl.getFormat().getNumber();
@@ -310,21 +305,18 @@
         }
 
         /** Gets the format for the animated image. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @AnimatedImageFormat
         public int getAnimatedImageFormat() {
             return mImpl.getAnimatedImageFormat().getNumber();
         }
 
         /** Gets the Android resource ID, e.g. R.drawable.foo. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @DrawableRes
         public int getResourceId() {
             return mImpl.getResourceId();
         }
 
         /** Gets the trigger to start the animation. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public Trigger getStartTrigger() {
             if (mImpl.hasStartTrigger()) {
@@ -418,14 +410,12 @@
         }
 
         /** Gets the format for the animated image. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @AnimatedImageFormat
         public int getAnimatedImageFormat() {
             return mImpl.getAnimatedImageFormat().getNumber();
         }
 
         /** Gets the Android resource ID, e.g. R.drawable.foo. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @DrawableRes
         public int getResourceId() {
             return mImpl.getResourceId();
@@ -441,7 +431,6 @@
          * new value on subsequent updates. If not set, the animation will play on load (similar to
          * a non-seekable animated).
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getProgress() {
             if (mImpl.hasProgress()) {
@@ -542,7 +531,6 @@
         }
 
         /** Gets an image resource that maps to an Android drawable by resource ID. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public AndroidImageResourceByResId getAndroidResourceByResId() {
             if (mImpl.hasAndroidResourceByResId()) {
@@ -553,7 +541,6 @@
         }
 
         /** Gets an image resource that contains the image data inline. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public InlineImageResource getInlineResource() {
             if (mImpl.hasInlineResource()) {
@@ -567,7 +554,6 @@
          * Gets a non-seekable animated image resource that maps to an Android drawable by resource
          * ID. The animation is started with given trigger, fire and forget.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         @ProtoLayoutExperimental
         public AndroidAnimatedImageResourceByResId getAndroidAnimatedResourceByResId() {
@@ -583,7 +569,6 @@
          * Gets a seekable animated image resource that maps to an Android drawable by resource ID.
          * The animation progress is bound to the provided dynamic float.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         @ProtoLayoutExperimental
         public AndroidSeekableAnimatedImageResourceByResId
@@ -708,14 +693,12 @@
          * layout to render successfully, and must match the resource version specified in
          * ResourcesRequest which triggered this request.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getVersion() {
             return mImpl.getVersion();
         }
 
         /** Gets a map of resource_ids to images, which can be used by layouts. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public Map<String, ImageResource> getIdToImageMapping() {
             Map<String, ImageResource> map = new HashMap<>();
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
index 4337153..2213aac 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
@@ -68,14 +68,12 @@
         }
 
         /** Gets the ID of the clickable that was last clicked. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getLastClickableId() {
             return mImpl.getLastClickableId();
         }
 
         /** Gets any shared state between the provider and renderer. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public Map<AppDataKey<?>, DynamicDataValue<?>> getKeyToValueMapping() {
             Map<AppDataKey<?>, DynamicDataValue<?>> map = new HashMap<>();
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TimelineBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TimelineBuilders.java
index fe536cd..4731b4c 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TimelineBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TimelineBuilders.java
@@ -47,13 +47,11 @@
         }
 
         /** Gets starting point of the time interval, in milliseconds since the Unix epoch. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public long getStartMillis() {
             return mImpl.getStartMillis();
         }
 
         /** Gets end point of the time interval, in milliseconds since the Unix epoch. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public long getEndMillis() {
             return mImpl.getEndMillis();
         }
@@ -125,7 +123,6 @@
         }
 
         /** Gets the validity period for this timeline entry. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public TimeInterval getValidity() {
             if (mImpl.hasValidity()) {
@@ -136,7 +133,6 @@
         }
 
         /** Gets the contents of this timeline entry. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @Nullable
         public Layout getLayout() {
             if (mImpl.hasLayout()) {
@@ -229,7 +225,6 @@
         }
 
         /** Gets the entries in a timeline. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public List<TimelineEntry> getTimelineEntries() {
             List<TimelineEntry> list = new ArrayList<>();
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java
index d712043..ab09eba 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TriggerBuilders.java
@@ -42,6 +42,7 @@
      * Creates a {@link Trigger} that fires *every time* the condition switches from false to true.
      * If the condition is true initially, that will fire the trigger on load.
      */
+    @RequiresSchemaVersion(major = 1, minor = 200)
     @NonNull
     public static Trigger createOnConditionMetTrigger(@NonNull DynamicBool dynamicBool) {
         return new OnConditionMetTrigger.Builder().setCondition(dynamicBool).build();
@@ -132,7 +133,6 @@
         }
 
         /** Gets dynamic boolean used as trigger. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getCondition() {
             if (mImpl.hasCondition()) {
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TypeBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TypeBuilders.java
index 049dd38..96f7117 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TypeBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/TypeBuilders.java
@@ -55,14 +55,12 @@
          * Gets the text string to use as the pattern for the largest text that can be laid out.
          * Used to ensure that the layout is of a known size during the layout pass.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @NonNull
         public String getPatternForLayout() {
             return mImpl.getValueForLayout();
         }
 
         /** Gets angular alignment of the actual content within the space reserved by value. */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @LayoutElementBuilders.TextAlignment
         public int getAlignment() {
             return mImpl.getTextAlignmentForLayoutValue();
@@ -146,7 +144,6 @@
         }
 
         /** Gets the static value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public int getValue() {
             return mImpl.getValue();
         }
@@ -225,7 +222,6 @@
          * values for the corresponding field, this static value will be ignored. If the static
          * value is not specified, {@code null} will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         @NonNull
         public String getValue() {
             return mImpl.getValue();
@@ -236,7 +232,6 @@
          * required to be set to support older renderers that only read the static value. If {@code
          * dynamicValue} has an invalid result, the provided static value will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicString getDynamicValue() {
             if (mImpl.hasDynamicValue()) {
@@ -366,7 +361,6 @@
          * values for the corresponding field, this static value will be ignored. If the static
          * value is not specified, zero will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 0)
         public float getValue() {
             return mImpl.getValue();
         }
@@ -376,7 +370,6 @@
          * required to be set to support older renderers that only read the static value. If {@code
          * dynamicValue} has an invalid result, the provided static value will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicFloat getDynamicValue() {
             if (mImpl.hasDynamicValue()) {
@@ -501,8 +494,11 @@
             this.mFingerprint = fingerprint;
         }
 
-        /** Gets the static value. */
-        @RequiresSchemaVersion(major = 1, minor = 0)
+        /**
+         * Gets the static value. If a dynamic value is also set and the renderer supports dynamic
+         * values for the corresponding field, this static value will be ignored. If the static
+         * value is not specified, false will be used instead.
+         */
         public boolean getValue() {
             return mImpl.getValue();
         }
@@ -512,7 +508,6 @@
          * required to be set to support older renderers that only read the static value. If {@code
          * dynamicValue} has an invalid result, the provided static value will be used instead.
          */
-        @RequiresSchemaVersion(major = 1, minor = 200)
         @Nullable
         public DynamicBool getDynamicValue() {
             if (mImpl.hasDynamicValue()) {
@@ -552,7 +547,12 @@
         @Override
         @NonNull
         public String toString() {
-            return "BoolProp{" + "value=" + getValue() + "}";
+            return "BoolProp{"
+                    + "value="
+                    + getValue()
+                    + ", dynamicValue="
+                    + getDynamicValue()
+                    + "}";
         }
 
         /** Builder for {@link BoolProp} */
@@ -576,7 +576,11 @@
             @Deprecated
             public Builder() {}
 
-            /** Sets the static value. */
+            /**
+             * Sets the static value. If a dynamic value is also set and the renderer supports
+             * dynamic values for the corresponding field, this static value will be ignored. If the
+             * static value is not specified, false will be used instead.
+             */
             @RequiresSchemaVersion(major = 1, minor = 0)
             @SuppressLint("MissingGetterMatchingBuilder")
             @NonNull
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
index c4eb4e1..a8352c8 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
@@ -323,7 +323,7 @@
         int[] expectedSizes = {size1, size2, lastSize};
         LayoutElementBuilders.FontStyle fontStyle =
                 new LayoutElementBuilders.FontStyle.Builder()
-                        .setSizes(sp(size1), sp(size2), sp(lastSize))
+                        .setSizes(size1, size2, lastSize)
                         .build();
 
         LayoutElementProto.FontStyle fontStyleProto = fontStyle.toProto();
@@ -367,7 +367,7 @@
         LayoutElementBuilders.FontStyle fontStyle =
                 new LayoutElementBuilders.FontStyle.Builder()
                         .setSize(sp(20))
-                        .setSizes(sp(size1), sp(size2))
+                        .setSizes(size1, size2)
                         .build();
 
         LayoutElementProto.FontStyle fontStyleProto = fontStyle.toProto();
@@ -385,21 +385,30 @@
 
     @Test
     public void testFontStyleSetSize_tooManySizes_throws() {
-        DimensionBuilders.SpProp[] sizes =
-                new DimensionBuilders.SpProp
-                        [LayoutElementBuilders.FontStyle.Builder.TEXT_SIZES_LIMIT + 1];
+        int[] sizes =
+                new int[LayoutElementBuilders.FontStyle.Builder.TEXT_SIZES_LIMIT + 1];
         assertThrows(
                 IllegalArgumentException.class,
                 () -> new LayoutElementBuilders.FontStyle.Builder().setSizes(sizes).build());
     }
 
     @Test
-    public void testFontStyleSetSize_allNegativeOrZero_throws() {
+    public void testFontStyleSetSize_atLeastOneNegative_throws() {
         assertThrows(
                 IllegalArgumentException.class,
                 () ->
                         new LayoutElementBuilders.FontStyle.Builder()
-                                .setSizes(sp(-1), sp(0))
+                                .setSizes(-1, 5, 1)
+                                .build());
+    }
+
+    @Test
+    public void testFontStyleSetSize_atLeastOneZero_throws() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        new LayoutElementBuilders.FontStyle.Builder()
+                                .setSizes(1, 2, 0)
                                 .build());
     }
 
diff --git a/wear/tiles/tiles-tooling-preview/build.gradle b/wear/tiles/tiles-tooling-preview/build.gradle
index 95af193..8e93c514 100644
--- a/wear/tiles/tiles-tooling-preview/build.gradle
+++ b/wear/tiles/tiles-tooling-preview/build.gradle
@@ -28,7 +28,7 @@
     implementation(project(":wear:protolayout:protolayout-proto"))
     implementation(project(":wear:tiles:tiles"))
 
-    api("androidx.wear:wear-tooling-preview:1.0.0-alpha01")
+    api("androidx.wear:wear-tooling-preview:1.0.0")
     api("androidx.annotation:annotation:1.6.0")
 }
 
diff --git a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Data.kt b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Data.kt
index ff20104..ea4cc25 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Data.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Data.kt
@@ -124,10 +124,10 @@
  * @property dataSource The [ComponentName] of the
  *   [androidx.wear.watchface.complications.datasource.ComplicationDataSourceService] that provided
  *   the ComplicationData. This may be `null` when run on old systems.
- * @property persistencePolicy The [ComplicationPersistencePolicy] for this complication. This
- *   requires the watchface to be built with a compatible library to work.
- * @property displayPolicy The [ComplicationDisplayPolicy] for this complication. This requires the
- *   watchface to be built with a compatible library to work.
+ * @property persistencePolicy The [persistence policy][ComplicationPersistencePolicies] for this
+ *   complication. This requires the watchface to be built with a compatible library to work.
+ * @property displayPolicy The [display policy][ComplicationDisplayPolicies] for this complication.
+ *   This requires the watchface to be built with a compatible library to work.
  * @property dynamicValueInvalidationFallback Used in case any dynamic value has been invalidated.
  *
  *   IMPORTANT: This is only used when the system supports dynamic values. See each dynamic field's
@@ -255,7 +255,7 @@
             return this as BuilderT
         }
 
-        /** Sets the complication's [ComplicationPersistencePolicy]. */
+        /** Sets the complication's [persistence policy][ComplicationPersistencePolicies]. */
         @Suppress("UNCHECKED_CAST", "SetterReturnsThis")
         @RequiresApi(Build.VERSION_CODES.TIRAMISU)
         public fun setPersistencePolicy(
@@ -265,7 +265,7 @@
             return this as BuilderT
         }
 
-        /** Sets the complication's [ComplicationDisplayPolicy]. */
+        /** Sets the complication's [display policy][ComplicationDisplayPolicies]. */
         @Suppress("UNCHECKED_CAST", "SetterReturnsThis")
         @RequiresApi(Build.VERSION_CODES.TIRAMISU)
         public fun setDisplayPolicy(@ComplicationDisplayPolicy displayPolicy: Int): BuilderT {
diff --git a/wear/wear-phone-interactions/api/current.txt b/wear/wear-phone-interactions/api/current.txt
index 0be3c03..6013a71 100644
--- a/wear/wear-phone-interactions/api/current.txt
+++ b/wear/wear-phone-interactions/api/current.txt
@@ -74,11 +74,17 @@
     method @UiThread public void close();
     method public static androidx.wear.phone.interactions.authentication.RemoteAuthClient create(android.content.Context context);
     method protected void finalize();
+    method public kotlinx.coroutines.flow.Flow<java.lang.Integer> getAvailabilityStatus();
     method @UiThread public void sendAuthorizationRequest(androidx.wear.phone.interactions.authentication.OAuthRequest request, java.util.concurrent.Executor executor, androidx.wear.phone.interactions.authentication.RemoteAuthClient.Callback clientCallback);
+    property public final kotlinx.coroutines.flow.Flow<java.lang.Integer> availabilityStatus;
     field public static final androidx.wear.phone.interactions.authentication.RemoteAuthClient.Companion Companion;
     field public static final int ERROR_PHONE_UNAVAILABLE = 1; // 0x1
     field public static final int ERROR_UNSUPPORTED = 0; // 0x0
     field public static final int NO_ERROR = -1; // 0xffffffff
+    field public static final int STATUS_AVAILABLE = 3; // 0x3
+    field public static final int STATUS_TEMPORARILY_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
   }
 
   public abstract static class RemoteAuthClient.Callback {
diff --git a/wear/wear-phone-interactions/api/restricted_current.txt b/wear/wear-phone-interactions/api/restricted_current.txt
index 0ee9fd0..d0e17bc 100644
--- a/wear/wear-phone-interactions/api/restricted_current.txt
+++ b/wear/wear-phone-interactions/api/restricted_current.txt
@@ -74,11 +74,17 @@
     method @UiThread public void close();
     method public static androidx.wear.phone.interactions.authentication.RemoteAuthClient create(android.content.Context context);
     method protected void finalize();
+    method public kotlinx.coroutines.flow.Flow<java.lang.Integer> getAvailabilityStatus();
     method @UiThread public void sendAuthorizationRequest(androidx.wear.phone.interactions.authentication.OAuthRequest request, java.util.concurrent.Executor executor, androidx.wear.phone.interactions.authentication.RemoteAuthClient.Callback clientCallback);
+    property public final kotlinx.coroutines.flow.Flow<java.lang.Integer> availabilityStatus;
     field public static final androidx.wear.phone.interactions.authentication.RemoteAuthClient.Companion Companion;
     field public static final int ERROR_PHONE_UNAVAILABLE = 1; // 0x1
     field public static final int ERROR_UNSUPPORTED = 0; // 0x0
     field public static final int NO_ERROR = -1; // 0xffffffff
+    field public static final int STATUS_AVAILABLE = 3; // 0x3
+    field public static final int STATUS_TEMPORARILY_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
   }
 
   public abstract static class RemoteAuthClient.Callback {
diff --git a/wear/wear-phone-interactions/build.gradle b/wear/wear-phone-interactions/build.gradle
index 0406deb..0403497 100644
--- a/wear/wear-phone-interactions/build.gradle
+++ b/wear/wear-phone-interactions/build.gradle
@@ -28,6 +28,7 @@
     api("androidx.core:core:1.6.0")
     api("androidx.wear:wear:1.2.0")
     api(libs.kotlinStdlib)
+    api(libs.kotlinCoroutinesCore)
 
     // Needed for Assert.assertThrows
     testImplementation(libs.junit)
@@ -37,6 +38,13 @@
     testImplementation(libs.robolectric)
     testImplementation(libs.mockitoCore4)
     testImplementation(libs.truth)
+    testImplementation(libs.mockitoKotlin4)
+
+    // Includes the wear-sdk jar
+    compileOnly files("../../wear/wear_sdk/wear-sdk.jar")
+    testImplementation(files("../../wear/wear_sdk/wear-sdk.jar"))
+
+    samples(project(":wear:wear-phone-interactions-samples"))
 }
 
 android {
diff --git a/wear/wear-phone-interactions/samples/build.gradle b/wear/wear-phone-interactions/samples/build.gradle
new file mode 100644
index 0000000..3d3f23f
--- /dev/null
+++ b/wear/wear-phone-interactions/samples/build.gradle
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+import androidx.build.LibraryType
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+}
+
+dependencies {
+    implementation(libs.kotlinStdlib)
+    implementation(project(":wear:wear-phone-interactions"))
+
+    compileOnly(project(":annotation:annotation-sampled"))
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 25
+    }
+    namespace "androidx.wear.phone.interactions.samples"
+}
+
+androidx {
+    name = "Android Wear Phone Interactions Samples"
+    type = LibraryType.SAMPLES
+    mavenVersion = LibraryVersions.WEAR_PHONE_INTERACTIONS
+    inceptionYear = "2023"
+    description = "Contains the sample code for the Android Wear Phone Interactions Classes"
+}
\ No newline at end of file
diff --git a/wear/wear-phone-interactions/samples/src/main/AndroidManifest.xml b/wear/wear-phone-interactions/samples/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3dc010d
--- /dev/null
+++ b/wear/wear-phone-interactions/samples/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+</manifest>
\ No newline at end of file
diff --git a/wear/wear-phone-interactions/samples/src/main/java/androidx/wear/phone/interactions/samples/RemoteAuthClientSample.kt b/wear/wear-phone-interactions/samples/src/main/java/androidx/wear/phone/interactions/samples/RemoteAuthClientSample.kt
new file mode 100644
index 0000000..baeafa8
--- /dev/null
+++ b/wear/wear-phone-interactions/samples/src/main/java/androidx/wear/phone/interactions/samples/RemoteAuthClientSample.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.wear.phone.interactions.samples
+
+import androidx.annotation.Sampled
+import androidx.wear.phone.interactions.authentication.OAuthRequest
+import androidx.wear.phone.interactions.authentication.RemoteAuthClient
+
+@Sampled
+suspend fun AuthAvailabilitySample(
+    remoteAuthClient: RemoteAuthClient,
+    oAuthRequest: OAuthRequest,
+    myAuthCallback: RemoteAuthClient.Callback
+) {
+    remoteAuthClient.availabilityStatus.collect {
+        status -> when (status) {
+            RemoteAuthClient.STATUS_UNAVAILABLE ->
+                TODO("Present alternative flow as remote auth is not available")
+            RemoteAuthClient.STATUS_TEMPORARILY_UNAVAILABLE ->
+                TODO("Present education to user to connect devices or bring to proximity.")
+            RemoteAuthClient.STATUS_AVAILABLE, RemoteAuthClient.STATUS_UNKNOWN ->
+                // Present normal auth flow when we don't know (old devices)
+                // or when we know it is available.
+                remoteAuthClient.sendAuthorizationRequest(
+                    oAuthRequest,
+                    Runnable::run,
+                    myAuthCallback)
+        } }
+}
diff --git a/wear/wear-phone-interactions/src/main/AndroidManifest.xml b/wear/wear-phone-interactions/src/main/AndroidManifest.xml
index 3082842..4938f5f 100644
--- a/wear/wear-phone-interactions/src/main/AndroidManifest.xml
+++ b/wear/wear-phone-interactions/src/main/AndroidManifest.xml
@@ -16,4 +16,9 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+  <application>
+    <uses-library
+        android:name="wear-sdk"
+        android:required="false"/>
+  </application>
 </manifest>
diff --git a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/IRemoteInteractionsManager.kt b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/IRemoteInteractionsManager.kt
new file mode 100644
index 0000000..48b046e
--- /dev/null
+++ b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/IRemoteInteractionsManager.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.wear.phone.interactions.authentication
+
+import com.google.wear.services.remoteinteractions.RemoteInteractionsManager
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+
+/**
+ * Forwards remote auth interaction availabilities to [RemoteInteractionsManager].
+ */
+internal interface IRemoteInteractionsManager {
+
+    /** Whether the availability status API is supported. */
+    val isAvailabilityStatusApiSupported: Boolean
+
+    /** Forwards a call [registerRemoteAuthClientStatusListener] to [RemoteInteractionsManager.registerRemoteAuthClientStatusListener]. */
+    fun registerRemoteAuthClientStatusListener(executor: Executor, listener: Consumer<Int>)
+
+    /** Forwards a call [unregisterRemoteAuthClientStatusListener] to [RemoteInteractionsManager.unregisterRemoteAuthClientStatusListener]. */
+    fun unregisterRemoteAuthClientStatusListener(listener: Consumer<Int>)
+}
diff --git a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt
index 8a95f2d..0b2a3b0 100644
--- a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt
+++ b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt
@@ -32,6 +32,11 @@
 import java.util.ArrayDeque
 import java.util.Queue
 import java.util.concurrent.Executor
+import java.util.function.Consumer
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.flowOf
 
 /**
  * Provides a client for supporting remote authentication on Wear. The authentication session
@@ -86,6 +91,7 @@
  * ```
  */
 public class RemoteAuthClient internal constructor(
+    private val remoteInteractionsManager: IRemoteInteractionsManager,
     private val serviceBinder: ServiceBinder,
     private val uiThreadExecutor: Executor,
     private val packageName: String
@@ -130,6 +136,32 @@
         internal const val ACTION_AUTH: String =
             "android.support.wearable.authentication.action.OAUTH"
 
+        /**
+         * The remote auth's availability is unknown.
+         *
+         * On older devices, [STATUS_UNKNOWN] is returned as we can not determine the availability states. To preserve
+         * compatibility with existing devices behavior, try [sendAuthorizationRequest] and handle
+         * error codes accordingly.
+         */
+        public const val STATUS_UNKNOWN = 0
+
+        /**
+         * Indicates that remote auth is unavailable because there is no paired device capable of handling the remote interaction.
+         */
+        public const val STATUS_UNAVAILABLE = 1
+
+        /**
+         * Indicates that remote auth is temporarily unavailable.
+         *
+         * There is a known paired device, but it is not currently connected or reachable to handle the remote interaction.
+         */
+        public const val STATUS_TEMPORARILY_UNAVAILABLE = 2
+
+        /**
+         * Indicates that remote auth is available with a connected device capable to handle the remote interaction.
+         */
+        public const val STATUS_AVAILABLE = 3
+
         /** Indicates 3p authentication is finished without error  */
         public const val NO_ERROR: Int = -1
 
@@ -158,6 +190,7 @@
         public fun create(context: Context): RemoteAuthClient {
             val appContext: Context = context.applicationContext
             return RemoteAuthClient(
+                RemoteInteractionsManagerCompat(appContext),
                 object : ServiceBinder {
                     override fun bindService(
                         intent: Intent,
@@ -210,6 +243,50 @@
     }
 
     /**
+     * Returns status indicating whether remote auth operation (such as [sendAuthorizationRequest]) is available.
+     *
+     * In scenarios of restricted connection or temporary disconnection with a paired device,
+     * remote auth operations will not be available. Please check status before [sendAuthorizationRequest]
+     * to provide better experience for the user.
+     *
+     * On older wear devices which do not support availability status, it will always return [STATUS_UNKNOWN].
+     * Wear devices start to support determining the availability status from Wear Sdk WEAR_TIRAMISU_4.
+     *
+     * @sample androidx.wear.phone.interactions.samples.AuthAvailabilitySample
+     *
+     * @return a [Flow] with a stream of status updates that could be one of [STATUS_UNKNOWN],
+     *   [STATUS_UNAVAILABLE], [STATUS_TEMPORARILY_UNAVAILABLE], [STATUS_AVAILABLE].
+     *
+     */
+    public val availabilityStatus: Flow<Int> get() {
+        if (!remoteInteractionsManager.isAvailabilityStatusApiSupported) {
+            return flowOf(STATUS_UNKNOWN)
+        }
+
+        return getRemoteAuthAvailableInternal()
+    }
+
+    private fun getRemoteAuthAvailableInternal(): Flow<Int> {
+        return callbackFlow {
+            val callback =
+                object : Consumer<Int> {
+                    override fun accept(value: Int) {
+                        // Emit WearSDK values through AndroidX with 1:1 mapping.
+                        trySend(value)
+                    }
+                }
+
+            remoteInteractionsManager
+                .registerRemoteAuthClientStatusListener(Runnable::run, callback)
+
+            awaitClose {
+                remoteInteractionsManager
+                    .unregisterRemoteAuthClientStatusListener(callback)
+            }
+        }
+    }
+
+    /**
      * Send a remote auth request. This will cause an authorization UI to be presented on
      * the user's phone.
      * This request is asynchronous; the callback provided will be be notified when the request
diff --git a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteInteractionsManagerCompat.kt b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteInteractionsManagerCompat.kt
new file mode 100644
index 0000000..44b0fcb
--- /dev/null
+++ b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteInteractionsManagerCompat.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.wear.phone.interactions.authentication
+
+import android.content.Context
+import com.google.wear.Sdk
+import com.google.wear.services.remoteinteractions.RemoteInteractionsManager
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+
+/**
+ * Forwards remote auth interaction availabilities to [RemoteInteractionsManager].
+ */
+internal open class RemoteInteractionsManagerCompat(context: Context) : IRemoteInteractionsManager {
+
+    // TODO(b/307543793): Reuse the generalized `WearApiVersionHelper` once available.
+    private val wearApiVersion: WearApiVersion = WearApiVersion()
+
+    private val remoteInteractionsManager: RemoteInteractionsManager? =
+        if (isAvailabilityStatusApiSupported)
+            Sdk.getWearManager(context, RemoteInteractionsManager::class.java)
+        else
+            null
+
+    override val isAvailabilityStatusApiSupported: Boolean
+        get() = wearApiVersion.wearSdkVersion >= 4
+
+    override fun registerRemoteAuthClientStatusListener(
+        executor: Executor,
+        listener: Consumer<Int>
+    ) {
+        if (isAvailabilityStatusApiSupported) {
+            remoteInteractionsManager!!.registerRemoteAuthClientStatusListener(
+                executor,
+                listener
+            )
+        } else {
+            throw UnsupportedOperationException("Should not call wear sdk when not supported.")
+        }
+    }
+
+    override fun unregisterRemoteAuthClientStatusListener(listener: Consumer<Int>) {
+        if (isAvailabilityStatusApiSupported) {
+            remoteInteractionsManager!!.unregisterRemoteAuthClientStatusListener(
+                listener
+            )
+        } else {
+            throw UnsupportedOperationException("Should not call wear sdk when not supported.")
+        }
+    }
+}
diff --git a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/WearApiVersion.kt b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/WearApiVersion.kt
new file mode 100644
index 0000000..79a2ada
--- /dev/null
+++ b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/WearApiVersion.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.wear.phone.interactions.authentication
+
+import android.os.Build
+import com.google.wear.Sdk
+
+/**
+ * Provides wear sdk api version.
+ */
+internal class WearApiVersion {
+
+    // TODO(b/307543793): Reuse the generalized `WearApiVersionHelper` once available.
+    /** Exposes version of wear sdk. Returns 0 if wear-sdk is not present. */
+    val wearSdkVersion: Int
+        get() {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                // Wear SDK INT can only be accessed safely from UPSIDE_DOWN_CAKE, introduced from tiramisu kr2.
+                // Or crashes with `NoSuchField` will be experienced.
+                return Sdk.VERSION.WEAR_SDK_INT
+            }
+            return 0
+        }
+}
diff --git a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
index f53fb50..6c881c7 100644
--- a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
+++ b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
@@ -30,9 +30,19 @@
 import androidx.wear.phone.interactions.WearPhoneInteractionsTestRunner
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.Executor
+import java.util.function.Consumer
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.runBlocking
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import org.robolectric.Shadows
 import org.robolectric.annotation.Config
 import org.robolectric.annotation.internal.DoNotInstrument
@@ -90,8 +100,13 @@
 
     private var fakeServiceBinder: FakeServiceBinder = FakeServiceBinder()
     private var fakeService: FakeClockworkHomeAuthService = FakeClockworkHomeAuthService()
+    private val remoteInteractionsManager: IRemoteInteractionsManager = mock()
     private var clientUnderTest: RemoteAuthClient =
-        RemoteAuthClient(fakeServiceBinder, DIRECT_EXECUTOR, appPackageName)
+        RemoteAuthClient(
+            remoteInteractionsManager,
+            fakeServiceBinder,
+            DIRECT_EXECUTOR,
+            appPackageName)
     private val executor: Executor = SyncExecutor()
 
     @Test
@@ -200,6 +215,44 @@
         assertThat(fakeServiceBinder.state).isEqualTo(ConnectionState.DISCONNECTED)
     }
 
+    @Test
+    fun remoteAuthClientStatus_notSupported_unknown() {
+        whenever(remoteInteractionsManager.isAvailabilityStatusApiSupported).thenReturn(false)
+        val isAvailable = runBlocking {
+            clientUnderTest.availabilityStatus.first()
+        }
+
+        assertThat(isAvailable).isEqualTo(RemoteAuthClient.STATUS_UNKNOWN)
+        verify(remoteInteractionsManager, never())
+            .registerRemoteAuthClientStatusListener(any(), any())
+    }
+
+    @Test
+    fun remoteAuthClientStatus_isSupported_propagateListenerValues() {
+        for (remoteStatus in listOf(
+            RemoteAuthClient.STATUS_AVAILABLE,
+            RemoteAuthClient.STATUS_UNAVAILABLE,
+            RemoteAuthClient.STATUS_TEMPORARILY_UNAVAILABLE)) {
+        whenever(remoteInteractionsManager.isAvailabilityStatusApiSupported).thenReturn(true)
+            doAnswer {
+                    @Suppress("UNCHECKED_CAST")
+                    val consumer: Consumer<Int> = it.arguments[1] as (Consumer<Int>)
+                    consumer.accept(remoteStatus)
+                }
+                .whenever(remoteInteractionsManager)
+                .registerRemoteAuthClientStatusListener(any(), any())
+
+            val isAvailable = runBlocking {
+                clientUnderTest.availabilityStatus.first()
+            }
+
+            assertThat(isAvailable).isEqualTo(remoteStatus)
+            verify(remoteInteractionsManager).registerRemoteAuthClientStatusListener(any(), any())
+            verify(remoteInteractionsManager).unregisterRemoteAuthClientStatusListener(any())
+            reset(remoteInteractionsManager)
+        }
+    }
+
     internal enum class ConnectionState {
         DISCONNECTED, CONNECTING, CONNECTED
     }
diff --git a/wear/wear-remote-interactions/api/current.txt b/wear/wear-remote-interactions/api/current.txt
index 8d134e3..754f9e9 100644
--- a/wear/wear-remote-interactions/api/current.txt
+++ b/wear/wear-remote-interactions/api/current.txt
@@ -4,14 +4,20 @@
   public final class RemoteActivityHelper {
     ctor public RemoteActivityHelper(android.content.Context context);
     ctor public RemoteActivityHelper(android.content.Context context, optional java.util.concurrent.Executor executor);
+    method public kotlinx.coroutines.flow.Flow<java.lang.Integer> getAvailabilityStatus();
     method public static android.content.Intent? getTargetIntent(android.content.Intent intent);
     method public static String? getTargetNodeId(android.content.Intent intent);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startRemoteActivity(android.content.Intent targetIntent);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startRemoteActivity(android.content.Intent targetIntent, optional String? targetNodeId);
+    property public final kotlinx.coroutines.flow.Flow<java.lang.Integer> availabilityStatus;
     field public static final String ACTION_REMOTE_INTENT = "com.google.android.wearable.intent.action.REMOTE_INTENT";
     field public static final androidx.wear.remote.interactions.RemoteActivityHelper.Companion Companion;
     field public static final int RESULT_FAILED = 1; // 0x1
     field public static final int RESULT_OK = 0; // 0x0
+    field public static final int STATUS_AVAILABLE = 3; // 0x3
+    field public static final int STATUS_TEMPORARILY_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
   }
 
   public static final class RemoteActivityHelper.Companion {
diff --git a/wear/wear-remote-interactions/api/restricted_current.txt b/wear/wear-remote-interactions/api/restricted_current.txt
index 8d134e3..754f9e9 100644
--- a/wear/wear-remote-interactions/api/restricted_current.txt
+++ b/wear/wear-remote-interactions/api/restricted_current.txt
@@ -4,14 +4,20 @@
   public final class RemoteActivityHelper {
     ctor public RemoteActivityHelper(android.content.Context context);
     ctor public RemoteActivityHelper(android.content.Context context, optional java.util.concurrent.Executor executor);
+    method public kotlinx.coroutines.flow.Flow<java.lang.Integer> getAvailabilityStatus();
     method public static android.content.Intent? getTargetIntent(android.content.Intent intent);
     method public static String? getTargetNodeId(android.content.Intent intent);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startRemoteActivity(android.content.Intent targetIntent);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startRemoteActivity(android.content.Intent targetIntent, optional String? targetNodeId);
+    property public final kotlinx.coroutines.flow.Flow<java.lang.Integer> availabilityStatus;
     field public static final String ACTION_REMOTE_INTENT = "com.google.android.wearable.intent.action.REMOTE_INTENT";
     field public static final androidx.wear.remote.interactions.RemoteActivityHelper.Companion Companion;
     field public static final int RESULT_FAILED = 1; // 0x1
     field public static final int RESULT_OK = 0; // 0x0
+    field public static final int STATUS_AVAILABLE = 3; // 0x3
+    field public static final int STATUS_TEMPORARILY_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
   }
 
   public static final class RemoteActivityHelper.Companion {
diff --git a/wear/wear-remote-interactions/build.gradle b/wear/wear-remote-interactions/build.gradle
index 6b41081..06ac5a4 100644
--- a/wear/wear-remote-interactions/build.gradle
+++ b/wear/wear-remote-interactions/build.gradle
@@ -47,6 +47,11 @@
     implementation("androidx.annotation:annotation:1.2.0")
     implementation(libs.playServicesBasement)
     implementation(libs.playServicesWearable, { exclude group: "androidx.core"})
+
+    // Includes the wear-sdk jar
+    compileOnly files("../../wear/wear_sdk/wear-sdk.jar")
+    testImplementation(files("../../wear/wear_sdk/wear-sdk.jar"))
+    samples(project(":wear:wear-remote-interactions-samples"))
 }
 
 android {
diff --git a/wear/wear-remote-interactions/samples/build.gradle b/wear/wear-remote-interactions/samples/build.gradle
new file mode 100644
index 0000000..27b52fe
--- /dev/null
+++ b/wear/wear-remote-interactions/samples/build.gradle
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+import androidx.build.LibraryType
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+}
+
+dependencies {
+    implementation(libs.kotlinStdlib)
+    implementation(project(":wear:wear-remote-interactions"))
+
+    compileOnly(project(":annotation:annotation-sampled"))
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 23
+    }
+    namespace "androidx.wear.remote.interactions.samples"
+}
+
+androidx {
+    name = "Android Wear Remote Interactions Samples"
+    type = LibraryType.SAMPLES
+    mavenVersion = LibraryVersions.WEAR_REMOTE_INTERACTIONS
+    inceptionYear = "2023"
+    description = "Contains the sample code for the Android Wear Remote Interactions Classes"
+}
diff --git a/wear/wear-remote-interactions/samples/src/main/AndroidManifest.xml b/wear/wear-remote-interactions/samples/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..bb9a4bc
--- /dev/null
+++ b/wear/wear-remote-interactions/samples/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+</manifest>
diff --git a/wear/wear-remote-interactions/samples/src/main/java/androidx/wear/remote/interactions/samples/RemoteActivityHelperSamples.kt b/wear/wear-remote-interactions/samples/src/main/java/androidx/wear/remote/interactions/samples/RemoteActivityHelperSamples.kt
new file mode 100644
index 0000000..193c29e
--- /dev/null
+++ b/wear/wear-remote-interactions/samples/src/main/java/androidx/wear/remote/interactions/samples/RemoteActivityHelperSamples.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.wear.remote.interactions.samples
+
+import android.content.Intent
+import androidx.annotation.Sampled
+import androidx.wear.remote.interactions.RemoteActivityHelper
+
+@Sampled
+suspend fun RemoteActivityAvailabilitySample(
+    remoteActivityHelper: RemoteActivityHelper,
+    remoteIntent: Intent
+) {
+    remoteActivityHelper.availabilityStatus.collect {
+        status -> when (status) {
+            RemoteActivityHelper.STATUS_UNAVAILABLE ->
+                TODO("Hide or present alternative flow as remote flow is not available.")
+            RemoteActivityHelper.STATUS_TEMPORARILY_UNAVAILABLE ->
+                TODO("Present education to user to connect devices or bring to proximity.")
+            RemoteActivityHelper.STATUS_AVAILABLE, RemoteActivityHelper.STATUS_UNKNOWN ->
+                // Present normal remote device flow when we don't know (old devices)
+                // or when we know it is available.
+                remoteActivityHelper.startRemoteActivity(remoteIntent)
+        } }
+}
diff --git a/wear/wear-remote-interactions/src/main/AndroidManifest.xml b/wear/wear-remote-interactions/src/main/AndroidManifest.xml
index e97e69d..e05fdbe 100644
--- a/wear/wear-remote-interactions/src/main/AndroidManifest.xml
+++ b/wear/wear-remote-interactions/src/main/AndroidManifest.xml
@@ -16,4 +16,9 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+  <application>
+    <uses-library
+        android:name="wear-sdk"
+        android:required="false"/>
+  </application>
 </manifest>
\ No newline at end of file
diff --git a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/IRemoteInteractionsManager.kt b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/IRemoteInteractionsManager.kt
new file mode 100644
index 0000000..3aded42
--- /dev/null
+++ b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/IRemoteInteractionsManager.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.wear.remote.interactions
+
+import com.google.wear.services.remoteinteractions.RemoteInteractionsManager
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+
+/**
+ * Forwards remote auth interaction availabilities to [RemoteInteractionsManager].
+ */
+internal interface IRemoteInteractionsManager {
+
+    /** Whether the availability status API is supported. */
+    val isAvailabilityStatusApiSupported: Boolean
+
+    /** Forwards a call to [RemoteInteractionsManager.registerRemoteActivityHelperStatusListener]. */
+    fun registerRemoteActivityHelperStatusListener(executor: Executor, listener: Consumer<Int>)
+
+    /** Forwards a call to [RemoteInteractionsManager.unregisterRemoteActivityHelperStatusListener]. */
+    fun unregisterRemoteActivityHelperStatusListener(listener: Consumer<Int>)
+}
diff --git a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt
index 6206efe..969c473 100644
--- a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt
+++ b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt
@@ -18,10 +18,12 @@
 import android.content.Context
 import android.content.Intent
 import android.content.res.Resources.NotFoundException
+import android.os.Build
 import android.os.Bundle
 import android.os.Parcel
 import android.os.ResultReceiver
 import androidx.annotation.IntDef
+import androidx.annotation.RequiresApi
 import androidx.annotation.VisibleForTesting
 import androidx.concurrent.futures.CallbackToFutureAdapter
 import androidx.wear.remote.interactions.RemoteInteractionsUtil.isCurrentDeviceAWatch
@@ -30,6 +32,11 @@
 import com.google.common.util.concurrent.ListenableFuture
 import java.util.concurrent.Executor
 import java.util.concurrent.Executors
+import java.util.function.Consumer
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.flowOf
 
 // Disabling max line length is needed for the link to work properly in the KDoc.
 /* ktlint-disable max-line-length */
@@ -75,6 +82,33 @@
         public const val ACTION_REMOTE_INTENT: String =
             "com.google.android.wearable.intent.action.REMOTE_INTENT"
 
+        /** The remote activity's availability is unknown. */
+        public const val STATUS_UNKNOWN = 0
+
+        /**
+         * The remote auth's availability is unknown.
+         *
+         * On older devices, [STATUS_UNKNOWN] is returned as we can not determine the availability states. To preserve
+         * compatibility with existing devices behavior, try [startRemoteActivity] and handle
+         * error codes accordingly.
+         */
+        public const val STATUS_UNAVAILABLE = 1
+
+        /**
+         * Indicates that remote activity is temporarily unavailable.
+         *
+         * There is a known paired device, but it is not currently connected or reachable to handle
+         * the remote interaction.
+         */
+        public const val STATUS_TEMPORARILY_UNAVAILABLE = 2
+
+        /**
+         * Indicates that remote activity is available.
+         *
+         * There is a connected device capable to handle the remote interaction.
+         */
+        public const val STATUS_AVAILABLE = 3
+
         private const val EXTRA_INTENT: String = "com.google.android.wearable.intent.extra.INTENT"
 
         private const val EXTRA_NODE_ID: String = "com.google.android.wearable.intent.extra.NODE_ID"
@@ -142,6 +176,60 @@
     @VisibleForTesting
     internal var nodeClient: NodeClient = Wearable.getNodeClient(context)
 
+    /** Used for testing only, so we can mock wear sdk dependency. */
+    @VisibleForTesting internal var remoteInteractionsManager: IRemoteInteractionsManager = RemoteInteractionsManagerCompat(context)
+
+    /**
+     * Status of whether [RemoteActivityHelper] can [startRemoteActivity], if known.
+     *
+     * In scenarios of restricted connection or temporary disconnection with a paired device,
+     * [startRemoteActivity] will not be available. Please check [availabilityStatus] before calling [startRemoteActivity] to
+     * provide better experience for the user.
+     *
+     * Wear devices start to support determining the availability status from Wear Sdk WEAR_TIRAMISU_4.
+     * On older wear devices, it will always return [STATUS_UNKNOWN].
+     * On phone devices, it will always return [STATUS_UNKNOWN].
+     *
+     * @sample androidx.wear.remote.interactions.samples.RemoteActivityAvailabilitySample
+     *
+     * @return a [Flow] with a stream of status updates that could be one of [STATUS_UNKNOWN],
+     *   [STATUS_UNAVAILABLE], [STATUS_TEMPORARILY_UNAVAILABLE], [STATUS_AVAILABLE].
+     */
+    public val availabilityStatus: Flow<Int> get() {
+        if (!isCurrentDeviceAWatch(context)) {
+            // Currently, we do not support knowing the startRemoteActivity's availability on a non-watch device.
+            return flowOf(STATUS_UNKNOWN)
+        }
+        if (!remoteInteractionsManager.isAvailabilityStatusApiSupported) {
+            return flowOf(STATUS_UNKNOWN)
+        }
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+            // This should never be reached as the check above wouldn't pass below T.
+            // `Consumer<Int>` requires min API 25 but library min API is 23, this hints to lint that the code below
+            // only executes on T+.
+            return flowOf(STATUS_UNKNOWN)
+        }
+
+        return getRemoteActivityHelperStatusInternal()
+    }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    private fun getRemoteActivityHelperStatusInternal(): Flow<Int> {
+        return callbackFlow {
+            val callback =
+                object : Consumer<Int> {
+                    override fun accept(value: Int) {
+                        // Emit WearSDK values through AndroidX with 1:1 mapping.
+                        trySend(value)
+                    }
+                }
+
+            remoteInteractionsManager.registerRemoteActivityHelperStatusListener(executor, callback)
+
+            awaitClose { remoteInteractionsManager.unregisterRemoteActivityHelperStatusListener(callback) }
+        }
+    }
+
     /**
      * Start an activity on another device. This api currently supports sending intents with
      * action set to [android.content.Intent.ACTION_VIEW], a data uri populated using
diff --git a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteInteractionsManagerCompat.kt b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteInteractionsManagerCompat.kt
new file mode 100644
index 0000000..69ac03e
--- /dev/null
+++ b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteInteractionsManagerCompat.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.wear.remote.interactions
+
+import android.content.Context
+import com.google.wear.Sdk
+import com.google.wear.services.remoteinteractions.RemoteInteractionsManager
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+
+/**
+ * Forwards remote auth interaction availabilities to [RemoteInteractionsManager].
+ */
+internal open class RemoteInteractionsManagerCompat(context: Context) : IRemoteInteractionsManager {
+
+    // TODO(b/307543793): Reuse the generalized `WearApiVersionHelper` once available.
+    private val wearApiVersion: WearApiVersion = WearApiVersion()
+
+    private val remoteInteractionsManager: RemoteInteractionsManager? =
+        if (isAvailabilityStatusApiSupported)
+            Sdk.getWearManager(context, RemoteInteractionsManager::class.java)
+        else
+            null
+
+    override val isAvailabilityStatusApiSupported: Boolean
+        get() = wearApiVersion.wearSdkVersion >= 4
+
+    override fun registerRemoteActivityHelperStatusListener(
+        executor: Executor,
+        listener: Consumer<Int>
+    ) {
+        if (isAvailabilityStatusApiSupported) {
+            remoteInteractionsManager!!.registerRemoteActivityHelperStatusListener(
+                executor,
+                listener
+            )
+        } else {
+            throw UnsupportedOperationException("Should not call wear sdk when not supported.")
+        }
+    }
+
+    override fun unregisterRemoteActivityHelperStatusListener(listener: Consumer<Int>) {
+        if (isAvailabilityStatusApiSupported) {
+            remoteInteractionsManager!!.unregisterRemoteActivityHelperStatusListener(
+                listener
+            )
+        } else {
+            throw UnsupportedOperationException("Should not call wear sdk when not supported.")
+        }
+    }
+}
diff --git a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WearApiVersion.kt b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WearApiVersion.kt
new file mode 100644
index 0000000..4e12a58
--- /dev/null
+++ b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WearApiVersion.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.wear.remote.interactions
+
+import android.os.Build
+import com.google.wear.Sdk
+
+/**
+ * Provides wear sdk api version.
+ */
+internal class WearApiVersion {
+
+    // TODO(b/307543793): Reuse the generalized `WearApiVersionHelper` once available.
+    /** Exposes version of wear sdk. Returns 0 if wear-sdk is not present. */
+    val wearSdkVersion: Int
+        get() {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                // Wear SDK INT can only be accessed safely from UPSIDE_DOWN_CAKE, introduced from tiramisu kr2.
+                // Or crashes with `NoSuchField` will be experienced.
+                return Sdk.VERSION.WEAR_SDK_INT
+            }
+            return 0
+        }
+}
diff --git a/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt b/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt
index c043ba5..45a06ecee 100644
--- a/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt
+++ b/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt
@@ -23,6 +23,7 @@
 import android.content.IntentFilter
 import android.content.res.Resources.NotFoundException
 import android.net.Uri
+import android.os.Build.VERSION_CODES
 import android.os.Looper
 import android.os.ResultReceiver
 import androidx.test.core.app.ApplicationProvider
@@ -38,6 +39,9 @@
 import com.google.android.gms.wearable.NodeClient
 import java.util.concurrent.ExecutionException
 import java.util.concurrent.Executor
+import java.util.function.Consumer
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertThrows
 import org.junit.Assert.assertTrue
@@ -45,10 +49,15 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.any
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import org.robolectric.Shadows.shadowOf
 import org.robolectric.annotation.Config
 import org.robolectric.annotation.Implements
@@ -103,11 +112,13 @@
     @Mock private var mockNodeClient: NodeClient = mock()
     @Mock private val mockTestNode: Node = mock()
     @Mock private val mockTestNode2: Node = mock()
+    private val remoteInteractionsManager: IRemoteInteractionsManager = mock()
 
     @Before
     fun setUp() {
         mRemoteActivityHelper = RemoteActivityHelper(context, SyncExecutor())
         mRemoteActivityHelper.nodeClient = mockNodeClient
+        mRemoteActivityHelper.remoteInteractionsManager = remoteInteractionsManager
     }
 
     private fun setSystemFeatureWatch(isWatch: Boolean) {
@@ -454,6 +465,62 @@
 
         assertTrue(actualException.cause is NotFoundException)
     }
+
+    @Test
+    fun remoteActivityHelperStatus_notWatch_unknown() {
+        setSystemFeatureWatch(false)
+        val remoteActivityHelperStatus = runBlocking {
+            mRemoteActivityHelper.availabilityStatus.first()
+        }
+
+        assertEquals(remoteActivityHelperStatus, RemoteActivityHelper.STATUS_UNKNOWN)
+        verify(remoteInteractionsManager, never())
+            .registerRemoteActivityHelperStatusListener(any(), any())
+    }
+
+    @Test
+    @Config(minSdk = VERSION_CODES.TIRAMISU)
+    fun remoteActivityHelperStatus_notSupported_unknown() {
+        setSystemFeatureWatch(true)
+            whenever(remoteInteractionsManager.isAvailabilityStatusApiSupported).thenReturn(false)
+        val remoteActivityHelperStatus = runBlocking {
+            mRemoteActivityHelper.availabilityStatus.first()
+        }
+
+        assertEquals(remoteActivityHelperStatus, RemoteActivityHelper.STATUS_UNKNOWN)
+        verify(remoteInteractionsManager, never())
+            .registerRemoteActivityHelperStatusListener(any(), any())
+    }
+
+    @Test
+    @Config(minSdk = VERSION_CODES.TIRAMISU)
+    fun remoteActivityHelperStatus_supported_propagateStatus() {
+        setSystemFeatureWatch(true)
+
+        for (remoteStatus in listOf(
+            RemoteActivityHelper.STATUS_AVAILABLE,
+            RemoteActivityHelper.STATUS_UNAVAILABLE,
+            RemoteActivityHelper.STATUS_TEMPORARILY_UNAVAILABLE)) {
+            whenever(remoteInteractionsManager.isAvailabilityStatusApiSupported).thenReturn(true)
+            doAnswer {
+                    @Suppress("UNCHECKED_CAST")
+                    val consumer: Consumer<Int> = it.arguments[1] as (Consumer<Int>)
+                    consumer.accept(remoteStatus)
+                }
+                .whenever(remoteInteractionsManager)
+                .registerRemoteActivityHelperStatusListener(any(), any())
+
+            val remoteActivityHelperStatus = runBlocking {
+                mRemoteActivityHelper.availabilityStatus.first()
+            }
+
+            assertEquals(remoteActivityHelperStatus, remoteStatus)
+            verify(remoteInteractionsManager)
+                .registerRemoteActivityHelperStatusListener(any(), any())
+            verify(remoteInteractionsManager).unregisterRemoteActivityHelperStatusListener(any())
+            reset(remoteInteractionsManager)
+        }
+    }
 }
 
 private class SyncExecutor : Executor {
diff --git a/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebSettingsCompatDarkModeTestBase.java b/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebSettingsCompatDarkModeTestBase.java
index 1b50075..31c4b7d 100644
--- a/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebSettingsCompatDarkModeTestBase.java
+++ b/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebSettingsCompatDarkModeTestBase.java
@@ -20,14 +20,12 @@
 
 import android.graphics.Bitmap;
 import android.graphics.Color;
-import android.os.Build;
 import android.util.Base64;
 import android.view.ViewGroup;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
@@ -42,7 +40,6 @@
 /**
  * Base class for dark mode related test.
  */
-@RequiresApi(Build.VERSION_CODES.KITKAT)
 public class WebSettingsCompatDarkModeTestBase<T extends WebViewTestActivity> {
 
     // The size of WebViews to use in the app.
diff --git a/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java b/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
index d22e732..ed2df16 100644
--- a/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
+++ b/webkit/integration-tests/instrumentation/src/androidTest/java/androidx/webkit/WebViewOnUiThread.java
@@ -24,7 +24,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Looper;
 import android.os.SystemClock;
 import android.webkit.ValueCallback;
@@ -36,7 +35,6 @@
 import androidx.annotation.CallSuper;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.concurrent.futures.ResolvableFuture;
 import androidx.test.core.app.ApplicationProvider;
 
@@ -53,7 +51,6 @@
  * Modifications to this class should be reflected in that class as necessary. See
  * http://go/modifying-webview-cts.
  */
-@RequiresApi(api = Build.VERSION_CODES.KITKAT)
 public class WebViewOnUiThread implements AutoCloseable{
     /**
      * The maximum time, in milliseconds (10 seconds) to wait for a load
diff --git a/webkit/webkit/api/1.10.0-beta01.txt b/webkit/webkit/api/1.10.0-beta01.txt
new file mode 100644
index 0000000..0a06f1f
--- /dev/null
+++ b/webkit/webkit/api/1.10.0-beta01.txt
@@ -0,0 +1,417 @@
+// Signature format: 4.0
+package androidx.webkit {
+
+  public class CookieManagerCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_COOKIE_INFO, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.List<java.lang.String!> getCookieInfo(android.webkit.CookieManager, String);
+  }
+
+  public final class DropDataContentProvider extends android.content.ContentProvider {
+    ctor public DropDataContentProvider();
+    method public int delete(android.net.Uri, String?, String![]?);
+    method public String? getType(android.net.Uri);
+    method public android.net.Uri? insert(android.net.Uri, android.content.ContentValues?);
+    method public boolean onCreate();
+    method public android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?);
+    method public int update(android.net.Uri, android.content.ContentValues?, String?, String![]?);
+  }
+
+  public abstract class JavaScriptReplyProxy {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(byte[]);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
+  }
+
+  public class ProcessGlobalConfig {
+    ctor public ProcessGlobalConfig();
+    method public static void apply(androidx.webkit.ProcessGlobalConfig);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDataDirectorySuffix(android.content.Context, String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDirectoryBasePaths(android.content.Context, java.io.File, java.io.File);
+  }
+
+  public interface Profile {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.CookieManager getCookieManager();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.GeolocationPermissions getGeolocationPermissions();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public String getName();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.ServiceWorkerController getServiceWorkerController();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.WebStorage getWebStorage();
+    field public static final String DEFAULT_PROFILE_NAME = "Default";
+  }
+
+  @UiThread public interface ProfileStore {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public boolean deleteProfile(String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public java.util.List<java.lang.String!> getAllProfileNames();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProfileStore getInstance();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.Profile getOrCreateProfile(String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.Profile? getProfile(String);
+  }
+
+  public final class ProxyConfig {
+    method public java.util.List<java.lang.String!> getBypassRules();
+    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
+    method public boolean isReverseBypassEnabled();
+    field public static final String MATCH_ALL_SCHEMES = "*";
+    field public static final String MATCH_HTTP = "http";
+    field public static final String MATCH_HTTPS = "https";
+  }
+
+  public static final class ProxyConfig.Builder {
+    ctor public ProxyConfig.Builder();
+    ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
+    method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
+    method public androidx.webkit.ProxyConfig.Builder addDirect();
+    method public androidx.webkit.ProxyConfig.Builder addDirect(String);
+    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
+    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
+    method public androidx.webkit.ProxyConfig build();
+    method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
+    method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.ProxyConfig.Builder setReverseBypassEnabled(boolean);
+  }
+
+  public static final class ProxyConfig.ProxyRule {
+    method public String getSchemeFilter();
+    method public String getUrl();
+  }
+
+  public abstract class ProxyController {
+    method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
+    method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
+  }
+
+  public abstract class SafeBrowsingResponseCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
+  }
+
+  public interface ScriptHandler {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DOCUMENT_START_SCRIPT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public void remove();
+  }
+
+  public abstract class ServiceWorkerClientCompat {
+    ctor public ServiceWorkerClientCompat();
+    method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
+  }
+
+  public abstract class ServiceWorkerControllerCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
+    method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
+    method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
+  }
+
+  public abstract class ServiceWorkerWebSettingsCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setRequestedWithHeaderOriginAllowList(java.util.Set<java.lang.String!>);
+  }
+
+  public class TracingConfig {
+    method public java.util.List<java.lang.String!> getCustomIncludedCategories();
+    method public int getPredefinedCategories();
+    method public int getTracingMode();
+    field public static final int CATEGORIES_ALL = 1; // 0x1
+    field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+    field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+    field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+    field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+    field public static final int CATEGORIES_NONE = 0; // 0x0
+    field public static final int CATEGORIES_RENDERING = 16; // 0x10
+    field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
+    field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
+    field public static final int RECORD_UNTIL_FULL = 0; // 0x0
+  }
+
+  public static class TracingConfig.Builder {
+    ctor public TracingConfig.Builder();
+    method public androidx.webkit.TracingConfig.Builder addCategories(int...);
+    method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
+    method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
+    method public androidx.webkit.TracingConfig build();
+    method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
+  }
+
+  public abstract class TracingController {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
+    method public abstract boolean isTracing();
+    method public abstract void start(androidx.webkit.TracingConfig);
+    method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
+  }
+
+  public final class UserAgentMetadata {
+    method public String? getArchitecture();
+    method public int getBitness();
+    method public java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!> getBrandVersionList();
+    method public String? getFullVersion();
+    method public String? getModel();
+    method public String? getPlatform();
+    method public String? getPlatformVersion();
+    method public boolean isMobile();
+    method public boolean isWow64();
+    field public static final int BITNESS_DEFAULT = 0; // 0x0
+  }
+
+  public static final class UserAgentMetadata.BrandVersion {
+    method public String getBrand();
+    method public String getFullVersion();
+    method public String getMajorVersion();
+  }
+
+  public static final class UserAgentMetadata.BrandVersion.Builder {
+    ctor public UserAgentMetadata.BrandVersion.Builder();
+    ctor public UserAgentMetadata.BrandVersion.Builder(androidx.webkit.UserAgentMetadata.BrandVersion);
+    method public androidx.webkit.UserAgentMetadata.BrandVersion build();
+    method public androidx.webkit.UserAgentMetadata.BrandVersion.Builder setBrand(String);
+    method public androidx.webkit.UserAgentMetadata.BrandVersion.Builder setFullVersion(String);
+    method public androidx.webkit.UserAgentMetadata.BrandVersion.Builder setMajorVersion(String);
+  }
+
+  public static final class UserAgentMetadata.Builder {
+    ctor public UserAgentMetadata.Builder();
+    ctor public UserAgentMetadata.Builder(androidx.webkit.UserAgentMetadata);
+    method public androidx.webkit.UserAgentMetadata build();
+    method public androidx.webkit.UserAgentMetadata.Builder setArchitecture(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setBitness(int);
+    method public androidx.webkit.UserAgentMetadata.Builder setBrandVersionList(java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!>);
+    method public androidx.webkit.UserAgentMetadata.Builder setFullVersion(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setMobile(boolean);
+    method public androidx.webkit.UserAgentMetadata.Builder setModel(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setPlatform(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setPlatformVersion(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setWow64(boolean);
+  }
+
+  public class WebMessageCompat {
+    ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[]);
+    ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[], androidx.webkit.WebMessagePortCompat![]?);
+    ctor public WebMessageCompat(String?);
+    ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
+    method public byte[] getArrayBuffer();
+    method public String? getData();
+    method public androidx.webkit.WebMessagePortCompat![]? getPorts();
+    method public int getType();
+    field public static final int TYPE_ARRAY_BUFFER = 1; // 0x1
+    field public static final int TYPE_STRING = 0; // 0x0
+  }
+
+  public abstract class WebMessagePortCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+  }
+
+  public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
+    ctor public WebMessagePortCompat.WebMessageCallbackCompat();
+    method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
+  }
+
+  public abstract class WebResourceErrorCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
+  }
+
+  public class WebResourceRequestCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
+  }
+
+  public class WebSettingsCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ATTRIBUTION_REGISTRATION_BEHAVIOR, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getAttributionRegistrationBehavior(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.UserAgentMetadata getUserAgentMetadata(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewMediaIntegrityApiStatusConfig getWebViewMediaIntegrityApiStatus(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ATTRIBUTION_REGISTRATION_BEHAVIOR, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAttributionRegistrationBehavior(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings, boolean);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setUserAgentMetadata(android.webkit.WebSettings, androidx.webkit.UserAgentMetadata);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewMediaIntegrityApiStatus(android.webkit.WebSettings, androidx.webkit.WebViewMediaIntegrityApiStatusConfig);
+    field public static final int ATTRIBUTION_BEHAVIOR_APP_SOURCE_AND_APP_TRIGGER = 3; // 0x3
+    field public static final int ATTRIBUTION_BEHAVIOR_APP_SOURCE_AND_WEB_TRIGGER = 1; // 0x1
+    field public static final int ATTRIBUTION_BEHAVIOR_DISABLED = 0; // 0x0
+    field public static final int ATTRIBUTION_BEHAVIOR_WEB_SOURCE_AND_WEB_TRIGGER = 2; // 0x2
+    field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
+    field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
+    field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
+    field @Deprecated public static final int FORCE_DARK_AUTO = 1; // 0x1
+    field @Deprecated public static final int FORCE_DARK_OFF = 0; // 0x0
+    field @Deprecated public static final int FORCE_DARK_ON = 2; // 0x2
+  }
+
+  public final class WebViewAssetLoader {
+    method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
+    field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
+  }
+
+  public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public static final class WebViewAssetLoader.Builder {
+    ctor public WebViewAssetLoader.Builder();
+    method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
+    method public androidx.webkit.WebViewAssetLoader build();
+    method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
+    method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
+  }
+
+  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+  }
+
+  public static interface WebViewAssetLoader.PathHandler {
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public class WebViewClientCompat extends android.webkit.WebViewClient {
+    ctor public WebViewClientCompat();
+    method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+    method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+    method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+    method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
+  }
+
+  public class WebViewCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DOCUMENT_START_SCRIPT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ScriptHandler addDocumentStartJavaScript(android.webkit.WebView, String, java.util.Set<java.lang.String!>);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
+    method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") @UiThread public static androidx.webkit.Profile getProfile(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_VARIATIONS_HEADER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static String getVariationsHeader();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") @UiThread public static void setProfile(android.webkit.WebView, String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ALLOWLIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingAllowlist(java.util.Set<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
+  }
+
+  public static interface WebViewCompat.VisualStateCallback {
+    method @UiThread public void onComplete(long);
+  }
+
+  public static interface WebViewCompat.WebMessageListener {
+    method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
+  }
+
+  public class WebViewFeature {
+    method public static boolean isFeatureSupported(String);
+    method public static boolean isStartupFeatureSupported(android.content.Context, String);
+    field public static final String ALGORITHMIC_DARKENING = "ALGORITHMIC_DARKENING";
+    field public static final String ATTRIBUTION_REGISTRATION_BEHAVIOR = "ATTRIBUTION_REGISTRATION_BEHAVIOR";
+    field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
+    field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+    field public static final String DOCUMENT_START_SCRIPT = "DOCUMENT_START_SCRIPT";
+    field public static final String ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = "ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY";
+    field public static final String FORCE_DARK = "FORCE_DARK";
+    field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
+    field public static final String GET_COOKIE_INFO = "GET_COOKIE_INFO";
+    field public static final String GET_VARIATIONS_HEADER = "GET_VARIATIONS_HEADER";
+    field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
+    field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
+    field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
+    field public static final String MULTI_PROCESS = "MULTI_PROCESS";
+    field public static final String MULTI_PROFILE = "MULTI_PROFILE";
+    field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+    field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
+    field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
+    field public static final String PROXY_OVERRIDE_REVERSE_BYPASS = "PROXY_OVERRIDE_REVERSE_BYPASS";
+    field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+    field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+    field public static final String SAFE_BROWSING_ALLOWLIST = "SAFE_BROWSING_ALLOWLIST";
+    field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+    field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+    field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+    field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
+    field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
+    field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
+    field @Deprecated public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+    field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+    field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+    field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+    field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+    field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+    field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+    field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
+    field public static final String STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX = "STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX";
+    field public static final String STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS = "STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS";
+    field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
+    field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+    field public static final String USER_AGENT_METADATA = "USER_AGENT_METADATA";
+    field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+    field public static final String WEBVIEW_MEDIA_INTEGRITY_API_STATUS = "WEBVIEW_MEDIA_INTEGRITY_API_STATUS";
+    field public static final String WEB_MESSAGE_ARRAY_BUFFER = "WEB_MESSAGE_ARRAY_BUFFER";
+    field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
+    field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
+    field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
+    field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
+    field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
+    field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
+    field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
+    field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
+    field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
+    field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
+  }
+
+  @RequiresFeature(name=androidx.webkit.WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public class WebViewMediaIntegrityApiStatusConfig {
+    ctor public WebViewMediaIntegrityApiStatusConfig(androidx.webkit.WebViewMediaIntegrityApiStatusConfig.Builder);
+    method public int getDefaultStatus();
+    method public java.util.Map<java.lang.String!,java.lang.Integer!> getOverrideRules();
+    field public static final int WEBVIEW_MEDIA_INTEGRITY_API_DISABLED = 0; // 0x0
+    field public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED = 2; // 0x2
+    field public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED_WITHOUT_APP_IDENTITY = 1; // 0x1
+  }
+
+  public static final class WebViewMediaIntegrityApiStatusConfig.Builder {
+    ctor public WebViewMediaIntegrityApiStatusConfig.Builder(int);
+    method public androidx.webkit.WebViewMediaIntegrityApiStatusConfig.Builder addOverrideRule(String, int);
+    method public androidx.webkit.WebViewMediaIntegrityApiStatusConfig build();
+  }
+
+  public abstract class WebViewRenderProcess {
+    ctor public WebViewRenderProcess();
+    method public abstract boolean terminate();
+  }
+
+  public abstract class WebViewRenderProcessClient {
+    ctor public WebViewRenderProcessClient();
+    method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+    method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.10.0-beta01.txt b/webkit/webkit/api/res-1.10.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/webkit/webkit/api/res-1.10.0-beta01.txt
diff --git a/webkit/webkit/api/restricted_1.10.0-beta01.txt b/webkit/webkit/api/restricted_1.10.0-beta01.txt
new file mode 100644
index 0000000..0a06f1f
--- /dev/null
+++ b/webkit/webkit/api/restricted_1.10.0-beta01.txt
@@ -0,0 +1,417 @@
+// Signature format: 4.0
+package androidx.webkit {
+
+  public class CookieManagerCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_COOKIE_INFO, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.List<java.lang.String!> getCookieInfo(android.webkit.CookieManager, String);
+  }
+
+  public final class DropDataContentProvider extends android.content.ContentProvider {
+    ctor public DropDataContentProvider();
+    method public int delete(android.net.Uri, String?, String![]?);
+    method public String? getType(android.net.Uri);
+    method public android.net.Uri? insert(android.net.Uri, android.content.ContentValues?);
+    method public boolean onCreate();
+    method public android.database.Cursor? query(android.net.Uri, String![]?, String?, String![]?, String?);
+    method public int update(android.net.Uri, android.content.ContentValues?, String?, String![]?);
+  }
+
+  public abstract class JavaScriptReplyProxy {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(byte[]);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
+  }
+
+  public class ProcessGlobalConfig {
+    ctor public ProcessGlobalConfig();
+    method public static void apply(androidx.webkit.ProcessGlobalConfig);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDataDirectorySuffix(android.content.Context, String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDirectoryBasePaths(android.content.Context, java.io.File, java.io.File);
+  }
+
+  public interface Profile {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.CookieManager getCookieManager();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.GeolocationPermissions getGeolocationPermissions();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public String getName();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.ServiceWorkerController getServiceWorkerController();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public android.webkit.WebStorage getWebStorage();
+    field public static final String DEFAULT_PROFILE_NAME = "Default";
+  }
+
+  @UiThread public interface ProfileStore {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public boolean deleteProfile(String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public java.util.List<java.lang.String!> getAllProfileNames();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProfileStore getInstance();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.Profile getOrCreateProfile(String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.Profile? getProfile(String);
+  }
+
+  public final class ProxyConfig {
+    method public java.util.List<java.lang.String!> getBypassRules();
+    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
+    method public boolean isReverseBypassEnabled();
+    field public static final String MATCH_ALL_SCHEMES = "*";
+    field public static final String MATCH_HTTP = "http";
+    field public static final String MATCH_HTTPS = "https";
+  }
+
+  public static final class ProxyConfig.Builder {
+    ctor public ProxyConfig.Builder();
+    ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
+    method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
+    method public androidx.webkit.ProxyConfig.Builder addDirect();
+    method public androidx.webkit.ProxyConfig.Builder addDirect(String);
+    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
+    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
+    method public androidx.webkit.ProxyConfig build();
+    method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
+    method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.ProxyConfig.Builder setReverseBypassEnabled(boolean);
+  }
+
+  public static final class ProxyConfig.ProxyRule {
+    method public String getSchemeFilter();
+    method public String getUrl();
+  }
+
+  public abstract class ProxyController {
+    method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
+    method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
+  }
+
+  public abstract class SafeBrowsingResponseCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
+  }
+
+  public interface ScriptHandler {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DOCUMENT_START_SCRIPT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public void remove();
+  }
+
+  public abstract class ServiceWorkerClientCompat {
+    ctor public ServiceWorkerClientCompat();
+    method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
+  }
+
+  public abstract class ServiceWorkerControllerCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
+    method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
+    method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
+  }
+
+  public abstract class ServiceWorkerWebSettingsCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setRequestedWithHeaderOriginAllowList(java.util.Set<java.lang.String!>);
+  }
+
+  public class TracingConfig {
+    method public java.util.List<java.lang.String!> getCustomIncludedCategories();
+    method public int getPredefinedCategories();
+    method public int getTracingMode();
+    field public static final int CATEGORIES_ALL = 1; // 0x1
+    field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+    field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+    field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+    field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+    field public static final int CATEGORIES_NONE = 0; // 0x0
+    field public static final int CATEGORIES_RENDERING = 16; // 0x10
+    field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
+    field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
+    field public static final int RECORD_UNTIL_FULL = 0; // 0x0
+  }
+
+  public static class TracingConfig.Builder {
+    ctor public TracingConfig.Builder();
+    method public androidx.webkit.TracingConfig.Builder addCategories(int...);
+    method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
+    method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
+    method public androidx.webkit.TracingConfig build();
+    method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
+  }
+
+  public abstract class TracingController {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
+    method public abstract boolean isTracing();
+    method public abstract void start(androidx.webkit.TracingConfig);
+    method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
+  }
+
+  public final class UserAgentMetadata {
+    method public String? getArchitecture();
+    method public int getBitness();
+    method public java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!> getBrandVersionList();
+    method public String? getFullVersion();
+    method public String? getModel();
+    method public String? getPlatform();
+    method public String? getPlatformVersion();
+    method public boolean isMobile();
+    method public boolean isWow64();
+    field public static final int BITNESS_DEFAULT = 0; // 0x0
+  }
+
+  public static final class UserAgentMetadata.BrandVersion {
+    method public String getBrand();
+    method public String getFullVersion();
+    method public String getMajorVersion();
+  }
+
+  public static final class UserAgentMetadata.BrandVersion.Builder {
+    ctor public UserAgentMetadata.BrandVersion.Builder();
+    ctor public UserAgentMetadata.BrandVersion.Builder(androidx.webkit.UserAgentMetadata.BrandVersion);
+    method public androidx.webkit.UserAgentMetadata.BrandVersion build();
+    method public androidx.webkit.UserAgentMetadata.BrandVersion.Builder setBrand(String);
+    method public androidx.webkit.UserAgentMetadata.BrandVersion.Builder setFullVersion(String);
+    method public androidx.webkit.UserAgentMetadata.BrandVersion.Builder setMajorVersion(String);
+  }
+
+  public static final class UserAgentMetadata.Builder {
+    ctor public UserAgentMetadata.Builder();
+    ctor public UserAgentMetadata.Builder(androidx.webkit.UserAgentMetadata);
+    method public androidx.webkit.UserAgentMetadata build();
+    method public androidx.webkit.UserAgentMetadata.Builder setArchitecture(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setBitness(int);
+    method public androidx.webkit.UserAgentMetadata.Builder setBrandVersionList(java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!>);
+    method public androidx.webkit.UserAgentMetadata.Builder setFullVersion(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setMobile(boolean);
+    method public androidx.webkit.UserAgentMetadata.Builder setModel(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setPlatform(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setPlatformVersion(String?);
+    method public androidx.webkit.UserAgentMetadata.Builder setWow64(boolean);
+  }
+
+  public class WebMessageCompat {
+    ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[]);
+    ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[], androidx.webkit.WebMessagePortCompat![]?);
+    ctor public WebMessageCompat(String?);
+    ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
+    method public byte[] getArrayBuffer();
+    method public String? getData();
+    method public androidx.webkit.WebMessagePortCompat![]? getPorts();
+    method public int getType();
+    field public static final int TYPE_ARRAY_BUFFER = 1; // 0x1
+    field public static final int TYPE_STRING = 0; // 0x0
+  }
+
+  public abstract class WebMessagePortCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+  }
+
+  public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
+    ctor public WebMessagePortCompat.WebMessageCallbackCompat();
+    method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
+  }
+
+  public abstract class WebResourceErrorCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
+  }
+
+  public class WebResourceRequestCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
+  }
+
+  public class WebSettingsCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ATTRIBUTION_REGISTRATION_BEHAVIOR, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getAttributionRegistrationBehavior(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.UserAgentMetadata getUserAgentMetadata(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewMediaIntegrityApiStatusConfig getWebViewMediaIntegrityApiStatus(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ATTRIBUTION_REGISTRATION_BEHAVIOR, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAttributionRegistrationBehavior(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings, boolean);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setUserAgentMetadata(android.webkit.WebSettings, androidx.webkit.UserAgentMetadata);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewMediaIntegrityApiStatus(android.webkit.WebSettings, androidx.webkit.WebViewMediaIntegrityApiStatusConfig);
+    field public static final int ATTRIBUTION_BEHAVIOR_APP_SOURCE_AND_APP_TRIGGER = 3; // 0x3
+    field public static final int ATTRIBUTION_BEHAVIOR_APP_SOURCE_AND_WEB_TRIGGER = 1; // 0x1
+    field public static final int ATTRIBUTION_BEHAVIOR_DISABLED = 0; // 0x0
+    field public static final int ATTRIBUTION_BEHAVIOR_WEB_SOURCE_AND_WEB_TRIGGER = 2; // 0x2
+    field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
+    field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
+    field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
+    field @Deprecated public static final int FORCE_DARK_AUTO = 1; // 0x1
+    field @Deprecated public static final int FORCE_DARK_OFF = 0; // 0x0
+    field @Deprecated public static final int FORCE_DARK_ON = 2; // 0x2
+  }
+
+  public final class WebViewAssetLoader {
+    method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
+    field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
+  }
+
+  public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public static final class WebViewAssetLoader.Builder {
+    ctor public WebViewAssetLoader.Builder();
+    method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
+    method public androidx.webkit.WebViewAssetLoader build();
+    method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
+    method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
+  }
+
+  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+  }
+
+  public static interface WebViewAssetLoader.PathHandler {
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+    ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
+    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+  }
+
+  public class WebViewClientCompat extends android.webkit.WebViewClient {
+    ctor public WebViewClientCompat();
+    method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+    method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+    method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+    method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
+  }
+
+  public class WebViewCompat {
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DOCUMENT_START_SCRIPT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ScriptHandler addDocumentStartJavaScript(android.webkit.WebView, String, java.util.Set<java.lang.String!>);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
+    method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") @UiThread public static androidx.webkit.Profile getProfile(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_VARIATIONS_HEADER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static String getVariationsHeader();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROFILE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") @UiThread public static void setProfile(android.webkit.WebView, String);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ALLOWLIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingAllowlist(java.util.Set<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
+    method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
+  }
+
+  public static interface WebViewCompat.VisualStateCallback {
+    method @UiThread public void onComplete(long);
+  }
+
+  public static interface WebViewCompat.WebMessageListener {
+    method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
+  }
+
+  public class WebViewFeature {
+    method public static boolean isFeatureSupported(String);
+    method public static boolean isStartupFeatureSupported(android.content.Context, String);
+    field public static final String ALGORITHMIC_DARKENING = "ALGORITHMIC_DARKENING";
+    field public static final String ATTRIBUTION_REGISTRATION_BEHAVIOR = "ATTRIBUTION_REGISTRATION_BEHAVIOR";
+    field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
+    field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+    field public static final String DOCUMENT_START_SCRIPT = "DOCUMENT_START_SCRIPT";
+    field public static final String ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = "ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY";
+    field public static final String FORCE_DARK = "FORCE_DARK";
+    field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
+    field public static final String GET_COOKIE_INFO = "GET_COOKIE_INFO";
+    field public static final String GET_VARIATIONS_HEADER = "GET_VARIATIONS_HEADER";
+    field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
+    field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
+    field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
+    field public static final String MULTI_PROCESS = "MULTI_PROCESS";
+    field public static final String MULTI_PROFILE = "MULTI_PROFILE";
+    field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+    field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
+    field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
+    field public static final String PROXY_OVERRIDE_REVERSE_BYPASS = "PROXY_OVERRIDE_REVERSE_BYPASS";
+    field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+    field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+    field public static final String SAFE_BROWSING_ALLOWLIST = "SAFE_BROWSING_ALLOWLIST";
+    field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+    field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+    field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+    field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
+    field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
+    field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
+    field @Deprecated public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+    field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+    field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+    field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+    field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+    field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+    field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+    field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
+    field public static final String STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX = "STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX";
+    field public static final String STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS = "STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS";
+    field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
+    field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+    field public static final String USER_AGENT_METADATA = "USER_AGENT_METADATA";
+    field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+    field public static final String WEBVIEW_MEDIA_INTEGRITY_API_STATUS = "WEBVIEW_MEDIA_INTEGRITY_API_STATUS";
+    field public static final String WEB_MESSAGE_ARRAY_BUFFER = "WEB_MESSAGE_ARRAY_BUFFER";
+    field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
+    field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
+    field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
+    field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
+    field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
+    field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
+    field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
+    field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
+    field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
+    field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
+  }
+
+  @RequiresFeature(name=androidx.webkit.WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public class WebViewMediaIntegrityApiStatusConfig {
+    ctor public WebViewMediaIntegrityApiStatusConfig(androidx.webkit.WebViewMediaIntegrityApiStatusConfig.Builder);
+    method public int getDefaultStatus();
+    method public java.util.Map<java.lang.String!,java.lang.Integer!> getOverrideRules();
+    field public static final int WEBVIEW_MEDIA_INTEGRITY_API_DISABLED = 0; // 0x0
+    field public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED = 2; // 0x2
+    field public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED_WITHOUT_APP_IDENTITY = 1; // 0x1
+  }
+
+  public static final class WebViewMediaIntegrityApiStatusConfig.Builder {
+    ctor public WebViewMediaIntegrityApiStatusConfig.Builder(int);
+    method public androidx.webkit.WebViewMediaIntegrityApiStatusConfig.Builder addOverrideRule(String, int);
+    method public androidx.webkit.WebViewMediaIntegrityApiStatusConfig build();
+  }
+
+  public abstract class WebViewRenderProcess {
+    ctor public WebViewRenderProcess();
+    method public abstract boolean terminate();
+  }
+
+  public abstract class WebViewRenderProcessClient {
+    ctor public WebViewRenderProcessClient();
+    method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+    method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+  }
+
+}
+
diff --git a/webkit/webkit/src/main/java/androidx/webkit/internal/WebMessageAdapter.java b/webkit/webkit/src/main/java/androidx/webkit/internal/WebMessageAdapter.java
index 1fd56c5..4c0492b 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/internal/WebMessageAdapter.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/internal/WebMessageAdapter.java
@@ -18,11 +18,8 @@
 
 import static org.chromium.support_lib_boundary.WebMessagePayloadBoundaryInterface.WebMessagePayloadType;
 
-import android.os.Build;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.webkit.WebMessageCompat;
 import androidx.webkit.WebMessagePortCompat;
 
@@ -59,7 +56,6 @@
         return mWebMessageCompat.getData();
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     @Override
     @Nullable
     public InvocationHandler getMessagePayload() {
diff --git a/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewProviderAdapter.java b/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewProviderAdapter.java
index 68c1056..eae16ef7 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewProviderAdapter.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewProviderAdapter.java
@@ -18,7 +18,6 @@
 
 import android.annotation.SuppressLint;
 import android.net.Uri;
-import android.os.Build;
 import android.webkit.WebChromeClient;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
@@ -56,7 +55,6 @@
     /**
      * Adapter method WebViewCompat.insertVisualStateCallback().
      */
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     public void insertVisualStateCallback(
             long requestId, @NonNull WebViewCompat.VisualStateCallback callback) {
         mImpl.insertVisualStateCallback(requestId,
@@ -80,7 +78,6 @@
     /**
      * Adapter method for {@link WebViewCompat#postWebMessage(WebView, WebMessageCompat, Uri)}.
      */
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     public void postWebMessage(@NonNull WebMessageCompat message, @NonNull Uri targetOrigin) {
         mImpl.postMessageToMainFrame(
                 BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
@@ -91,7 +88,6 @@
      * Adapter method for {@link WebViewCompat#addWebMessageListener(android.webkit.WebView,
      * String, List<String>, androidx.webkit.WebViewCompat.WebMessageListener)}.
      */
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     public void addWebMessageListener(@NonNull String jsObjectName,
             @NonNull String[] allowedOriginRules,
             @NonNull WebViewCompat.WebMessageListener listener) {
@@ -160,7 +156,6 @@
     // WebViewRenderProcessClient is a callback class, so it should be last. See
     // https://issuetracker.google.com/issues/139770271.
     @SuppressLint("LambdaLast")
-    @RequiresApi(Build.VERSION_CODES.KITKAT)
     public void setWebViewRenderProcessClient(@Nullable Executor executor,
             @Nullable WebViewRenderProcessClient webViewRenderProcessClient) {
         InvocationHandler handler = webViewRenderProcessClient != null
diff --git a/window/window-core/build.gradle b/window/window-core/build.gradle
index 1462e5e..8e33dbf 100644
--- a/window/window-core/build.gradle
+++ b/window/window-core/build.gradle
@@ -46,6 +46,12 @@
                 implementation(libs.kotlinTestJunit)
             }
         }
+
+        androidInstrumentedTest {
+            dependencies {
+                implementation(libs.testRunner)
+            }
+        }
     }
 }
 
diff --git a/window/window-testing/src/androidTest/java/androidx/window/testing/layout/WindowMetricsCalculatorRuleTest.kt b/window/window-testing/src/androidTest/java/androidx/window/testing/layout/WindowMetricsCalculatorRuleTest.kt
index 95bed8b..faddb36 100644
--- a/window/window-testing/src/androidTest/java/androidx/window/testing/layout/WindowMetricsCalculatorRuleTest.kt
+++ b/window/window-testing/src/androidTest/java/androidx/window/testing/layout/WindowMetricsCalculatorRuleTest.kt
@@ -96,11 +96,9 @@
         }
     }
 
-    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     @Test
     fun testCurrentWindowMetrics_context_matchesDisplayRealSize_17to29() {
         Utils.assumePlatformAtOrBelow(Build.VERSION_CODES.Q)
-        Utils.assumePlatformAtOrAbove(Build.VERSION_CODES.JELLY_BEAN_MR1)
 
         activityRule.scenario.onActivity { activity ->
             val calculator = WindowMetricsCalculator.getOrCreate()
diff --git a/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt b/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt
index da05ab5..08e70ec 100644
--- a/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt
+++ b/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt
@@ -29,7 +29,6 @@
 import com.google.android.gms.gcm.Task
 import java.util.concurrent.TimeUnit
 import org.hamcrest.MatcherAssert.assertThat
-import org.hamcrest.Matchers.greaterThan
 import org.hamcrest.Matchers.lessThanOrEqualTo
 import org.junit.Assert.assertEquals
 import org.junit.Before
@@ -210,13 +209,15 @@
 
     @Test
     @SdkSuppress(
-        minSdkVersion = 22, // b/269194015 for minSdkVersion = 22
         maxSdkVersion = WorkManagerImpl.MAX_PRE_JOB_SCHEDULER_API_LEVEL
     )
     fun testPeriodicWorkRequest_withFlex_firstRun() {
         val request = PeriodicWorkRequestBuilder<TestWorker>(
             15L, TimeUnit.MINUTES, 5, TimeUnit.MINUTES
         ).build()
+        val now = System.currentTimeMillis()
+        `when`(mTaskConverter.now()).thenReturn(now)
+        request.workSpec.lastEnqueueTime = now
 
         val task = mTaskConverter.convert(request.workSpec)
         assertEquals(task.serviceName, WorkManagerGcmService::class.java.name)
@@ -224,12 +225,12 @@
         assertEquals(task.isUpdateCurrent, true)
         assertEquals(task.requiredNetwork, Task.NETWORK_STATE_ANY)
         assertEquals(task.requiresCharging, false)
-        assertThat(task.windowStart, greaterThan(0L)) // should be in the future
+        // should be period - flex
+        assertEquals(task.windowStart, TimeUnit.MINUTES.toSeconds(10))
     }
 
     @Test
     @SdkSuppress(
-        minSdkVersion = 22, // b/269194015 for minSdkVersion = 22
         maxSdkVersion = WorkManagerImpl.MAX_PRE_JOB_SCHEDULER_API_LEVEL
     )
     fun testPeriodicWorkRequest_withFlex_nextRun() {
@@ -241,6 +242,7 @@
         ).build()
 
         request.workSpec.lastEnqueueTime = now
+        request.workSpec.periodCount++
         val expected = TimeUnit.MINUTES.toSeconds(15L)
 
         val task = mTaskConverter.convert(request.workSpec)
diff --git a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableData.java b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableData.java
deleted file mode 100644
index 8f6d48c..0000000
--- a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableData.java
+++ /dev/null
@@ -1,248 +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.
- */
-
-package androidx.work.multiprocess.parcelable;
-
-import static androidx.work.Data.convertPrimitiveBooleanArray;
-import static androidx.work.Data.convertPrimitiveByteArray;
-import static androidx.work.Data.convertPrimitiveDoubleArray;
-import static androidx.work.Data.convertPrimitiveFloatArray;
-import static androidx.work.Data.convertPrimitiveIntArray;
-import static androidx.work.Data.convertPrimitiveLongArray;
-import static androidx.work.Data.convertToPrimitiveArray;
-import static androidx.work.multiprocess.parcelable.ParcelUtils.readBooleanValue;
-import static androidx.work.multiprocess.parcelable.ParcelUtils.writeBooleanValue;
-
-import android.annotation.SuppressLint;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-import androidx.work.Data;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link androidx.work.Data} but {@link android.os.Parcelable}.
- *
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-@SuppressLint("BanParcelableUsage")
-public class ParcelableData implements Parcelable {
-
-    // The list of supported types.
-    private static final byte TYPE_NULL = 0;
-    private static final byte TYPE_BOOLEAN = 1;
-    private static final byte TYPE_BYTE = 2;
-    private static final byte TYPE_INTEGER = 3;
-    private static final byte TYPE_LONG = 4;
-    private static final byte TYPE_FLOAT = 5;
-    private static final byte TYPE_DOUBLE = 6;
-    private static final byte TYPE_STRING = 7;
-    private static final byte TYPE_BOOLEAN_ARRAY = 8;
-    private static final byte TYPE_BYTE_ARRAY = 9;
-    private static final byte TYPE_INTEGER_ARRAY = 10;
-    private static final byte TYPE_LONG_ARRAY = 11;
-    private static final byte TYPE_FLOAT_ARRAY = 12;
-    private static final byte TYPE_DOUBLE_ARRAY = 13;
-    private static final byte TYPE_STRING_ARRAY = 14;
-
-    private final Data mData;
-
-    public ParcelableData(@NonNull Data data) {
-        mData = data;
-    }
-
-    protected ParcelableData(@NonNull Parcel in) {
-        Map<String, Object> values = new HashMap<>();
-        // size
-        int size = in.readInt();
-        for (int i = 0; i < size; i++) {
-            // entries
-            addEntry(in, values);
-        }
-        mData = new Data(values);
-    }
-
-    public static final Creator<ParcelableData> CREATOR =
-            new Creator<ParcelableData>() {
-                @Override
-                public ParcelableData createFromParcel(@NonNull Parcel in) {
-                    return new ParcelableData(in);
-                }
-
-                @Override
-                public ParcelableData[] newArray(int size) {
-                    return new ParcelableData[size];
-                }
-            };
-
-    @NonNull
-    public Data getData() {
-        return mData;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel parcel, int flags) {
-        Map<String, Object> keyValueMap = mData.getKeyValueMap();
-        // size
-        parcel.writeInt(keyValueMap.size());
-        for (Map.Entry<String, Object> entry : keyValueMap.entrySet()) {
-            writeToParcel(parcel, entry.getKey(), entry.getValue());
-        }
-    }
-
-    private void writeToParcel(
-            @NonNull Parcel parcel,
-            @NonNull String key,
-            @Nullable Object value) {
-
-        // type + value
-        if (value == null) {
-            parcel.writeByte(TYPE_NULL);
-        } else {
-            Class<?> valueType = value.getClass();
-            if (valueType == Boolean.class) {
-                parcel.writeByte(TYPE_BOOLEAN);
-                boolean booleanValue = (Boolean) value;
-                writeBooleanValue(parcel, booleanValue);
-            } else if (valueType == Byte.class) {
-                parcel.writeByte(TYPE_BYTE);
-                byte byteValue = (Byte) value;
-                parcel.writeByte(byteValue);
-            } else if (valueType == Integer.class) {
-                parcel.writeByte(TYPE_INTEGER);
-                int intValue = (Integer) value;
-                parcel.writeInt(intValue);
-            } else if (valueType == Long.class) {
-                parcel.writeByte(TYPE_LONG);
-                Long longValue = (Long) value;
-                parcel.writeLong(longValue);
-            } else if (valueType == Float.class) {
-                parcel.writeByte(TYPE_FLOAT);
-                float floatValue = (Float) value;
-                parcel.writeFloat(floatValue);
-            } else if (valueType == Double.class) {
-                parcel.writeByte(TYPE_DOUBLE);
-                double doubleValue = (Double) value;
-                parcel.writeDouble(doubleValue);
-            } else if (valueType == String.class) {
-                parcel.writeByte(TYPE_STRING);
-                String stringValue = (String) value;
-                parcel.writeString(stringValue);
-            } else if (valueType == Boolean[].class) {
-                parcel.writeByte(TYPE_BOOLEAN_ARRAY);
-                Boolean[] booleanArray = (Boolean[]) value;
-                parcel.writeBooleanArray(convertToPrimitiveArray(booleanArray));
-            } else if (valueType == Byte[].class) {
-                parcel.writeByte(TYPE_BYTE_ARRAY);
-                Byte[] byteArray = (Byte[]) value;
-                parcel.writeByteArray(convertToPrimitiveArray(byteArray));
-            } else if (valueType == Integer[].class) {
-                parcel.writeByte(TYPE_INTEGER_ARRAY);
-                Integer[] integerArray = (Integer[]) value;
-                parcel.writeIntArray(convertToPrimitiveArray(integerArray));
-            } else if (valueType == Long[].class) {
-                parcel.writeByte(TYPE_LONG_ARRAY);
-                Long[] longArray = (Long[]) value;
-                parcel.writeLongArray(convertToPrimitiveArray(longArray));
-            } else if (valueType == Float[].class) {
-                parcel.writeByte(TYPE_FLOAT_ARRAY);
-                Float[] floatArray = (Float[]) value;
-                parcel.writeFloatArray(convertToPrimitiveArray(floatArray));
-            } else if (valueType == Double[].class) {
-                parcel.writeByte(TYPE_DOUBLE_ARRAY);
-                Double[] doubleArray = (Double[]) value;
-                parcel.writeDoubleArray(convertToPrimitiveArray(doubleArray));
-            } else if (valueType == String[].class) {
-                parcel.writeByte(TYPE_STRING_ARRAY);
-                String[] stringArray = (String[]) value;
-                parcel.writeStringArray(stringArray);
-            } else {
-                // Exhaustive check
-                String message = "Unsupported value type " + valueType.getName();
-                throw new IllegalArgumentException(message);
-            }
-        }
-        // key
-        parcel.writeString(key);
-    }
-
-    private void addEntry(@NonNull Parcel parcel, @NonNull Map<String, Object> values) {
-        // type
-        int type = parcel.readByte();
-        Object value = null;
-        switch (type) {
-            case TYPE_NULL:
-                break;
-            case TYPE_BYTE:
-                value = parcel.readByte();
-                break;
-            case TYPE_BOOLEAN:
-                value = readBooleanValue(parcel);
-                break;
-            case TYPE_INTEGER:
-                value = parcel.readInt();
-                break;
-            case TYPE_LONG:
-                value = parcel.readLong();
-                break;
-            case TYPE_FLOAT:
-                value = parcel.readFloat();
-                break;
-            case TYPE_DOUBLE:
-                value = parcel.readDouble();
-                break;
-            case TYPE_STRING:
-                value = parcel.readString();
-                break;
-            case TYPE_BOOLEAN_ARRAY:
-                value = convertPrimitiveBooleanArray(parcel.createBooleanArray());
-                break;
-            case TYPE_BYTE_ARRAY:
-                value = convertPrimitiveByteArray(parcel.createByteArray());
-                break;
-            case TYPE_INTEGER_ARRAY:
-                value = convertPrimitiveIntArray(parcel.createIntArray());
-                break;
-            case TYPE_LONG_ARRAY:
-                value = convertPrimitiveLongArray(parcel.createLongArray());
-                break;
-            case TYPE_FLOAT_ARRAY:
-                value = convertPrimitiveFloatArray(parcel.createFloatArray());
-                break;
-            case TYPE_DOUBLE_ARRAY:
-                value = convertPrimitiveDoubleArray(parcel.createDoubleArray());
-                break;
-            case TYPE_STRING_ARRAY:
-                value = parcel.createStringArray();
-                break;
-            default:
-                String message = "Unsupported type " + type;
-                throw new IllegalStateException(message);
-        }
-        String key = parcel.readString();
-        values.put(key, value);
-    }
-}
diff --git a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableData.kt b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableData.kt
new file mode 100644
index 0000000..042aa2d
--- /dev/null
+++ b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableData.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package androidx.work.multiprocess.parcelable
+
+import android.annotation.SuppressLint
+import android.os.Parcel
+import android.os.Parcelable
+import androidx.annotation.RestrictTo
+import androidx.work.Data
+
+/**
+ * [androidx.work.Data] but [android.os.Parcelable].
+ *
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@SuppressLint("BanParcelableUsage")
+class ParcelableData(val data: Data) : Parcelable {
+
+    constructor(inParcel: Parcel) : this(
+        inParcel.createByteArray()?.let { Data.fromByteArray(it) } ?: Data.EMPTY
+    )
+
+    override fun describeContents(): Int {
+        return 0
+    }
+
+    override fun writeToParcel(parcel: Parcel, flags: Int) {
+        parcel.writeByteArray(data.toByteArray())
+    }
+
+    companion object {
+        @JvmField
+        val CREATOR: Parcelable.Creator<ParcelableData> =
+            object : Parcelable.Creator<ParcelableData> {
+                override fun createFromParcel(inParcel: Parcel): ParcelableData {
+                    return ParcelableData(inParcel)
+                }
+
+                override fun newArray(size: Int): Array<ParcelableData?> {
+                    return arrayOfNulls(size)
+                }
+            }
+    }
+}
diff --git a/work/work-runtime/api/api_lint.ignore b/work/work-runtime/api/api_lint.ignore
index 191ab3b..137ff05 100644
--- a/work/work-runtime/api/api_lint.ignore
+++ b/work/work-runtime/api/api_lint.ignore
@@ -55,8 +55,8 @@
 
 BuilderSetStyle: androidx.work.Data.Builder#putAll(androidx.work.Data):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putAll(androidx.work.Data)
-BuilderSetStyle: androidx.work.Data.Builder#putAll(java.util.Map<java.lang.String,java.lang.Object>):
-    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putAll(java.util.Map<java.lang.String,java.lang.Object>)
+BuilderSetStyle: androidx.work.Data.Builder#putAll(java.util.Map<java.lang.String,?>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putAll(java.util.Map<java.lang.String,?>)
 BuilderSetStyle: androidx.work.Data.Builder#putBoolean(String, boolean):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putBoolean(String,boolean)
 BuilderSetStyle: androidx.work.Data.Builder#putBooleanArray(String, boolean[]):
diff --git a/work/work-runtime/api/current.ignore b/work/work-runtime/api/current.ignore
index 43c44c7..14b1e6a 100644
--- a/work/work-runtime/api/current.ignore
+++ b/work/work-runtime/api/current.ignore
@@ -1,4 +1,6 @@
 // Baseline format: 1.0
+ChangedType: androidx.work.Data#getKeyValueMap():
+    Method androidx.work.Data.getKeyValueMap has changed return type from java.util.Map<java.lang.String,java.lang.Object> to java.util.Map<java.lang.String,java.lang.Object>
 ChangedType: androidx.work.WorkQuery#getIds():
     Method androidx.work.WorkQuery.getIds has changed return type from java.util.List<java.util.UUID!> to java.util.List<java.util.UUID>
 ChangedType: androidx.work.WorkQuery#getStates():
diff --git a/work/work-runtime/api/current.txt b/work/work-runtime/api/current.txt
index c117818..8e85f2c 100644
--- a/work/work-runtime/api/current.txt
+++ b/work/work-runtime/api/current.txt
@@ -136,25 +136,27 @@
   }
 
   public final class Data {
-    ctor public Data(androidx.work.Data);
-    method @androidx.room.TypeConverter public static androidx.work.Data fromByteArray(byte[]);
-    method public boolean getBoolean(String, boolean);
-    method public boolean[]? getBooleanArray(String);
-    method public byte getByte(String, byte);
-    method public byte[]? getByteArray(String);
-    method public double getDouble(String, double);
-    method public double[]? getDoubleArray(String);
-    method public float getFloat(String, float);
-    method public float[]? getFloatArray(String);
-    method public int getInt(String, int);
-    method public int[]? getIntArray(String);
-    method public java.util.Map<java.lang.String!,java.lang.Object!> getKeyValueMap();
-    method public long getLong(String, long);
-    method public long[]? getLongArray(String);
-    method public String? getString(String);
-    method public String![]? getStringArray(String);
-    method public <T> boolean hasKeyWithValueOfType(String, Class<T!>);
+    ctor public Data(androidx.work.Data other);
+    method @androidx.room.TypeConverter public static androidx.work.Data fromByteArray(byte[] bytes);
+    method public boolean getBoolean(String key, boolean defaultValue);
+    method public boolean[]? getBooleanArray(String key);
+    method public byte getByte(String key, byte defaultValue);
+    method public byte[]? getByteArray(String key);
+    method public double getDouble(String key, double defaultValue);
+    method public double[]? getDoubleArray(String key);
+    method public float getFloat(String key, float defaultValue);
+    method public float[]? getFloatArray(String key);
+    method public int getInt(String key, int defaultValue);
+    method public int[]? getIntArray(String key);
+    method public java.util.Map<java.lang.String,java.lang.Object> getKeyValueMap();
+    method public long getLong(String key, long defaultValue);
+    method public long[]? getLongArray(String key);
+    method public String? getString(String key);
+    method public String![]? getStringArray(String key);
+    method public <T> boolean hasKeyWithValueOfType(String key, Class<T> klass);
     method public byte[] toByteArray();
+    property public final java.util.Map<java.lang.String,java.lang.Object> keyValueMap;
+    field public static final androidx.work.Data.Companion Companion;
     field public static final androidx.work.Data EMPTY;
     field public static final int MAX_DATA_BYTES = 10240; // 0x2800
   }
@@ -162,22 +164,26 @@
   public static final class Data.Builder {
     ctor public Data.Builder();
     method public androidx.work.Data build();
-    method public androidx.work.Data.Builder putAll(androidx.work.Data);
-    method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String!,java.lang.Object!>);
-    method public androidx.work.Data.Builder putBoolean(String, boolean);
-    method public androidx.work.Data.Builder putBooleanArray(String, boolean[]);
-    method public androidx.work.Data.Builder putByte(String, byte);
-    method public androidx.work.Data.Builder putByteArray(String, byte[]);
-    method public androidx.work.Data.Builder putDouble(String, double);
-    method public androidx.work.Data.Builder putDoubleArray(String, double[]);
-    method public androidx.work.Data.Builder putFloat(String, float);
-    method public androidx.work.Data.Builder putFloatArray(String, float[]);
-    method public androidx.work.Data.Builder putInt(String, int);
-    method public androidx.work.Data.Builder putIntArray(String, int[]);
-    method public androidx.work.Data.Builder putLong(String, long);
-    method public androidx.work.Data.Builder putLongArray(String, long[]);
-    method public androidx.work.Data.Builder putString(String, String?);
-    method public androidx.work.Data.Builder putStringArray(String, String![]);
+    method public androidx.work.Data.Builder putAll(androidx.work.Data data);
+    method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String,?> values);
+    method public androidx.work.Data.Builder putBoolean(String key, boolean value);
+    method public androidx.work.Data.Builder putBooleanArray(String key, boolean[] value);
+    method public androidx.work.Data.Builder putByte(String key, byte value);
+    method public androidx.work.Data.Builder putByteArray(String key, byte[] value);
+    method public androidx.work.Data.Builder putDouble(String key, double value);
+    method public androidx.work.Data.Builder putDoubleArray(String key, double[] value);
+    method public androidx.work.Data.Builder putFloat(String key, float value);
+    method public androidx.work.Data.Builder putFloatArray(String key, float[] value);
+    method public androidx.work.Data.Builder putInt(String key, int value);
+    method public androidx.work.Data.Builder putIntArray(String key, int[] value);
+    method public androidx.work.Data.Builder putLong(String key, long value);
+    method public androidx.work.Data.Builder putLongArray(String key, long[] value);
+    method public androidx.work.Data.Builder putString(String key, String? value);
+    method public androidx.work.Data.Builder putStringArray(String key, String![] value);
+  }
+
+  public static final class Data.Companion {
+    method @androidx.room.TypeConverter public androidx.work.Data fromByteArray(byte[] bytes);
   }
 
   public final class DataKt {
diff --git a/work/work-runtime/api/restricted_current.ignore b/work/work-runtime/api/restricted_current.ignore
index 43c44c7..14b1e6a 100644
--- a/work/work-runtime/api/restricted_current.ignore
+++ b/work/work-runtime/api/restricted_current.ignore
@@ -1,4 +1,6 @@
 // Baseline format: 1.0
+ChangedType: androidx.work.Data#getKeyValueMap():
+    Method androidx.work.Data.getKeyValueMap has changed return type from java.util.Map<java.lang.String,java.lang.Object> to java.util.Map<java.lang.String,java.lang.Object>
 ChangedType: androidx.work.WorkQuery#getIds():
     Method androidx.work.WorkQuery.getIds has changed return type from java.util.List<java.util.UUID!> to java.util.List<java.util.UUID>
 ChangedType: androidx.work.WorkQuery#getStates():
diff --git a/work/work-runtime/api/restricted_current.txt b/work/work-runtime/api/restricted_current.txt
index c117818..8e85f2c 100644
--- a/work/work-runtime/api/restricted_current.txt
+++ b/work/work-runtime/api/restricted_current.txt
@@ -136,25 +136,27 @@
   }
 
   public final class Data {
-    ctor public Data(androidx.work.Data);
-    method @androidx.room.TypeConverter public static androidx.work.Data fromByteArray(byte[]);
-    method public boolean getBoolean(String, boolean);
-    method public boolean[]? getBooleanArray(String);
-    method public byte getByte(String, byte);
-    method public byte[]? getByteArray(String);
-    method public double getDouble(String, double);
-    method public double[]? getDoubleArray(String);
-    method public float getFloat(String, float);
-    method public float[]? getFloatArray(String);
-    method public int getInt(String, int);
-    method public int[]? getIntArray(String);
-    method public java.util.Map<java.lang.String!,java.lang.Object!> getKeyValueMap();
-    method public long getLong(String, long);
-    method public long[]? getLongArray(String);
-    method public String? getString(String);
-    method public String![]? getStringArray(String);
-    method public <T> boolean hasKeyWithValueOfType(String, Class<T!>);
+    ctor public Data(androidx.work.Data other);
+    method @androidx.room.TypeConverter public static androidx.work.Data fromByteArray(byte[] bytes);
+    method public boolean getBoolean(String key, boolean defaultValue);
+    method public boolean[]? getBooleanArray(String key);
+    method public byte getByte(String key, byte defaultValue);
+    method public byte[]? getByteArray(String key);
+    method public double getDouble(String key, double defaultValue);
+    method public double[]? getDoubleArray(String key);
+    method public float getFloat(String key, float defaultValue);
+    method public float[]? getFloatArray(String key);
+    method public int getInt(String key, int defaultValue);
+    method public int[]? getIntArray(String key);
+    method public java.util.Map<java.lang.String,java.lang.Object> getKeyValueMap();
+    method public long getLong(String key, long defaultValue);
+    method public long[]? getLongArray(String key);
+    method public String? getString(String key);
+    method public String![]? getStringArray(String key);
+    method public <T> boolean hasKeyWithValueOfType(String key, Class<T> klass);
     method public byte[] toByteArray();
+    property public final java.util.Map<java.lang.String,java.lang.Object> keyValueMap;
+    field public static final androidx.work.Data.Companion Companion;
     field public static final androidx.work.Data EMPTY;
     field public static final int MAX_DATA_BYTES = 10240; // 0x2800
   }
@@ -162,22 +164,26 @@
   public static final class Data.Builder {
     ctor public Data.Builder();
     method public androidx.work.Data build();
-    method public androidx.work.Data.Builder putAll(androidx.work.Data);
-    method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String!,java.lang.Object!>);
-    method public androidx.work.Data.Builder putBoolean(String, boolean);
-    method public androidx.work.Data.Builder putBooleanArray(String, boolean[]);
-    method public androidx.work.Data.Builder putByte(String, byte);
-    method public androidx.work.Data.Builder putByteArray(String, byte[]);
-    method public androidx.work.Data.Builder putDouble(String, double);
-    method public androidx.work.Data.Builder putDoubleArray(String, double[]);
-    method public androidx.work.Data.Builder putFloat(String, float);
-    method public androidx.work.Data.Builder putFloatArray(String, float[]);
-    method public androidx.work.Data.Builder putInt(String, int);
-    method public androidx.work.Data.Builder putIntArray(String, int[]);
-    method public androidx.work.Data.Builder putLong(String, long);
-    method public androidx.work.Data.Builder putLongArray(String, long[]);
-    method public androidx.work.Data.Builder putString(String, String?);
-    method public androidx.work.Data.Builder putStringArray(String, String![]);
+    method public androidx.work.Data.Builder putAll(androidx.work.Data data);
+    method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String,?> values);
+    method public androidx.work.Data.Builder putBoolean(String key, boolean value);
+    method public androidx.work.Data.Builder putBooleanArray(String key, boolean[] value);
+    method public androidx.work.Data.Builder putByte(String key, byte value);
+    method public androidx.work.Data.Builder putByteArray(String key, byte[] value);
+    method public androidx.work.Data.Builder putDouble(String key, double value);
+    method public androidx.work.Data.Builder putDoubleArray(String key, double[] value);
+    method public androidx.work.Data.Builder putFloat(String key, float value);
+    method public androidx.work.Data.Builder putFloatArray(String key, float[] value);
+    method public androidx.work.Data.Builder putInt(String key, int value);
+    method public androidx.work.Data.Builder putIntArray(String key, int[] value);
+    method public androidx.work.Data.Builder putLong(String key, long value);
+    method public androidx.work.Data.Builder putLongArray(String key, long[] value);
+    method public androidx.work.Data.Builder putString(String key, String? value);
+    method public androidx.work.Data.Builder putStringArray(String key, String![] value);
+  }
+
+  public static final class Data.Companion {
+    method @androidx.room.TypeConverter public androidx.work.Data fromByteArray(byte[] bytes);
   }
 
   public final class DataKt {
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/constraints/trackers/NetworkStateTrackerTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/constraints/trackers/NetworkStateTrackerTest.java
index afbaf5b..7b4f8c3 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/constraints/trackers/NetworkStateTrackerTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/constraints/trackers/NetworkStateTrackerTest.java
@@ -65,16 +65,6 @@
 
     @Test
     @SmallTest
-    @SdkSuppress(maxSdkVersion = 15)
-    public void testGetInitialState_nullNetworkInfoSdk15() {
-        // API < 16 conservatively treats null networkInfo as metered.
-        NetworkState expectedState = new NetworkState(false, false, true, false);
-        assertThat(mTracker.readSystemState(), is(expectedState));
-    }
-
-    @Test
-    @SmallTest
-    @SdkSuppress(minSdkVersion = 16)
     public void testGetInitialState_nullNetworkInfo() {
         NetworkState expectedState = new NetworkState(false, false, false, false);
         assertThat(mTracker.readSystemState(), is(expectedState));
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt
index d7e25ac..5e34fba 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt
@@ -68,7 +68,7 @@
     @Test(expected = IllegalStateException::class)
     @MediumTest
     // Mockito tries to class load android.os.CancellationSignal which is only available on API >= 16
-    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 29)
+    @SdkSuppress(maxSdkVersion = 29)
     public fun setForeground_whenWorkReplaced() {
         val foregroundUpdater =
             WorkForegroundUpdater(mDatabase, mForegroundProcessor, mTaskExecutor)
@@ -83,7 +83,7 @@
     @Test(expected = IllegalStateException::class)
     @MediumTest
     // Mockito tries to class load android.os.CancellationSignal which is only available on API >= 16
-    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 29)
+    @SdkSuppress(maxSdkVersion = 29)
     public fun setForeground_whenWorkFinished() {
         `when`(mWorkSpecDao.getState(anyString())).thenReturn(WorkInfo.State.SUCCEEDED)
         val foregroundUpdater =
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt
index eaf7b7b..b812e9e 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt
@@ -19,7 +19,6 @@
 import android.content.Context
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import androidx.test.filters.SdkSuppress
 import androidx.work.Data
 import androidx.work.WorkInfo
 import androidx.work.impl.WorkDatabase
@@ -36,7 +35,6 @@
 
 @RunWith(AndroidJUnit4::class)
 // Mockito tries to class load android.os.CancellationSignal which is only available on API >= 16
-@SdkSuppress(minSdkVersion = 16)
 class WorkProgressUpdaterTest {
     private lateinit var mContext: Context
     private lateinit var mDatabase: WorkDatabase
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java
index 72a068d..72d4ff3 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 
@@ -155,9 +154,7 @@
 
     @After
     public void tearDown() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            mHandlerThread.quitSafely();
-        }
+        mHandlerThread.quitSafely();
     }
 
     @Test
diff --git a/work/work-runtime/src/main/java/androidx/work/ArrayCreatingInputMerger.kt b/work/work-runtime/src/main/java/androidx/work/ArrayCreatingInputMerger.kt
index aa4bb47..08373d9 100644
--- a/work/work-runtime/src/main/java/androidx/work/ArrayCreatingInputMerger.kt
+++ b/work/work-runtime/src/main/java/androidx/work/ArrayCreatingInputMerger.kt
@@ -51,7 +51,8 @@
                     // First time encountering this key.
                     if (valueClass.isArray) {
                         // Arrays carry over as-is.
-                        value
+                        // if valueClass.isArray is true then value isn't null
+                        value as Any
                     } else {
                         // Primitives get turned into size 1 arrays.
                         createArrayFor(value, valueClass)
@@ -62,7 +63,8 @@
                     when {
                         existingValueClass == valueClass -> {
                             // The classes match; we can merge.
-                            concatenateArrays(existingValue, value)
+                            // both classes are arrays in this case => value isn't null
+                            concatenateArrays(existingValue, value as Any)
                         }
                         existingValueClass.componentType == valueClass -> {
                             // We have an existing array of the same type.
diff --git a/work/work-runtime/src/main/java/androidx/work/Data.java b/work/work-runtime/src/main/java/androidx/work/Data.java
deleted file mode 100644
index bfe97f1..0000000
--- a/work/work-runtime/src/main/java/androidx/work/Data.java
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- * Copyright 2018 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.work;
-
-import android.annotation.SuppressLint;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-import androidx.annotation.VisibleForTesting;
-import androidx.room.TypeConverter;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A persistable set of key/value pairs which are used as inputs and outputs for
- * {@link ListenableWorker}s.  Keys are Strings, and values can be Strings, primitive types, or
- * their array variants.
- * <p>
- * This is a lightweight container, and should not be considered your data store.  As such, there is
- * an enforced {@link #MAX_DATA_BYTES} limit on the serialized (byte array) size of the payloads.
- * This class will throw {@link IllegalStateException}s if you try to serialize or deserialize past
- * this limit.
- */
-
-public final class Data {
-
-    private static final String TAG = Logger.tagWithPrefix("Data");
-
-    /**
-     * An empty Data object with no elements.
-     */
-    public static final Data EMPTY = new Data.Builder().build();
-
-    /**
-     * The maximum number of bytes for Data when it is serialized (converted to a byte array).
-     * Please see the class-level Javadoc for more information.
-     */
-    @SuppressLint("MinMaxConstant")
-    public static final int MAX_DATA_BYTES = 10 * 1024;    // 10KB
-
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-            Map<String, Object> mValues;
-
-    Data() {    // stub required for room
-    }
-
-    public Data(@NonNull Data other) {
-        mValues = new HashMap<>(other.mValues);
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public Data(@NonNull Map<String, ?> values) {
-        mValues = new HashMap<>(values);
-    }
-
-    /**
-     * Gets the boolean value for the given key.
-     *
-     * @param key          The key for the argument
-     * @param defaultValue The default value to return if the key is not found
-     * @return The value specified by the key if it exists; the default value otherwise
-     */
-    public boolean getBoolean(@NonNull String key, boolean defaultValue) {
-        Object value = mValues.get(key);
-        if (value instanceof Boolean) {
-            return (boolean) value;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Gets the boolean array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public boolean[] getBooleanArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof Boolean[]) {
-            Boolean[] array = (Boolean[]) value;
-            return convertToPrimitiveArray(array);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the byte value for the given key.
-     *
-     * @param key          The key for the argument
-     * @param defaultValue The default value to return if the key is not found
-     * @return The value specified by the key if it exists; the default value otherwise
-     */
-    public byte getByte(@NonNull String key, byte defaultValue) {
-        Object value = mValues.get(key);
-        if (value instanceof Byte) {
-            return (byte) value;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Gets the byte array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public byte[] getByteArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof Byte[]) {
-            Byte[] array = (Byte[]) value;
-            return convertToPrimitiveArray(array);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the integer value for the given key.
-     *
-     * @param key          The key for the argument
-     * @param defaultValue The default value to return if the key is not found
-     * @return The value specified by the key if it exists; the default value otherwise
-     */
-    public int getInt(@NonNull String key, int defaultValue) {
-        Object value = mValues.get(key);
-        if (value instanceof Integer) {
-            return (int) value;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Gets the integer array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public int[] getIntArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof Integer[]) {
-            Integer[] array = (Integer[]) value;
-            return convertToPrimitiveArray(array);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the long value for the given key.
-     *
-     * @param key          The key for the argument
-     * @param defaultValue The default value to return if the key is not found
-     * @return The value specified by the key if it exists; the default value otherwise
-     */
-    public long getLong(@NonNull String key, long defaultValue) {
-        Object value = mValues.get(key);
-        if (value instanceof Long) {
-            return (long) value;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Gets the long array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public long[] getLongArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof Long[]) {
-            Long[] array = (Long[]) value;
-            return convertToPrimitiveArray(array);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the float value for the given key.
-     *
-     * @param key          The key for the argument
-     * @param defaultValue The default value to return if the key is not found
-     * @return The value specified by the key if it exists; the default value otherwise
-     */
-    public float getFloat(@NonNull String key, float defaultValue) {
-        Object value = mValues.get(key);
-        if (value instanceof Float) {
-            return (float) value;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Gets the float array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public float[] getFloatArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof Float[]) {
-            Float[] array = (Float[]) value;
-            return convertToPrimitiveArray(array);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the double value for the given key.
-     *
-     * @param key          The key for the argument
-     * @param defaultValue The default value to return if the key is not found
-     * @return The value specified by the key if it exists; the default value otherwise
-     */
-    public double getDouble(@NonNull String key, double defaultValue) {
-        Object value = mValues.get(key);
-        if (value instanceof Double) {
-            return (double) value;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Gets the double array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public double[] getDoubleArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof Double[]) {
-            Double[] array = (Double[]) value;
-            return convertToPrimitiveArray(array);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the String value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public String getString(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof String) {
-            return (String) value;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the String array value for the given key.
-     *
-     * @param key The key for the argument
-     * @return The value specified by the key if it exists; {@code null} otherwise
-     */
-    @Nullable
-    public String[] getStringArray(@NonNull String key) {
-        Object value = mValues.get(key);
-        if (value instanceof String[]) {
-            return (String[]) value;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets all the values in this Data object.
-     *
-     * @return A {@link Map} of key-value pairs for this object; this Map is unmodifiable and should
-     * be used for reads only.
-     */
-    @NonNull
-    public Map<String, Object> getKeyValueMap() {
-        return Collections.unmodifiableMap(mValues);
-    }
-
-    /**
-     * Converts this Data to a byte array suitable for sending to other processes in your
-     * application.  There are no versioning guarantees with this byte array, so you should not
-     * use this for IPCs between applications or persistence.
-     *
-     * @return The byte array representation of the input
-     * @throws IllegalStateException if the serialized payload is bigger than
-     *                               {@link #MAX_DATA_BYTES}
-     */
-    @NonNull
-    public byte[] toByteArray() {
-        return Data.toByteArrayInternal(this);
-    }
-
-    /**
-     * Returns {@code true} if the instance of {@link Data} has a non-null value corresponding to
-     * the given {@link String} key with the expected type of {@code T}.
-     *
-     * @param key   The {@link String} key
-     * @param klass The {@link Class} container for the expected type
-     * @param <T>   The expected type
-     * @return {@code true} If the instance of {@link Data} has a value for the given
-     * {@link String} key with the expected type.
-     */
-    public <T> boolean hasKeyWithValueOfType(@NonNull String key, @NonNull Class<T> klass) {
-        Object value = mValues.get(key);
-        return value != null && klass.isAssignableFrom(value.getClass());
-    }
-
-    /**
-     * @return The number of elements in this Data object.
-     */
-    @VisibleForTesting
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public int size() {
-        return mValues.size();
-    }
-
-    /**
-     * Converts {@link Data} to a byte array for persistent storage.
-     *
-     * @param data The {@link Data} object to convert
-     * @return The byte array representation of the input
-     * @throws IllegalStateException if the serialized payload is bigger than
-     *                               {@link #MAX_DATA_BYTES}
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @TypeConverter
-    @NonNull
-    public static byte[] toByteArrayInternal(@NonNull Data data) {
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        ObjectOutputStream objectOutputStream = null;
-        try {
-            objectOutputStream = new ObjectOutputStream(outputStream);
-            objectOutputStream.writeInt(data.size());
-            for (Map.Entry<String, Object> entry : data.mValues.entrySet()) {
-                objectOutputStream.writeUTF(entry.getKey());
-                objectOutputStream.writeObject(entry.getValue());
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Error in Data#toByteArray: ", e);
-            return outputStream.toByteArray();
-        } finally {
-            if (objectOutputStream != null) {
-                try {
-                    // NOTE: this writes something to the output stream for bookkeeping purposes.
-                    // Don't get the byteArray before we do this!
-                    objectOutputStream.close();
-                } catch (IOException e) {
-                    Log.e(TAG, "Error in Data#toByteArray: ", e);
-                }
-            }
-            try {
-                outputStream.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Error in Data#toByteArray: ", e);
-            }
-        }
-
-        if (outputStream.size() > MAX_DATA_BYTES) {
-            throw new IllegalStateException(
-                    "Data cannot occupy more than " + MAX_DATA_BYTES
-                            + " bytes when serialized");
-        }
-        return outputStream.toByteArray();
-    }
-
-    /**
-     * Converts a byte array to {@link Data}.
-     *
-     * @param bytes The byte array representation to convert
-     * @return An {@link Data} object built from the input
-     * @throws IllegalStateException if bytes is bigger than {@link #MAX_DATA_BYTES}
-     */
-    @TypeConverter
-    @NonNull
-    public static Data fromByteArray(@NonNull byte[] bytes) {
-        if (bytes.length > MAX_DATA_BYTES) {
-            throw new IllegalStateException(
-                    "Data cannot occupy more than " + MAX_DATA_BYTES + " bytes when serialized");
-        }
-
-        Map<String, Object> map = new HashMap<>();
-        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
-        ObjectInputStream objectInputStream = null;
-        try {
-            objectInputStream = new ObjectInputStream(inputStream);
-            for (int i = objectInputStream.readInt(); i > 0; i--) {
-                map.put(objectInputStream.readUTF(), objectInputStream.readObject());
-            }
-        } catch (IOException | ClassNotFoundException e) {
-            Log.e(TAG, "Error in Data#fromByteArray: ", e);
-        } finally {
-            if (objectInputStream != null) {
-                try {
-                    objectInputStream.close();
-                } catch (IOException e) {
-                    Log.e(TAG, "Error in Data#fromByteArray: ", e);
-                }
-            }
-            try {
-                inputStream.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Error in Data#fromByteArray: ", e);
-            }
-        }
-        return new Data(map);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        Data other = (Data) o;
-        Set<String> keys = mValues.keySet();
-        if (!keys.equals(other.mValues.keySet())) {
-            return false;
-        }
-
-        for (String key : keys) {
-            Object value = mValues.get(key);
-            Object otherValue = other.mValues.get(key);
-            boolean equal;
-            if (value == null || otherValue == null) {
-                equal = value == otherValue;
-            } else if (value instanceof Object[] && otherValue instanceof Object[]) {
-                equal = Arrays.deepEquals((Object[]) value, (Object[]) otherValue);
-            } else {
-                equal = value.equals(otherValue);
-            }
-
-            if (!equal) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * mValues.hashCode();
-    }
-
-    @NonNull
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("Data {");
-        if (!mValues.isEmpty()) {
-            for (String key : mValues.keySet()) {
-                sb.append(key).append(" : ");
-                Object value = mValues.get(key);
-                if (value instanceof Object[]) {
-                    sb.append(Arrays.toString((Object[]) value));
-                } else {
-                    sb.append(value);
-                }
-                sb.append(", ");
-            }
-        }
-        sb.append("}");
-        return sb.toString();
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static Boolean[] convertPrimitiveBooleanArray(@NonNull boolean[] value) {
-        Boolean[] returnValue = new Boolean[value.length];
-        for (int i = 0; i < value.length; ++i) {
-            returnValue[i] = value[i];
-        }
-        return returnValue;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static Byte[] convertPrimitiveByteArray(@NonNull byte[] value) {
-        Byte[] returnValue = new Byte[value.length];
-        for (int i = 0; i < value.length; ++i) {
-            returnValue[i] = value[i];
-        }
-        return returnValue;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static Integer[] convertPrimitiveIntArray(@NonNull int[] value) {
-        Integer[] returnValue = new Integer[value.length];
-        for (int i = 0; i < value.length; ++i) {
-            returnValue[i] = value[i];
-        }
-        return returnValue;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static Long[] convertPrimitiveLongArray(@NonNull long[] value) {
-        Long[] returnValue = new Long[value.length];
-        for (int i = 0; i < value.length; ++i) {
-            returnValue[i] = value[i];
-        }
-        return returnValue;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static Float[] convertPrimitiveFloatArray(@NonNull float[] value) {
-        Float[] returnValue = new Float[value.length];
-        for (int i = 0; i < value.length; ++i) {
-            returnValue[i] = value[i];
-        }
-        return returnValue;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static Double[] convertPrimitiveDoubleArray(@NonNull double[] value) {
-        Double[] returnValue = new Double[value.length];
-        for (int i = 0; i < value.length; ++i) {
-            returnValue[i] = value[i];
-        }
-        return returnValue;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static boolean[] convertToPrimitiveArray(@NonNull Boolean[] array) {
-        boolean[] returnArray = new boolean[array.length];
-        for (int i = 0; i < array.length; ++i) {
-            returnArray[i] = array[i];
-        }
-        return returnArray;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static byte[] convertToPrimitiveArray(@NonNull Byte[] array) {
-        byte[] returnArray = new byte[array.length];
-        for (int i = 0; i < array.length; ++i) {
-            returnArray[i] = array[i];
-        }
-        return returnArray;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static int[] convertToPrimitiveArray(@NonNull Integer[] array) {
-        int[] returnArray = new int[array.length];
-        for (int i = 0; i < array.length; ++i) {
-            returnArray[i] = array[i];
-        }
-        return returnArray;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static long[] convertToPrimitiveArray(@NonNull Long[] array) {
-        long[] returnArray = new long[array.length];
-        for (int i = 0; i < array.length; ++i) {
-            returnArray[i] = array[i];
-        }
-        return returnArray;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static float[] convertToPrimitiveArray(@NonNull Float[] array) {
-        float[] returnArray = new float[array.length];
-        for (int i = 0; i < array.length; ++i) {
-            returnArray[i] = array[i];
-        }
-        return returnArray;
-    }
-
-    /**
-     */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @NonNull
-    public static double[] convertToPrimitiveArray(@NonNull Double[] array) {
-        double[] returnArray = new double[array.length];
-        for (int i = 0; i < array.length; ++i) {
-            returnArray[i] = array[i];
-        }
-        return returnArray;
-    }
-
-    /**
-     * A builder for {@link Data} objects.
-     */
-    public static final class Builder {
-
-        private Map<String, Object> mValues = new HashMap<>();
-
-        /**
-         * Puts a boolean into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putBoolean(@NonNull String key, boolean value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts a boolean array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putBooleanArray(@NonNull String key, @NonNull boolean[] value) {
-            mValues.put(key, convertPrimitiveBooleanArray(value));
-            return this;
-        }
-
-        /**
-         * Puts an byte into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putByte(@NonNull String key, byte value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts an integer array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putByteArray(@NonNull String key, @NonNull byte[] value) {
-            mValues.put(key, convertPrimitiveByteArray(value));
-            return this;
-        }
-
-        /**
-         * Puts an integer into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putInt(@NonNull String key, int value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts an integer array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putIntArray(@NonNull String key, @NonNull int[] value) {
-            mValues.put(key, convertPrimitiveIntArray(value));
-            return this;
-        }
-
-        /**
-         * Puts a long into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putLong(@NonNull String key, long value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts a long array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putLongArray(@NonNull String key, @NonNull long[] value) {
-            mValues.put(key, convertPrimitiveLongArray(value));
-            return this;
-        }
-
-        /**
-         * Puts a float into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putFloat(@NonNull String key, float value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts a float array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putFloatArray(@NonNull String key, @NonNull float[] value) {
-            mValues.put(key, convertPrimitiveFloatArray(value));
-            return this;
-        }
-
-        /**
-         * Puts a double into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putDouble(@NonNull String key, double value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts a double array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putDoubleArray(@NonNull String key, @NonNull double[] value) {
-            mValues.put(key, convertPrimitiveDoubleArray(value));
-            return this;
-        }
-
-        /**
-         * Puts a String into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putString(@NonNull String key, @Nullable String value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts a String array into the arguments.
-         *
-         * @param key   The key for this argument
-         * @param value The value for this argument
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putStringArray(@NonNull String key, @NonNull String[] value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        /**
-         * Puts all input key-value pairs from a {@link Data} into the Builder.
-         * <p>
-         * Valid value types are: Boolean, Integer, Long, Float, Double, String, and their array
-         * versions.  Invalid types will throw an {@link IllegalArgumentException}.
-         *
-         * @param data {@link Data} containing key-value pairs to add
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putAll(@NonNull Data data) {
-            putAll(data.mValues);
-            return this;
-        }
-
-        /**
-         * Puts all input key-value pairs from a {@link Map} into the Builder.
-         * <p>
-         * Valid value types are: Boolean, Integer, Long, Float, Double, String, and their array
-         * versions.  Invalid types will throw an {@link IllegalArgumentException}.
-         *
-         * @param values A {@link Map} of key-value pairs to add
-         * @return The {@link Builder}
-         */
-        @NonNull
-        public Builder putAll(@NonNull Map<String, Object> values) {
-            for (Map.Entry<String, Object> entry : values.entrySet()) {
-                String key = entry.getKey();
-                Object value = entry.getValue();
-                put(key, value);
-            }
-            return this;
-        }
-
-        /**
-         * Puts an input key-value pair into the Builder. Valid types are: Boolean, Integer,
-         * Long, Float, Double, String, and array versions of each of those types.
-         * Invalid types throw an {@link IllegalArgumentException}.
-         *
-         * @param key   A {@link String} key to add
-         * @param value A nullable {@link Object} value to add of the valid types
-         * @return The {@link Builder}
-         */
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-        @NonNull
-        public Builder put(@NonNull String key, @Nullable Object value) {
-            if (value == null) {
-                mValues.put(key, null);
-            } else {
-                Class<?> valueType = value.getClass();
-                if (valueType == Boolean.class
-                        || valueType == Byte.class
-                        || valueType == Integer.class
-                        || valueType == Long.class
-                        || valueType == Float.class
-                        || valueType == Double.class
-                        || valueType == String.class
-                        || valueType == Boolean[].class
-                        || valueType == Byte[].class
-                        || valueType == Integer[].class
-                        || valueType == Long[].class
-                        || valueType == Float[].class
-                        || valueType == Double[].class
-                        || valueType == String[].class) {
-                    mValues.put(key, value);
-                } else if (valueType == boolean[].class) {
-                    mValues.put(key, convertPrimitiveBooleanArray((boolean[]) value));
-                } else if (valueType == byte[].class) {
-                    mValues.put(key, convertPrimitiveByteArray((byte[]) value));
-                } else if (valueType == int[].class) {
-                    mValues.put(key, convertPrimitiveIntArray((int[]) value));
-                } else if (valueType == long[].class) {
-                    mValues.put(key, convertPrimitiveLongArray((long[]) value));
-                } else if (valueType == float[].class) {
-                    mValues.put(key, convertPrimitiveFloatArray((float[]) value));
-                } else if (valueType == double[].class) {
-                    mValues.put(key, convertPrimitiveDoubleArray((double[]) value));
-                } else {
-                    throw new IllegalArgumentException(
-                            "Key " + key + " has invalid type " + valueType);
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Builds a {@link Data} object.
-         *
-         * @return The {@link Data} object containing all key-value pairs specified by this
-         * {@link Builder}.
-         */
-        @NonNull
-        public Data build() {
-            Data data = new Data(mValues);
-            // Make sure we catch Data objects that are too large at build() instead of later.  This
-            // method will throw an exception if data is too big.
-            Data.toByteArrayInternal(data);
-            return data;
-        }
-    }
-}
diff --git a/work/work-runtime/src/main/java/androidx/work/Data_.kt b/work/work-runtime/src/main/java/androidx/work/Data_.kt
new file mode 100644
index 0000000..0c8d296
--- /dev/null
+++ b/work/work-runtime/src/main/java/androidx/work/Data_.kt
@@ -0,0 +1,611 @@
+/*
+ * Copyright 2018 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.work
+
+import android.annotation.SuppressLint
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+import androidx.room.TypeConverter
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.IOException
+import java.io.ObjectInputStream
+import java.io.ObjectOutputStream
+import java.util.Collections
+
+/**
+ * A persistable set of key/value pairs which are used as inputs and outputs for
+ * [ListenableWorker]s.  Keys are Strings, and values can be Strings, primitive types, or
+ * their array variants.
+ *
+ * This is a lightweight container, and should not be considered your data store.  As such, there is
+ * an enforced [.MAX_DATA_BYTES] limit on the serialized (byte array) size of the payloads.
+ * This class will throw [IllegalStateException]s if you try to serialize or deserialize past
+ * this limit.
+ */
+class Data {
+    private val values: Map<String, Any?>
+
+    /**
+     * Copy constructor
+     */
+    constructor(other: Data) {
+        values = HashMap(other.values)
+    }
+
+    internal constructor(values: Map<String, *>) {
+        this.values = HashMap(values)
+    }
+
+    private inline fun <reified T : Any> getOrDefault(key: String, defaultValue: T): T {
+        val value = values[key]
+        return if (value is T) value else defaultValue
+    }
+
+    private inline fun <reified T : Any, TArray> getTypedArray(
+        key: String,
+        constructor: (size: Int, init: (index: Int) -> T) -> TArray
+    ): TArray? {
+        val value = values[key]
+        return if (value is Array<*> && value.isArrayOf<T>())
+            constructor(value.size) { i -> value[i] as T }
+        else null
+    }
+
+    /**
+     * Gets the boolean value for the given key.
+     *
+     * @param key          The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    fun getBoolean(key: String, defaultValue: Boolean): Boolean = getOrDefault(key, defaultValue)
+
+    /**
+     * Gets the boolean array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getBooleanArray(key: String): BooleanArray? = getTypedArray(key, ::BooleanArray)
+
+    /**
+     * Gets the byte value for the given key.
+     *
+     * @param key          The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    fun getByte(key: String, defaultValue: Byte): Byte = getOrDefault(key, defaultValue)
+
+    /**
+     * Gets the byte array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getByteArray(key: String): ByteArray? = getTypedArray(key, ::ByteArray)
+
+    /**
+     * Gets the integer value for the given key.
+     *
+     * @param key          The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    fun getInt(key: String, defaultValue: Int): Int = getOrDefault(key, defaultValue)
+
+    /**
+     * Gets the integer array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getIntArray(key: String): IntArray? = getTypedArray(key, ::IntArray)
+
+    /**
+     * Gets the long value for the given key.
+     *
+     * @param key          The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    fun getLong(key: String, defaultValue: Long): Long = getOrDefault(key, defaultValue)
+
+    /**
+     * Gets the long array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getLongArray(key: String): LongArray? = getTypedArray(key, ::LongArray)
+
+    /**
+     * Gets the float value for the given key.
+     *
+     * @param key          The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    fun getFloat(key: String, defaultValue: Float): Float = getOrDefault(key, defaultValue)
+
+    /**
+     * Gets the float array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getFloatArray(key: String): FloatArray? = getTypedArray(key, ::FloatArray)
+
+    /**
+     * Gets the double value for the given key.
+     *
+     * @param key          The key for the argument
+     * @param defaultValue The default value to return if the key is not found
+     * @return The value specified by the key if it exists; the default value otherwise
+     */
+    fun getDouble(key: String, defaultValue: Double): Double = getOrDefault(key, defaultValue)
+
+    /**
+     * Gets the double array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getDoubleArray(key: String): DoubleArray? = getTypedArray(key, ::DoubleArray)
+
+    /**
+     * Gets the String value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getString(key: String): String? = values[key] as? String
+
+    /**
+     * Gets the String array value for the given key.
+     *
+     * @param key The key for the argument
+     * @return The value specified by the key if it exists; `null` otherwise
+     */
+    fun getStringArray(key: String): Array<String>? = getTypedArray(key, ::Array)
+
+    val keyValueMap: Map<String, Any?>
+        /**
+         * Gets all the values in this Data object.
+         *
+         * @return A [Map] of key-value pairs for this object; this Map is unmodifiable and should
+         * be used for reads only.
+         */
+        get() = Collections.unmodifiableMap(values)
+
+    /**
+     * Converts this Data to a byte array suitable for sending to other processes in your
+     * application.  There are no versioning guarantees with this byte array, so you should not
+     * use this for IPCs between applications or persistence.
+     *
+     * @return The byte array representation of the input
+     * @throws IllegalStateException if the serialized payload is bigger than
+     * [.MAX_DATA_BYTES]
+     */
+    fun toByteArray(): ByteArray = toByteArrayInternal(this)
+
+    /**
+     * Returns `true` if the instance of [Data] has a non-null value corresponding to
+     * the given [String] key with the expected type of `T`.
+     *
+     * @param key   The [String] key
+     * @param klass The [Class] container for the expected type
+     * @return `true` If the instance of [Data] has a value for the given
+     * [String] key with the expected type.
+     */
+    fun <T> hasKeyWithValueOfType(key: String, klass: Class<T>): Boolean {
+        val value = values[key]
+        return value != null && klass.isAssignableFrom(value.javaClass)
+    }
+
+    /**
+     * @return The number of elements in this Data object.
+     */
+    @VisibleForTesting
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun size(): Int = values.size
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) {
+            return true
+        }
+        if (other == null || javaClass != other.javaClass) {
+            return false
+        }
+        val otherData = other as Data
+        val keys = values.keys
+        if (keys != otherData.values.keys) {
+            return false
+        }
+        for (key in keys) {
+            val value = values[key]
+            val otherValue = otherData.values[key]
+            val equal = if (value == null || otherValue == null) {
+                value === otherValue
+            } else if (value is Array<*> && value.isArrayOf<Any>() &&
+                otherValue is Array<*> && otherValue.isArrayOf<Any>()
+            ) {
+                value.contentDeepEquals(otherValue)
+            } else {
+                value == otherValue
+            }
+            if (!equal) return false
+        }
+        return true
+    }
+
+    override fun hashCode(): Int {
+        return 31 * values.hashCode()
+    }
+
+    override fun toString(): String = buildString {
+        append("Data {")
+        val content = values.entries.joinToString { (key, value) ->
+            "$key : ${if (value is Array<*>) value.contentToString() else value}"
+        }
+        append(content)
+        append("}")
+    }
+
+    /**
+     * A builder for [Data] objects.
+     */
+    class Builder {
+        private val values: MutableMap<String, Any?> = mutableMapOf()
+
+        private fun putDirect(key: String, value: Any?): Builder {
+            values[key] = value
+            return this
+        }
+
+        /**
+         * Puts a boolean into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putBoolean(key: String, value: Boolean): Builder = putDirect(key, value)
+
+        /**
+         * Puts a boolean array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putBooleanArray(key: String, value: BooleanArray): Builder {
+            values[key] = convertPrimitiveArray(value)
+            return this
+        }
+
+        /**
+         * Puts an byte into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putByte(key: String, value: Byte): Builder = putDirect(key, value)
+
+        /**
+         * Puts an integer array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putByteArray(key: String, value: ByteArray): Builder {
+            values[key] = convertPrimitiveArray(value)
+            return this
+        }
+
+        /**
+         * Puts an integer into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putInt(key: String, value: Int): Builder = putDirect(key, value)
+
+        /**
+         * Puts an integer array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putIntArray(key: String, value: IntArray): Builder {
+            values[key] = convertPrimitiveArray(value)
+            return this
+        }
+
+        /**
+         * Puts a long into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putLong(key: String, value: Long): Builder = putDirect(key, value)
+
+        /**
+         * Puts a long array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putLongArray(key: String, value: LongArray): Builder {
+            values[key] = convertPrimitiveArray(value)
+            return this
+        }
+
+        /**
+         * Puts a float into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putFloat(key: String, value: Float): Builder = putDirect(key, value)
+
+        /**
+         * Puts a float array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putFloatArray(key: String, value: FloatArray): Builder {
+            values[key] = convertPrimitiveArray(value)
+            return this
+        }
+
+        /**
+         * Puts a double into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putDouble(key: String, value: Double): Builder = putDirect(key, value)
+
+        /**
+         * Puts a double array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putDoubleArray(key: String, value: DoubleArray): Builder {
+            values[key] = convertPrimitiveArray(value)
+            return this
+        }
+
+        /**
+         * Puts a String into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putString(key: String, value: String?): Builder = putDirect(key, value)
+
+        /**
+         * Puts a String array into the arguments.
+         *
+         * @param key   The key for this argument
+         * @param value The value for this argument
+         * @return The [Builder]
+         */
+        fun putStringArray(key: String, value: Array<String?>): Builder = putDirect(key, value)
+
+        /**
+         * Puts all input key-value pairs from a [Data] into the Builder.
+         *
+         * Valid value types are: Boolean, Integer, Long, Float, Double, String, and their array
+         * versions.  Invalid types will throw an [IllegalArgumentException].
+         *
+         * @param data [Data] containing key-value pairs to add
+         * @return The [Builder]
+         */
+        fun putAll(data: Data): Builder {
+            putAll(data.values)
+            return this
+        }
+
+        /**
+         * Puts all input key-value pairs from a [Map] into the Builder.
+         *
+         * Valid value types are: Boolean, Integer, Long, Float, Double, String, and their array
+         * versions.  Invalid types will throw an [IllegalArgumentException].
+         *
+         * @param values A [Map] of key-value pairs to add
+         * @return The [Builder]
+         */
+        fun putAll(values: Map<String, Any?>): Builder {
+            values.forEach { (key, value) -> put(key, value) }
+            return this
+        }
+
+        /**
+         * Puts an input key-value pair into the Builder. Valid types are: Boolean, Integer,
+         * Long, Float, Double, String, and array versions of each of those types.
+         * Invalid types throw an [IllegalArgumentException].
+         *
+         * @param key   A [String] key to add
+         * @param value A nullable [Object] value to add of the valid types
+         * @return The [Builder]
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        fun put(key: String, value: Any?): Builder {
+            values[key] = if (value == null) {
+                null
+            } else {
+                when (val valueType = value::class) {
+                    Boolean::class,
+                    Byte::class,
+                    Int::class,
+                    Long::class,
+                    Float::class,
+                    Double::class,
+                    String::class,
+                    Array<Boolean>::class,
+                    Array<Byte>::class,
+                    Array<Int>::class,
+                    Array<Long>::class,
+                    Array<Float>::class,
+                    Array<Double>::class,
+                    Array<String>::class -> value
+
+                    BooleanArray::class -> convertPrimitiveArray(value as BooleanArray)
+                    ByteArray::class -> convertPrimitiveArray(value as ByteArray)
+                    IntArray::class -> convertPrimitiveArray(value as IntArray)
+                    LongArray::class -> convertPrimitiveArray(value as LongArray)
+                    FloatArray::class -> convertPrimitiveArray(value as FloatArray)
+                    DoubleArray::class -> convertPrimitiveArray(value as DoubleArray)
+
+                    else -> throw IllegalArgumentException("Key $key has invalid type $valueType")
+                }
+            }
+            return this
+        }
+
+        /**
+         * Builds a [Data] object.
+         *
+         * @return The [Data] object containing all key-value pairs specified by this
+         * [Builder].
+         */
+        fun build(): Data {
+            val data = Data(values)
+            // Make sure we catch Data objects that are too large at build() instead of later.  This
+            // method will throw an exception if data is too big.
+            toByteArrayInternal(data)
+            return data
+        }
+    }
+
+    companion object {
+        /**
+         * An empty Data object with no elements.
+         */
+        @JvmField
+        val EMPTY = Builder().build()
+
+        /**
+         * The maximum number of bytes for Data when it is serialized (converted to a byte array).
+         * Please see the class-level Javadoc for more information.
+         */
+        @SuppressLint("MinMaxConstant")
+        const val MAX_DATA_BYTES = 10 * 1024 // 10KB
+
+        /**
+         * Converts [Data] to a byte array for persistent storage.
+         *
+         * @param data The [Data] object to convert
+         * @return The byte array representation of the input
+         * @throws IllegalStateException if the serialized payload is bigger than
+         * [.MAX_DATA_BYTES]
+         */
+        @JvmStatic
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @TypeConverter
+        fun toByteArrayInternal(data: Data): ByteArray {
+            return try {
+                val stream = ByteArrayOutputStream().use { outputStream ->
+                    ObjectOutputStream(outputStream).use { objectOutputStream ->
+                        objectOutputStream.writeInt(data.size())
+                        for ((key, value) in data.values) {
+                            objectOutputStream.writeUTF(key)
+                            objectOutputStream.writeObject(value)
+                        }
+                    }
+                    outputStream
+                }
+                if (stream.size() > MAX_DATA_BYTES)
+                    throw IllegalStateException(
+                        "Data cannot occupy more than $MAX_DATA_BYTES bytes when serialized"
+                    )
+
+                stream.toByteArray()
+            } catch (e: IOException) {
+                loge(TAG, e) { "Error in Data#toByteArray: " }
+                ByteArray(0)
+            }
+        }
+
+        /**
+         * Converts a byte array to [Data].
+         *
+         * @param bytes The byte array representation to convert
+         * @return An [Data] object built from the input
+         * @throws IllegalStateException if bytes is bigger than [.MAX_DATA_BYTES]
+         */
+        @JvmStatic
+        @TypeConverter
+        fun fromByteArray(bytes: ByteArray): Data {
+            check(bytes.size <= MAX_DATA_BYTES) {
+                "Data cannot occupy more than $MAX_DATA_BYTES bytes when serialized"
+            }
+            if (bytes.isEmpty()) return EMPTY
+
+            val map = mutableMapOf<String, Any?>()
+            try {
+                ByteArrayInputStream(bytes).use { inputStream ->
+                    ObjectInputStream(inputStream).use { objectInputStream ->
+                        repeat(objectInputStream.readInt()) {
+                            map[objectInputStream.readUTF()] = objectInputStream.readObject()
+                        }
+                    }
+                }
+            } catch (e: IOException) {
+                loge(TAG, e) { "Error in Data#fromByteArray: " }
+            } catch (e: ClassNotFoundException) {
+                loge(TAG, e) { "Error in Data#fromByteArray: " }
+            }
+            return Data(map)
+        }
+    }
+}
+
+private fun convertPrimitiveArray(value: BooleanArray): Array<Boolean> =
+    Array(value.size) { i -> value[i] }
+
+private fun convertPrimitiveArray(value: ByteArray): Array<Byte> =
+    Array(value.size) { i -> value[i] }
+
+private fun convertPrimitiveArray(value: IntArray): Array<Int> =
+    Array(value.size) { i -> value[i] }
+
+private fun convertPrimitiveArray(value: LongArray): Array<Long> =
+    Array(value.size) { i -> value[i] }
+
+private fun convertPrimitiveArray(value: FloatArray): Array<Float> =
+    Array(value.size) { i -> value[i] }
+
+private fun convertPrimitiveArray(value: DoubleArray): Array<Double> =
+    Array(value.size) { i -> value[i] }
+
+private val TAG = Logger.tagWithPrefix("Data")
diff --git a/work/work-runtime/src/main/java/androidx/work/LoggerExt.kt b/work/work-runtime/src/main/java/androidx/work/LoggerExt.kt
new file mode 100644
index 0000000..27be27c
--- /dev/null
+++ b/work/work-runtime/src/main/java/androidx/work/LoggerExt.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.work
+
+internal inline fun logd(tag: String, block: () -> String) = Logger.get().debug(tag, block())
+internal inline fun logi(tag: String, block: () -> String) = Logger.get().info(tag, block())
+internal inline fun logi(tag: String, t: Throwable, block: () -> String) =
+    Logger.get().info(tag, block(), t)
+
+internal inline fun loge(tag: String, block: () -> String) = Logger.get().error(tag, block())
+internal inline fun loge(tag: String, t: Throwable, block: () -> String) =
+    Logger.get().info(tag, block(), t)
diff --git a/work/work-runtime/src/main/java/androidx/work/OverwritingInputMerger.kt b/work/work-runtime/src/main/java/androidx/work/OverwritingInputMerger.kt
index 5c4bd8a..1f00b8b 100644
--- a/work/work-runtime/src/main/java/androidx/work/OverwritingInputMerger.kt
+++ b/work/work-runtime/src/main/java/androidx/work/OverwritingInputMerger.kt
@@ -24,7 +24,7 @@
 class OverwritingInputMerger : InputMerger() {
     override fun merge(inputs: List<Data>): Data {
         val output = Data.Builder()
-        val mergedValues = mutableMapOf<String, Any>()
+        val mergedValues = mutableMapOf<String, Any?>()
         for (input in inputs) {
             mergedValues.putAll(input.keyValueMap)
         }
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt b/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
index 6468de7..7fe3201 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
+++ b/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
@@ -41,6 +41,9 @@
 import androidx.work.impl.utils.WorkProgressUpdater
 import androidx.work.impl.utils.futures.SettableFuture
 import androidx.work.impl.utils.taskexecutor.TaskExecutor
+import androidx.work.logd
+import androidx.work.loge
+import androidx.work.logi
 import com.google.common.util.concurrent.ListenableFuture
 import java.util.UUID
 import java.util.concurrent.Callable
@@ -102,10 +105,9 @@
             // running, finished, or is blocked.
             if (workSpec.state !== WorkInfo.State.ENQUEUED) {
                 resolveIncorrectStatus()
-                Logger.get().debug(
-                    TAG,
+                logd(TAG) {
                     "${workSpec.workerClassName} is not in ENQUEUED state. Nothing more to do"
-                )
+                }
                 return@Callable true
             }
 
@@ -150,10 +152,7 @@
             val inputMerger =
                 inputMergerFactory.createInputMergerWithDefaultFallback(inputMergerClassName)
             if (inputMerger == null) {
-                Logger.get().error(
-                    TAG,
-                    "Could not create Input Merger ${workSpec.inputMergerClassName}"
-                )
+                loge(TAG) { "Could not create Input Merger ${workSpec.inputMergerClassName}" }
                 setFailedAndResolve()
                 return
             }
@@ -185,19 +184,15 @@
         }
         val worker = worker
         if (worker == null) {
-            Logger.get().error(
-                TAG,
-                "Could not create Worker ${workSpec.workerClassName}"
-            )
+            loge(TAG) { "Could not create Worker ${workSpec.workerClassName}" }
             setFailedAndResolve()
             return
         }
         if (worker.isUsed) {
-            Logger.get().error(
-                TAG,
+            loge(TAG) {
                 "Received an already-used Worker ${workSpec.workerClassName}; " +
                     "Worker Factory should return new instances"
-            )
+            }
             setFailedAndResolve()
             return
         }
@@ -233,10 +228,7 @@
                 }
                 try {
                     runExpedited.get()
-                    Logger.get().debug(
-                        TAG,
-                        "Starting work for ${workSpec.workerClassName}"
-                    )
+                    logd(TAG) { "Starting work for ${workSpec.workerClassName}" }
                     // Call mWorker.startWork() on the main thread.
                     workerResultFuture.setFuture(worker.startWork())
                 } catch (e: Throwable) {
@@ -251,33 +243,26 @@
                     // If the ListenableWorker returns a null result treat it as a failure.
                     val result = workerResultFuture.get()
                     if (result == null) {
-                        Logger.get().error(
-                            TAG, workSpec.workerClassName +
+                        loge(TAG) {
+                            workSpec.workerClassName +
                                 " returned a null result. Treating it as a failure."
-                        )
+                        }
                     } else {
-                        Logger.get().debug(
-                            TAG,
-                            "${workSpec.workerClassName} returned a $result."
-                        )
+                        logd(TAG) { "${workSpec.workerClassName} returned a $result." }
                         this.result = result
                     }
                 } catch (exception: CancellationException) {
                     // Cancellations need to be treated with care here because innerFuture
                     // cancellations will bubble up, and we need to gracefully handle that.
-                    Logger.get().info(TAG, "$workDescription was cancelled", exception)
+                    logi(TAG, exception) { "$workDescription was cancelled" }
                 } catch (exception: InterruptedException) {
-                    Logger.get().error(
-                        TAG,
-                        "$workDescription failed because it threw an exception/error",
-                        exception
-                    )
+                    loge(TAG, exception) {
+                        "$workDescription failed because it threw an exception/error"
+                    }
                 } catch (exception: ExecutionException) {
-                    Logger.get().error(
-                        TAG,
-                        "$workDescription failed because it threw an exception/error",
-                        exception
-                    )
+                    loge(TAG, exception) {
+                        "$workDescription failed because it threw an exception/error"
+                    }
                 } finally {
                     onWorkFinished()
                 }
@@ -324,25 +309,20 @@
         if (worker != null && workerResultFuture.isCancelled()) {
             worker.stop(stopReason)
         } else {
-            val message = "WorkSpec $workSpec is already done. Not interrupting."
-            Logger.get().debug(TAG, message)
+            logd(TAG) { "WorkSpec $workSpec is already done. Not interrupting." }
         }
     }
 
     private fun resolveIncorrectStatus() {
         val status = workSpecDao.getState(workSpecId)
         if (status === WorkInfo.State.RUNNING) {
-            Logger.get().debug(
-                TAG,
+            logd(TAG) {
                 "Status for $workSpecId is RUNNING; not doing any work and " +
                     "rescheduling for later execution"
-            )
+            }
             resolve(true)
         } else {
-            Logger.get().debug(
-                TAG,
-                "Status for $workSpecId is $status ; not doing any work"
-            )
+            logd(TAG) { "Status for $workSpecId is $status ; not doing any work" }
             resolve(false)
         }
     }
@@ -354,7 +334,7 @@
         // Worker exceeding a 10 min execution window.
         // One scheduler completing a Worker, and telling other Schedulers to cleanup.
         if (interrupted != WorkInfo.STOP_REASON_NOT_STOPPED) {
-            Logger.get().debug(TAG, "Work interrupted for $workDescription")
+            logd(TAG) { "Work interrupted for $workDescription" }
             val currentState = workSpecDao.getState(workSpecId)
             if (currentState == null) {
                 // This can happen because of a beginUniqueWork(..., REPLACE, ...).  Notify the
@@ -397,26 +377,17 @@
 
     private fun handleResult(result: ListenableWorker.Result) {
         if (result is ListenableWorker.Result.Success) {
-            Logger.get().info(
-                TAG,
-                "Worker result SUCCESS for $workDescription"
-            )
+            logi(TAG) { "Worker result SUCCESS for $workDescription" }
             if (workSpec.isPeriodic) {
                 resetPeriodicAndResolve()
             } else {
                 setSucceededAndResolve()
             }
         } else if (result is ListenableWorker.Result.Retry) {
-            Logger.get().info(
-                TAG,
-                "Worker result RETRY for $workDescription"
-            )
+            logi(TAG) { "Worker result RETRY for $workDescription" }
             rescheduleAndResolve()
         } else {
-            Logger.get().info(
-                TAG,
-                "Worker result FAILURE for $workDescription"
-            )
+            logi(TAG) { "Worker result FAILURE for $workDescription" }
             if (workSpec.isPeriodic) {
                 resetPeriodicAndResolve()
             } else {
@@ -509,10 +480,7 @@
                 if (workSpecDao.getState(dependentWorkId) === WorkInfo.State.BLOCKED &&
                     dependencyDao.hasCompletedAllPrerequisites(dependentWorkId)
                 ) {
-                    Logger.get().info(
-                        TAG,
-                        "Setting status to enqueued for $dependentWorkId"
-                    )
+                    logi(TAG) { "Setting status to enqueued for $dependentWorkId" }
                     workSpecDao.setState(WorkInfo.State.ENQUEUED, dependentWorkId)
                     workSpecDao.setLastEnqueueTime(dependentWorkId, currentTimeMillis)
                 }
diff --git a/work/work-runtime/src/test/java/androidx/work/DataTest.java b/work/work-runtime/src/test/java/androidx/work/DataTest.java
index e31ffbc..a245b4c 100644
--- a/work/work-runtime/src/test/java/androidx/work/DataTest.java
+++ b/work/work-runtime/src/test/java/androidx/work/DataTest.java
@@ -119,7 +119,7 @@
     public void testToString() {
         Data data = createData();
         String result = data.toString();
-        for (String key : data.mValues.keySet()) {
+        for (String key : data.getKeyValueMap().keySet()) {
             assertThat(result, containsString(key));
         }
     }