Merge "Fix testDensityChangeInvalidatesDrawWithCache" into androidx-main
diff --git a/compose/animation/animation-core/src/androidInstrumentedTest/kotlin/androidx/compose/animation/core/PathEasingTest.kt b/compose/animation/animation-core/src/androidInstrumentedTest/kotlin/androidx/compose/animation/core/PathEasingTest.kt
index 1566c9e..8f9d455 100644
--- a/compose/animation/animation-core/src/androidInstrumentedTest/kotlin/androidx/compose/animation/core/PathEasingTest.kt
+++ b/compose/animation/animation-core/src/androidInstrumentedTest/kotlin/androidx/compose/animation/core/PathEasingTest.kt
@@ -21,7 +21,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
-import java.lang.IllegalStateException
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
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 86ba661..816bec4 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
@@ -28,8 +28,8 @@
 
 @RunWith(JUnit4::class)
 class EasingTest {
-    private val ZeroEpsilon = -(1.0f.ulp)
-    private val OneEpsilon = 1.0f + 1.0f.ulp
+    private val ZeroEpsilon = -(1.0f.ulp * 2.0f)
+    private val OneEpsilon = 1.0f + 1.0f.ulp * 2.0f
 
     @Test
     fun cubicBezierStartsAt0() {
@@ -108,12 +108,49 @@
 
     @Test
     fun canSolveCubicForFractionsCloseToOne() {
-        val curve = CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)
+        // Only test curves defined in [0..1]
+        // For instance, EaseInOutBack is defined in a larger domain, so exclude it from the list
+        val curves =
+            listOf(
+                CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f),
+                Ease,
+                EaseIn,
+                EaseInBack,
+                EaseInCirc,
+                EaseInCubic,
+                EaseInExpo,
+                EaseInOut,
+                EaseInOutCirc,
+                EaseInOutCubic,
+                EaseInOutExpo,
+                EaseInOutQuad,
+                EaseInOutQuart,
+                EaseInOutQuint,
+                EaseInOutSine,
+                EaseInOutQuad,
+                EaseInOutQuart,
+                EaseInOutQuint,
+                EaseInSine,
+                EaseOut,
+                EaseOutCirc,
+                EaseOutCubic,
+                EaseOutExpo,
+                EaseOutQuad,
+                EaseOutQuart,
+                EaseOutQuint,
+                EaseOutSine
+            )
 
-        // Test the last 16 ulps until 1.0f
-        for (i in 0x3f7ffff0..0x3f7fffff) {
-            val t = curve.transform(floatFromBits(i))
-            assertTrue(t in -ZeroEpsilon..OneEpsilon)
+        for (curve in curves) {
+            // Test the last 16 ulps until 1.0f
+            for (i in 0x3f7ffff0..0x3f7fffff) {
+                val fraction = floatFromBits(i)
+                val t = curve.transform(fraction)
+                assertTrue(
+                    "f($fraction) = $t out of range for $curve",
+                    t in -ZeroEpsilon..OneEpsilon
+                )
+            }
         }
     }
 }
diff --git a/compose/material3/adaptive/samples/build.gradle b/compose/material3/adaptive/samples/build.gradle
index ea8aec0..08e4e4e 100644
--- a/compose/material3/adaptive/samples/build.gradle
+++ b/compose/material3/adaptive/samples/build.gradle
@@ -38,6 +38,7 @@
 
     implementation("androidx.compose.foundation:foundation:1.6.0-rc01")
     implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
+    implementation("androidx.compose.material:material-icons-core:1.6.8")
     implementation(project(":compose:material3:adaptive:adaptive-layout"))
     implementation(project(":compose:material3:adaptive:adaptive-navigation"))
     implementation(project(":compose:material3:material3"))
diff --git a/compose/material3/integration-tests/macrobenchmark-target/build.gradle b/compose/material3/integration-tests/macrobenchmark-target/build.gradle
index c19b92d..c3ee0c6 100644
--- a/compose/material3/integration-tests/macrobenchmark-target/build.gradle
+++ b/compose/material3/integration-tests/macrobenchmark-target/build.gradle
@@ -20,4 +20,5 @@
 dependencies {
     implementation(project(":activity:activity-compose"))
     implementation(project(":compose:material3:material3"))
+    implementation("androidx.compose.material:material-icons-core:1.6.8")
 }
diff --git a/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle b/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle
index 19ae106..d65e6a8 100644
--- a/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle
+++ b/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle
@@ -38,6 +38,7 @@
 
     implementation("androidx.compose.foundation:foundation:1.6.0-rc01")
     implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
+    implementation("androidx.compose.material:material-icons-core:1.6.8")
     implementation(project(":compose:material3:adaptive:adaptive"))
     implementation(project(":compose:material3:material3"))
     implementation(project(":compose:material3:material3-adaptive-navigation-suite"))
diff --git a/compose/material3/material3-common/build.gradle b/compose/material3/material3-common/build.gradle
index c488a59..13b52b2 100644
--- a/compose/material3/material3-common/build.gradle
+++ b/compose/material3/material3-common/build.gradle
@@ -35,6 +35,7 @@
 androidXMultiplatform {
     android()
     jvmStubs()
+    linuxX64Stubs()
 
     defaultPlatform(PlatformIdentifier.ANDROID)
 
@@ -43,11 +44,11 @@
             dependencies {
                 implementation(libs.kotlinStdlib)
                 implementation(project(":compose:ui:ui-util"))
-                api("androidx.compose.foundation:foundation:1.6.0")
-                api("androidx.compose.foundation:foundation-layout:1.6.0")
+                api(project(":compose:foundation:foundation"))
+                api(project(":compose:foundation:foundation-layout"))
                 api(project(":compose:runtime:runtime"))
-                api("androidx.compose.ui:ui-graphics:1.6.0")
-                api("androidx.compose.ui:ui-text:1.6.0")
+                api(project(":compose:ui:ui-graphics"))
+                api(project(":compose:ui:ui-text"))
             }
         }
 
@@ -69,10 +70,16 @@
             }
         }
 
+        commonStubsMain {
+            dependsOn(commonMain)
+        }
+
         jvmStubsMain {
-            dependsOn(jvmMain)
-            dependencies {
-            }
+            dependsOn(commonStubsMain)
+        }
+
+        linuxx64StubsMain {
+            dependsOn(commonStubsMain)
         }
 
         androidInstrumentedTest {
@@ -80,6 +87,7 @@
             dependencies {
                 implementation(project(":compose:material3:material3"))
                 implementation(project(":compose:material3:material3-common"))
+                implementation("androidx.compose.material:material-icons-core:1.6.8")
                 implementation(project(":compose:test-utils"))
                 implementation(libs.testRules)
                 implementation(libs.junit)
diff --git a/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt b/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt
index 3f463fcf..f2bcce7 100644
--- a/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt
+++ b/compose/material3/material3-common/src/commonMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.kt
@@ -73,11 +73,13 @@
                 "interactions if the element would measure smaller"
     }
 
-    override fun hashCode(): Int = System.identityHashCode(this)
+    override fun hashCode(): Int = identifyHashCode(this)
 
     override fun equals(other: Any?) = (other === this)
 }
 
+internal expect inline fun identifyHashCode(value: Any): Int
+
 internal class MinimumInteractiveModifierNode :
     Modifier.Node(), CompositionLocalConsumerModifierNode, LayoutModifierNode {
     override fun MeasureScope.measure(
diff --git a/compose/material3/material3-common/src/commonStubsMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.commonStubs.kt b/compose/material3/material3-common/src/commonStubsMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.commonStubs.kt
new file mode 100644
index 0000000..0332b5c
--- /dev/null
+++ b/compose/material3/material3-common/src/commonStubsMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.commonStubs.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024 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.common
+
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun identifyHashCode(value: Any): Int = implementedInJetBrainsFork()
diff --git a/compose/material3/material3-common/src/commonStubsMain/kotlin/androidx/compose/material3/common/NotImplemented.commonStubs.kt b/compose/material3/material3-common/src/commonStubsMain/kotlin/androidx/compose/material3/common/NotImplemented.commonStubs.kt
new file mode 100644
index 0000000..dfb855a
--- /dev/null
+++ b/compose/material3/material3-common/src/commonStubsMain/kotlin/androidx/compose/material3/common/NotImplemented.commonStubs.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2024 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.common
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun implementedInJetBrainsFork(): Nothing =
+    throw NotImplementedError(
+        """
+        Implemented only in JetBrains fork.
+        Please use `org.jetbrains.compose.material3:material3-common` package instead.
+        """
+            .trimIndent()
+    )
diff --git a/compose/material3/material3-common/src/jvmMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.jvm.kt b/compose/material3/material3-common/src/jvmMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.jvm.kt
new file mode 100644
index 0000000..280a27c
--- /dev/null
+++ b/compose/material3/material3-common/src/jvmMain/kotlin/androidx/compose/material3/common/InteractiveComponentSize.jvm.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024 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.common
+
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun identifyHashCode(value: Any): Int = System.identityHashCode(value)
diff --git a/compose/material3/material3-window-size-class/build.gradle b/compose/material3/material3-window-size-class/build.gradle
index f9109995..f31ae70 100644
--- a/compose/material3/material3-window-size-class/build.gradle
+++ b/compose/material3/material3-window-size-class/build.gradle
@@ -33,6 +33,7 @@
 androidXMultiplatform {
     android()
     jvmStubs()
+    linuxX64Stubs()
 
     defaultPlatform(PlatformIdentifier.ANDROID)
 
@@ -40,10 +41,10 @@
         commonMain {
             dependencies {
                 implementation(libs.kotlinStdlib)
-                implementation("androidx.compose.ui:ui-util:1.6.0")
-                api("androidx.compose.runtime:runtime:1.7.0-beta02")
-                api("androidx.compose.ui:ui:1.6.0")
-                api("androidx.compose.ui:ui-unit:1.6.0")
+                implementation(project(":compose:ui:ui-util"))
+                api(project(":compose:runtime:runtime"))
+                api(project(":compose:ui:ui"))
+                api(project(":compose:ui:ui-unit"))
             }
         }
 
@@ -66,10 +67,16 @@
             }
         }
 
+        commonStubsMain {
+            dependsOn(commonMain)
+        }
+
         jvmStubsMain {
-            dependsOn(jvmMain)
-            dependencies {
-            }
+            dependsOn(commonStubsMain)
+        }
+
+        linuxx64StubsMain {
+            dependsOn(commonStubsMain)
         }
 
         androidInstrumentedTest {
diff --git a/compose/material3/material3-window-size-class/src/commonStubsMain/kotlin/androidx/compose/material3/windowsizeclass/TestOnly.stubsCommon.kt b/compose/material3/material3-window-size-class/src/commonStubsMain/kotlin/androidx/compose/material3/windowsizeclass/TestOnly.stubsCommon.kt
new file mode 100644
index 0000000..a4e3587
--- /dev/null
+++ b/compose/material3/material3-window-size-class/src/commonStubsMain/kotlin/androidx/compose/material3/windowsizeclass/TestOnly.stubsCommon.kt
@@ -0,0 +1,19 @@
+/*
+ * 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.material3.windowsizeclass
+
+@MustBeDocumented actual annotation class TestOnly()
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index ea41305..1d4ba66 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -33,6 +33,7 @@
 androidXMultiplatform {
     android()
     jvmStubs()
+    linuxX64Stubs()
 
     defaultPlatform(PlatformIdentifier.ANDROID)
 
@@ -41,17 +42,16 @@
             dependencies {
                 implementation(libs.kotlinStdlib)
                 // Keep pinned unless there is a need for tip of tree behavior
-                implementation("androidx.collection:collection:1.4.0")
-                implementation("androidx.compose.animation:animation-core:1.6.0")
-                implementation("androidx.compose.ui:ui-util:1.6.0")
-                api("androidx.compose.foundation:foundation:1.7.0-beta02")
-                api("androidx.compose.foundation:foundation-layout:1.7.0-beta02")
-                api("androidx.compose.material:material-icons-core:1.6.0")
-                api("androidx.compose.material:material-ripple:1.7.0-beta02")
-                api("androidx.compose.runtime:runtime:1.7.0-beta02")
-                api("androidx.compose.ui:ui:1.6.0")
-                api("androidx.compose.ui:ui-text:1.6.0")
-                api("androidx.graphics:graphics-shapes:1.0.0-beta01")
+                implementation("androidx.collection:collection:1.4.1")
+                implementation(project(":compose:animation:animation-core"))
+                implementation(project(":compose:ui:ui-util"))
+                api(project(":compose:foundation:foundation"))
+                api(project(":compose:foundation:foundation-layout"))
+                api(project(":compose:material:material-ripple"))
+                api(project(":compose:runtime:runtime"))
+                api(project(":compose:ui:ui"))
+                api(project(":compose:ui:ui-text"))
+                api(project(":graphics:graphics-shapes"))
             }
         }
 
@@ -72,15 +72,20 @@
                 api("androidx.annotation:annotation:1.1.0")
                 api("androidx.annotation:annotation-experimental:1.4.1")
                 implementation("androidx.activity:activity-compose:1.8.2")
-
                 implementation("androidx.lifecycle:lifecycle-common-java8:2.6.1")
             }
         }
 
+        commonStubsMain {
+            dependsOn(commonMain)
+        }
+
         jvmStubsMain {
-            dependsOn(jvmMain)
-            dependencies {
-            }
+            dependsOn(commonStubsMain)
+        }
+
+        linuxx64StubsMain {
+            dependsOn(commonStubsMain)
         }
 
         androidUnitTest {
@@ -100,6 +105,7 @@
                 implementation(project(":compose:test-utils"))
                 implementation(project(':compose:foundation:foundation-layout'))
                 implementation(project(':compose:foundation:foundation'))
+                implementation("androidx.compose.material:material-icons-core:1.6.8")
                 implementation(project(":test:screenshot:screenshot"))
                 implementation(projectOrArtifact(":core:core"))
                 implementation(libs.testRules)
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DateInput.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DateInput.android.kt
new file mode 100644
index 0000000..4f33650
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DateInput.android.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2024 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
+
+import androidx.compose.material3.internal.CalendarDate
+import androidx.compose.material3.internal.DateInputFormat
+import androidx.compose.runtime.Stable
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Stable
+internal actual class DateInputValidator
+actual constructor(
+    private val yearRange: IntRange,
+    private val selectableDates: SelectableDates,
+    private val dateInputFormat: DateInputFormat,
+    private val dateFormatter: DatePickerFormatter,
+    private val errorDatePattern: String,
+    private val errorDateOutOfYearRange: String,
+    private val errorInvalidNotAllowed: String,
+    private val errorInvalidRangeInput: String
+) {
+    /**
+     * the currently selected start date in milliseconds. Only checked against when the
+     * [InputIdentifier] is [InputIdentifier.EndDateInput].
+     */
+    actual var currentStartDateMillis: Long? = null
+
+    /**
+     * the currently selected end date in milliseconds. Only checked against when the
+     * [InputIdentifier] is [InputIdentifier.StartDateInput].
+     */
+    actual var currentEndDateMillis: Long? = null
+
+    actual fun validate(
+        dateToValidate: CalendarDate?,
+        inputIdentifier: InputIdentifier,
+        locale: CalendarLocale
+    ): String {
+        if (dateToValidate == null) {
+            return errorDatePattern.format(dateInputFormat.patternWithDelimiters.uppercase())
+        }
+        // Check that the date is within the valid range of years.
+        if (!yearRange.contains(dateToValidate.year)) {
+            return errorDateOutOfYearRange.format(
+                yearRange.first.toLocalString(),
+                yearRange.last.toLocalString()
+            )
+        }
+        // Check that the provided SelectableDates allows this date to be selected.
+        with(selectableDates) {
+            if (
+                !isSelectableYear(dateToValidate.year) ||
+                    !isSelectableDate(dateToValidate.utcTimeMillis)
+            ) {
+                return errorInvalidNotAllowed.format(
+                    dateFormatter.formatDate(
+                        dateMillis = dateToValidate.utcTimeMillis,
+                        locale = locale
+                    )
+                )
+            }
+        }
+
+        // Additional validation when the InputIdentifier is for start of end dates in a range input
+        if (
+            (inputIdentifier == InputIdentifier.StartDateInput &&
+                dateToValidate.utcTimeMillis >= (currentEndDateMillis ?: Long.MAX_VALUE)) ||
+                (inputIdentifier == InputIdentifier.EndDateInput &&
+                    dateToValidate.utcTimeMillis < (currentStartDateMillis ?: Long.MIN_VALUE))
+        ) {
+            // The input start date is after the end date, or the end date is before the start date.
+            return errorInvalidRangeInput
+        }
+
+        return ""
+    }
+}
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DatePicker.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DatePicker.android.kt
new file mode 100644
index 0000000..d5e94bf
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DatePicker.android.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 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
+
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun formatDatePickerNavigateToYearString(
+    template: String,
+    localizedYear: String
+): String = template.format(localizedYear)
+
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun formatHeadlineDescription(
+    template: String,
+    verboseDateDescription: String
+): String = template.format(verboseDateDescription)
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt
index 146b300..95bcbd4 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt
@@ -35,8 +35,7 @@
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.text.selection.LocalTextSelectionColors
 import androidx.compose.foundation.text.selection.TextSelectionColors
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowDropDown
+import androidx.compose.material3.internal.Icons
 import androidx.compose.material3.internal.MenuPosition
 import androidx.compose.material3.internal.Strings
 import androidx.compose.material3.internal.getString
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/InteractiveComponentSize.android.kt
similarity index 63%
copy from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt
copy to compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/InteractiveComponentSize.android.kt
index 02ed679..a4ebf46 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/InteractiveComponentSize.android.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 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.
@@ -16,11 +16,5 @@
 
 package androidx.compose.material3
 
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.ReadOnlyComposable
-
-/** Returns the default [CalendarLocale]. */
-@Composable
-@ReadOnlyComposable
-@OptIn(ExperimentalMaterial3Api::class)
-internal actual fun defaultLocale(): CalendarLocale = implementedInJetBrainsFork()
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun identityHashCode(value: Any): Int = System.identityHashCode(value)
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.android.kt
new file mode 100644
index 0000000..95a2223
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.android.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2024 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.internal
+
+import kotlinx.coroutines.CancellationException
+
+internal actual class AnchoredDragFinishedSignal actual constructor() :
+    CancellationException("Anchored drag finished") {
+    override fun fillInStackTrace(): Throwable {
+        stackTrace = emptyArray()
+        return this
+    }
+}
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/CalendarModel.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/CalendarModel.android.kt
index dad7b59..59ca59a 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/CalendarModel.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/CalendarModel.android.kt
@@ -64,3 +64,38 @@
         LegacyCalendarModelImpl.formatWithPattern(utcTimeMillis, pattern, locale, cache)
     }
 }
+
+/**
+ * Receives a given local date format string and returns a string that can be displayed to the user
+ * and parsed by the date parser.
+ *
+ * This function:
+ * - Removes all characters that don't match `d`, `M` and `y`, or any of the date format delimiters
+ *   `.`, `/` and `-`.
+ * - Ensures that the format is for two digits day and month, and four digits year.
+ *
+ * The output of this cleanup is always a 10 characters string in one of the following variations:
+ * - yyyy/MM/dd
+ * - yyyy-MM-dd
+ * - yyyy.MM.dd
+ * - dd/MM/yyyy
+ * - dd-MM-yyyy
+ * - dd.MM.yyyy
+ * - MM/dd/yyyy
+ */
+internal actual fun datePatternAsInputFormat(localeFormat: String): DateInputFormat {
+    val patternWithDelimiters =
+        localeFormat
+            .replace(Regex("[^dMy/\\-.]"), "")
+            .replace(Regex("d{1,2}"), "dd")
+            .replace(Regex("M{1,2}"), "MM")
+            .replace(Regex("y{1,4}"), "yyyy")
+            .replace("My", "M/y") // Edge case for the Kako locale
+            .removeSuffix(".") // Removes a dot suffix that appears in some formats
+
+    val delimiterRegex = Regex("[/\\-.]")
+    val delimiterMatchResult = delimiterRegex.find(patternWithDelimiters)
+    val delimiterIndex = delimiterMatchResult!!.groups[0]!!.range.first
+    val delimiter = patternWithDelimiters.substring(delimiterIndex, delimiterIndex + 1)
+    return DateInputFormat(patternWithDelimiters = patternWithDelimiters, delimiter = delimiter[0])
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
index a96d1d7..cd94958 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
@@ -94,6 +94,7 @@
 import androidx.compose.ui.unit.isFinite
 import androidx.compose.ui.unit.isSpecified
 import androidx.compose.ui.util.fastFirst
+import kotlin.jvm.JvmInline
 import kotlin.math.abs
 import kotlin.math.max
 import kotlin.math.roundToInt
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
index a8c9b1e..d4daf51 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
@@ -52,6 +52,7 @@
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.util.fastMaxOfOrNull
+import kotlin.math.max
 import kotlin.math.roundToInt
 import kotlinx.coroutines.launch
 
@@ -386,7 +387,7 @@
 
         layout(layoutWidth, layoutHeight) {
             val sheetWidth = sheetPlaceables.fastMaxOfOrNull { it.width } ?: 0
-            val sheetOffsetX = Integer.max(0, (layoutWidth - sheetWidth) / 2)
+            val sheetOffsetX = max(0, (layoutWidth - sheetWidth) / 2)
 
             val snackbarWidth = snackbarPlaceables.fastMaxOfOrNull { it.width } ?: 0
             val snackbarHeight = snackbarPlaceables.fastMaxOfOrNull { it.height } ?: 0
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
index d915eb2..9065f0c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
@@ -47,6 +47,7 @@
 import androidx.compose.ui.text.input.TransformedText
 import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.unit.dp
+import kotlin.jvm.JvmInline
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
@@ -222,25 +223,29 @@
  * @param errorInvalidRangeInput a string for displaying an error message when in a range input mode
  *   and one of the input dates is out of order (i.e. the user inputs a start date that is after the
  *   end date, or an end date that is before the start date)
- * @param currentStartDateMillis the currently selected start date in milliseconds. Only checked
- *   against when the [InputIdentifier] is [InputIdentifier.EndDateInput].
- * @param currentEndDateMillis the currently selected end date in milliseconds. Only checked against
- *   when the [InputIdentifier] is [InputIdentifier.StartDateInput].
  */
 @OptIn(ExperimentalMaterial3Api::class)
 @Stable
-internal class DateInputValidator(
-    private val yearRange: IntRange,
-    private val selectableDates: SelectableDates,
-    private val dateInputFormat: DateInputFormat,
-    private val dateFormatter: DatePickerFormatter,
-    private val errorDatePattern: String,
-    private val errorDateOutOfYearRange: String,
-    private val errorInvalidNotAllowed: String,
-    private val errorInvalidRangeInput: String,
-    internal var currentStartDateMillis: Long? = null,
-    internal var currentEndDateMillis: Long? = null,
+internal expect class DateInputValidator(
+    yearRange: IntRange,
+    selectableDates: SelectableDates,
+    dateInputFormat: DateInputFormat,
+    dateFormatter: DatePickerFormatter,
+    errorDatePattern: String,
+    errorDateOutOfYearRange: String,
+    errorInvalidNotAllowed: String,
+    errorInvalidRangeInput: String,
 ) {
+    /**
+     * the currently selected start date in milliseconds. Only checked against when the
+     * [InputIdentifier] is [InputIdentifier.EndDateInput].
+     */
+    var currentStartDateMillis: Long?
+    /**
+     * the currently selected end date in milliseconds. Only checked against when the
+     * [InputIdentifier] is [InputIdentifier.StartDateInput].
+     */
+    var currentEndDateMillis: Long?
 
     /**
      * Validates a [CalendarDate] input and returns an error string in case an issue with the given
@@ -255,45 +260,7 @@
         dateToValidate: CalendarDate?,
         inputIdentifier: InputIdentifier,
         locale: CalendarLocale
-    ): String {
-        if (dateToValidate == null) {
-            return errorDatePattern.format(dateInputFormat.patternWithDelimiters.uppercase())
-        }
-        // Check that the date is within the valid range of years.
-        if (!yearRange.contains(dateToValidate.year)) {
-            return errorDateOutOfYearRange.format(
-                yearRange.first.toLocalString(),
-                yearRange.last.toLocalString()
-            )
-        }
-        // Check that the provided SelectableDates allows this date to be selected.
-        with(selectableDates) {
-            if (
-                !isSelectableYear(dateToValidate.year) ||
-                    !isSelectableDate(dateToValidate.utcTimeMillis)
-            ) {
-                return errorInvalidNotAllowed.format(
-                    dateFormatter.formatDate(
-                        dateMillis = dateToValidate.utcTimeMillis,
-                        locale = locale
-                    )
-                )
-            }
-        }
-
-        // Additional validation when the InputIdentifier is for start of end dates in a range input
-        if (
-            (inputIdentifier == InputIdentifier.StartDateInput &&
-                dateToValidate.utcTimeMillis >= (currentEndDateMillis ?: Long.MAX_VALUE)) ||
-                (inputIdentifier == InputIdentifier.EndDateInput &&
-                    dateToValidate.utcTimeMillis < (currentStartDateMillis ?: Long.MIN_VALUE))
-        ) {
-            // The input start date is after the end date, or the end date is before the start date.
-            return errorInvalidRangeInput
-        }
-
-        return ""
-    }
+    ): String
 }
 
 /**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
index bf91ec5..806bf7e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
@@ -58,16 +58,11 @@
 import androidx.compose.foundation.lazy.grid.rememberLazyGridState
 import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
-import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
-import androidx.compose.material.icons.filled.ArrowDropDown
-import androidx.compose.material.icons.filled.DateRange
-import androidx.compose.material.icons.filled.Edit
 import androidx.compose.material3.OutlinedTextFieldDefaults.defaultOutlinedTextFieldColors
 import androidx.compose.material3.internal.CalendarModel
 import androidx.compose.material3.internal.CalendarMonth
 import androidx.compose.material3.internal.DaysInWeek
+import androidx.compose.material3.internal.Icons
 import androidx.compose.material3.internal.MillisecondsIn24Hours
 import androidx.compose.material3.internal.ProvideContentColorTextStyle
 import androidx.compose.material3.internal.Strings
@@ -124,6 +119,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastForEach
+import kotlin.jvm.JvmInline
 import kotlin.math.max
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
@@ -672,11 +668,14 @@
                 }
 
         val headlineDescription =
-            when (displayMode) {
-                DisplayMode.Picker -> getString(Strings.DatePickerHeadlineDescription)
-                DisplayMode.Input -> getString(Strings.DateInputHeadlineDescription)
-                else -> ""
-            }.format(verboseDateDescription)
+            formatHeadlineDescription(
+                when (displayMode) {
+                    DisplayMode.Picker -> getString(Strings.DatePickerHeadlineDescription)
+                    DisplayMode.Input -> getString(Strings.DateInputHeadlineDescription)
+                    else -> ""
+                },
+                verboseDateDescription
+            )
 
         Text(
             text = headlineText,
@@ -748,6 +747,11 @@
     const val YearMonthWeekdayDaySkeleton: String = "yMMMMEEEEd"
 }
 
+internal expect inline fun formatHeadlineDescription(
+    template: String,
+    verboseDateDescription: String
+): String
+
 /**
  * Represents the colors used by the date picker.
  *
@@ -2051,8 +2055,10 @@
                     onClick = { onYearSelected(selectedYear) },
                     enabled = selectableDates.isSelectableYear(selectedYear),
                     description =
-                        getString(Strings.DatePickerNavigateToYearDescription)
-                            .format(localizedYear),
+                        formatDatePickerNavigateToYearString(
+                            getString(Strings.DatePickerNavigateToYearDescription),
+                            localizedYear
+                        ),
                     colors = colors
                 ) {
                     Text(
@@ -2067,6 +2073,11 @@
     }
 }
 
+internal expect inline fun formatDatePickerNavigateToYearString(
+    template: String,
+    localizedYear: String
+): String
+
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 private fun Year(
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt
index a31e5e7..db9690e90 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/InteractiveComponentSize.kt
@@ -75,11 +75,13 @@
                 "interactions if the element would measure smaller"
     }
 
-    override fun hashCode(): Int = System.identityHashCode(this)
+    override fun hashCode(): Int = identityHashCode(this)
 
     override fun equals(other: Any?) = (other === this)
 }
 
+internal expect inline fun identityHashCode(value: Any): Int
+
 internal class MinimumInteractiveModifierNode :
     Modifier.Node(), CompositionLocalConsumerModifierNode, LayoutModifierNode {
     override fun MeasureScope.measure(
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
index a628d71..717f48b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
@@ -53,6 +53,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.offset
 import androidx.compose.ui.unit.sp
+import kotlin.jvm.JvmInline
 import kotlin.math.max
 
 /**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationItem.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationItem.kt
index 300ee65..3c5d10d 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationItem.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationItem.kt
@@ -70,6 +70,7 @@
 import androidx.compose.ui.util.fastFirst
 import androidx.compose.ui.util.fastFirstOrNull
 import androidx.compose.ui.util.lerp
+import kotlin.jvm.JvmInline
 import kotlin.math.max
 import kotlin.math.roundToInt
 
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ProgressIndicator.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ProgressIndicator.kt
index b6778d9..5f79700 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ProgressIndicator.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ProgressIndicator.kt
@@ -538,8 +538,7 @@
             } else {
                 gapSize + strokeWidth
             }
-        val gapSizeSweep =
-            (adjustedGapSize.value / (Math.PI * size.width.toDp().value).toFloat()) * 360f
+        val gapSizeSweep = (adjustedGapSize.value / (PI * size.width.toDp().value).toFloat()) * 360f
 
         drawCircularIndicator(
             startAngle + sweep + min(sweep, gapSizeSweep),
@@ -659,8 +658,7 @@
             } else {
                 gapSize + strokeWidth
             }
-        val gapSizeSweep =
-            (adjustedGapSize.value / (Math.PI * size.width.toDp().value).toFloat()) * 360f
+        val gapSizeSweep = (adjustedGapSize.value / (PI * size.width.toDp().value).toFloat()) * 360f
 
         rotate(globalRotation.value + additionalRotation.value) {
             drawCircularIndicator(
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
index 554a36c..6f26f15 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
@@ -43,8 +43,7 @@
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.foundation.shape.CornerBasedShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Check
+import androidx.compose.material3.internal.Icons
 import androidx.compose.material3.tokens.MotionTokens
 import androidx.compose.material3.tokens.OutlinedSegmentedButtonTokens
 import androidx.compose.material3.tokens.OutlinedSegmentedButtonTokens.DisabledLabelTextColor
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
index a97f7c0..87200fd 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
@@ -54,6 +54,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
+import kotlin.jvm.JvmName
 import kotlinx.coroutines.CancellationException
 
 /**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ShortNavigationBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ShortNavigationBar.kt
index e0fd8eb..553c9ad 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ShortNavigationBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ShortNavigationBar.kt
@@ -44,6 +44,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
+import kotlin.jvm.JvmInline
 import kotlin.math.roundToInt
 
 /**
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 d373eb5..d7cb737 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
@@ -100,6 +100,7 @@
 import androidx.compose.ui.util.packFloats
 import androidx.compose.ui.util.unpackFloat1
 import androidx.compose.ui.util.unpackFloat2
+import kotlin.jvm.JvmInline
 import kotlin.math.abs
 import kotlin.math.floor
 import kotlin.math.max
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Snackbar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Snackbar.kt
index 06b06b7..2142d27 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Snackbar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Snackbar.kt
@@ -23,8 +23,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.paddingFromBaseline
 import androidx.compose.foundation.layout.widthIn
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Close
+import androidx.compose.material3.internal.Icons
 import androidx.compose.material3.internal.Strings
 import androidx.compose.material3.internal.getString
 import androidx.compose.material3.tokens.SnackbarTokens
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
index aa0c01f..bde0b7e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
@@ -174,6 +174,7 @@
 import androidx.compose.ui.util.fastForEachIndexed
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.zIndex
+import kotlin.jvm.JvmInline
 import kotlin.math.PI
 import kotlin.math.atan2
 import kotlin.math.cos
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/WideNavigationRail.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/WideNavigationRail.kt
index 6ea365c..54f7e17 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/WideNavigationRail.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/WideNavigationRail.kt
@@ -60,6 +60,8 @@
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastMap
 import androidx.compose.ui.util.fastSumBy
+import kotlin.jvm.JvmInline
+import kotlin.math.min
 
 /**
  * Material design wide navigation rail.
@@ -240,7 +242,7 @@
                                             .constrain(
                                                 Constraints.fitPrioritizingWidth(
                                                     minWidth =
-                                                        Math.min(
+                                                        min(
                                                             ItemMinWidth.roundToPx(),
                                                             itemMaxWidthConstraint
                                                         ),
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
index 46534c4..67883b1 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
@@ -53,6 +53,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import kotlin.jvm.JvmInline
 import kotlin.math.roundToInt
 
 /**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.kt
index 0a4a8fc..ecacf8b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.kt
@@ -701,12 +701,7 @@
     val AnimationSpec = SpringSpec<Float>()
 }
 
-private class AnchoredDragFinishedSignal : CancellationException() {
-    override fun fillInStackTrace(): Throwable {
-        stackTrace = emptyArray()
-        return this
-    }
-}
+internal expect class AnchoredDragFinishedSignal() : CancellationException
 
 private suspend fun <I> restartable(inputs: () -> I, block: suspend (I) -> Unit) {
     try {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/CalendarModel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/CalendarModel.kt
index 3d8c3c2..7ece81f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/CalendarModel.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/CalendarModel.kt
@@ -297,22 +297,7 @@
  * - dd.MM.yyyy
  * - MM/dd/yyyy
  */
-internal fun datePatternAsInputFormat(localeFormat: String): DateInputFormat {
-    val patternWithDelimiters =
-        localeFormat
-            .replace(Regex("[^dMy/\\-.]"), "")
-            .replace(Regex("d{1,2}"), "dd")
-            .replace(Regex("M{1,2}"), "MM")
-            .replace(Regex("y{1,4}"), "yyyy")
-            .replace("My", "M/y") // Edge case for the Kako locale
-            .removeSuffix(".") // Removes a dot suffix that appears in some formats
-
-    val delimiterRegex = Regex("[/\\-.]")
-    val delimiterMatchResult = delimiterRegex.find(patternWithDelimiters)
-    val delimiterIndex = delimiterMatchResult!!.groups[0]!!.range.first
-    val delimiter = patternWithDelimiters.substring(delimiterIndex, delimiterIndex + 1)
-    return DateInputFormat(patternWithDelimiters = patternWithDelimiters, delimiter = delimiter[0])
-}
+internal expect fun datePatternAsInputFormat(localeFormat: String): DateInputFormat
 
 internal const val DaysInWeek: Int = 7
 internal const val MillisecondsIn24Hours = 86400000L
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Icons.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Icons.kt
new file mode 100644
index 0000000..e2334af
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Icons.kt
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2024 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.internal
+
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.PathFillType
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.StrokeJoin
+import androidx.compose.ui.graphics.vector.DefaultFillType
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.PathBuilder
+import androidx.compose.ui.graphics.vector.path
+import androidx.compose.ui.unit.dp
+
+internal object Icons {
+    internal object AutoMirrored {
+        internal object Filled {
+            internal val KeyboardArrowLeft: ImageVector
+                get() {
+                    if (_keyboardArrowLeft != null) {
+                        return _keyboardArrowLeft!!
+                    }
+                    _keyboardArrowLeft =
+                        materialIcon(
+                            name = "AutoMirrored.Filled.KeyboardArrowLeft",
+                            autoMirror = true
+                        ) {
+                            materialPath {
+                                moveTo(15.41f, 16.59f)
+                                lineTo(10.83f, 12.0f)
+                                lineToRelative(4.58f, -4.59f)
+                                lineTo(14.0f, 6.0f)
+                                lineToRelative(-6.0f, 6.0f)
+                                lineToRelative(6.0f, 6.0f)
+                                lineToRelative(1.41f, -1.41f)
+                                close()
+                            }
+                        }
+                    return _keyboardArrowLeft!!
+                }
+
+            private var _keyboardArrowLeft: ImageVector? = null
+
+            internal val KeyboardArrowRight: ImageVector
+                get() {
+                    if (_keyboardArrowRight != null) {
+                        return _keyboardArrowRight!!
+                    }
+                    _keyboardArrowRight =
+                        materialIcon(
+                            name = "AutoMirrored.Filled.KeyboardArrowRight",
+                            autoMirror = true
+                        ) {
+                            materialPath {
+                                moveTo(8.59f, 16.59f)
+                                lineTo(13.17f, 12.0f)
+                                lineTo(8.59f, 7.41f)
+                                lineTo(10.0f, 6.0f)
+                                lineToRelative(6.0f, 6.0f)
+                                lineToRelative(-6.0f, 6.0f)
+                                lineToRelative(-1.41f, -1.41f)
+                                close()
+                            }
+                        }
+                    return _keyboardArrowRight!!
+                }
+
+            private var _keyboardArrowRight: ImageVector? = null
+        }
+    }
+
+    internal object Filled {
+        internal val Close: ImageVector
+            get() {
+                if (_close != null) {
+                    return _close!!
+                }
+                _close =
+                    materialIcon(name = "Filled.Close") {
+                        materialPath {
+                            moveTo(19.0f, 6.41f)
+                            lineTo(17.59f, 5.0f)
+                            lineTo(12.0f, 10.59f)
+                            lineTo(6.41f, 5.0f)
+                            lineTo(5.0f, 6.41f)
+                            lineTo(10.59f, 12.0f)
+                            lineTo(5.0f, 17.59f)
+                            lineTo(6.41f, 19.0f)
+                            lineTo(12.0f, 13.41f)
+                            lineTo(17.59f, 19.0f)
+                            lineTo(19.0f, 17.59f)
+                            lineTo(13.41f, 12.0f)
+                            close()
+                        }
+                    }
+                return _close!!
+            }
+
+        private var _close: ImageVector? = null
+
+        internal val Check: ImageVector
+            get() {
+                if (_check != null) {
+                    return _check!!
+                }
+                _check =
+                    materialIcon(name = "Filled.Check") {
+                        materialPath {
+                            moveTo(9.0f, 16.17f)
+                            lineTo(4.83f, 12.0f)
+                            lineToRelative(-1.42f, 1.41f)
+                            lineTo(9.0f, 19.0f)
+                            lineTo(21.0f, 7.0f)
+                            lineToRelative(-1.41f, -1.41f)
+                            close()
+                        }
+                    }
+                return _check!!
+            }
+
+        private var _check: ImageVector? = null
+
+        internal val Edit: ImageVector
+            get() {
+                if (_edit != null) {
+                    return _edit!!
+                }
+                _edit =
+                    materialIcon(name = "Filled.Edit") {
+                        materialPath {
+                            moveTo(3.0f, 17.25f)
+                            verticalLineTo(21.0f)
+                            horizontalLineToRelative(3.75f)
+                            lineTo(17.81f, 9.94f)
+                            lineToRelative(-3.75f, -3.75f)
+                            lineTo(3.0f, 17.25f)
+                            close()
+                            moveTo(20.71f, 7.04f)
+                            curveToRelative(0.39f, -0.39f, 0.39f, -1.02f, 0.0f, -1.41f)
+                            lineToRelative(-2.34f, -2.34f)
+                            curveToRelative(-0.39f, -0.39f, -1.02f, -0.39f, -1.41f, 0.0f)
+                            lineToRelative(-1.83f, 1.83f)
+                            lineToRelative(3.75f, 3.75f)
+                            lineToRelative(1.83f, -1.83f)
+                            close()
+                        }
+                    }
+                return _edit!!
+            }
+
+        private var _edit: ImageVector? = null
+
+        internal val DateRange: ImageVector
+            get() {
+                if (_dateRange != null) {
+                    return _dateRange!!
+                }
+                _dateRange =
+                    materialIcon(name = "Filled.DateRange") {
+                        materialPath {
+                            moveTo(9.0f, 11.0f)
+                            lineTo(7.0f, 11.0f)
+                            verticalLineToRelative(2.0f)
+                            horizontalLineToRelative(2.0f)
+                            verticalLineToRelative(-2.0f)
+                            close()
+                            moveTo(13.0f, 11.0f)
+                            horizontalLineToRelative(-2.0f)
+                            verticalLineToRelative(2.0f)
+                            horizontalLineToRelative(2.0f)
+                            verticalLineToRelative(-2.0f)
+                            close()
+                            moveTo(17.0f, 11.0f)
+                            horizontalLineToRelative(-2.0f)
+                            verticalLineToRelative(2.0f)
+                            horizontalLineToRelative(2.0f)
+                            verticalLineToRelative(-2.0f)
+                            close()
+                            moveTo(19.0f, 4.0f)
+                            horizontalLineToRelative(-1.0f)
+                            lineTo(18.0f, 2.0f)
+                            horizontalLineToRelative(-2.0f)
+                            verticalLineToRelative(2.0f)
+                            lineTo(8.0f, 4.0f)
+                            lineTo(8.0f, 2.0f)
+                            lineTo(6.0f, 2.0f)
+                            verticalLineToRelative(2.0f)
+                            lineTo(5.0f, 4.0f)
+                            curveToRelative(-1.11f, 0.0f, -1.99f, 0.9f, -1.99f, 2.0f)
+                            lineTo(3.0f, 20.0f)
+                            curveToRelative(0.0f, 1.1f, 0.89f, 2.0f, 2.0f, 2.0f)
+                            horizontalLineToRelative(14.0f)
+                            curveToRelative(1.1f, 0.0f, 2.0f, -0.9f, 2.0f, -2.0f)
+                            lineTo(21.0f, 6.0f)
+                            curveToRelative(0.0f, -1.1f, -0.9f, -2.0f, -2.0f, -2.0f)
+                            close()
+                            moveTo(19.0f, 20.0f)
+                            lineTo(5.0f, 20.0f)
+                            lineTo(5.0f, 9.0f)
+                            horizontalLineToRelative(14.0f)
+                            verticalLineToRelative(11.0f)
+                            close()
+                        }
+                    }
+                return _dateRange!!
+            }
+
+        private var _dateRange: ImageVector? = null
+
+        internal val ArrowDropDown: ImageVector
+            get() {
+                if (_arrowDropDown != null) {
+                    return _arrowDropDown!!
+                }
+                _arrowDropDown =
+                    materialIcon(name = "Filled.ArrowDropDown") {
+                        materialPath {
+                            moveTo(7.0f, 10.0f)
+                            lineToRelative(5.0f, 5.0f)
+                            lineToRelative(5.0f, -5.0f)
+                            close()
+                        }
+                    }
+                return _arrowDropDown!!
+            }
+
+        private var _arrowDropDown: ImageVector? = null
+    }
+}
+
+private inline fun materialIcon(
+    name: String,
+    block: ImageVector.Builder.() -> ImageVector.Builder
+): ImageVector =
+    ImageVector.Builder(
+            name = name,
+            defaultWidth = MaterialIconDimension.dp,
+            defaultHeight = MaterialIconDimension.dp,
+            viewportWidth = MaterialIconDimension,
+            viewportHeight = MaterialIconDimension
+        )
+        .block()
+        .build()
+
+private inline fun materialIcon(
+    name: String,
+    autoMirror: Boolean = false,
+    block: ImageVector.Builder.() -> ImageVector.Builder
+): ImageVector =
+    ImageVector.Builder(
+            name = name,
+            defaultWidth = MaterialIconDimension.dp,
+            defaultHeight = MaterialIconDimension.dp,
+            viewportWidth = MaterialIconDimension,
+            viewportHeight = MaterialIconDimension,
+            autoMirror = autoMirror
+        )
+        .block()
+        .build()
+
+private inline fun ImageVector.Builder.materialPath(
+    fillAlpha: Float = 1f,
+    strokeAlpha: Float = 1f,
+    pathFillType: PathFillType = DefaultFillType,
+    pathBuilder: PathBuilder.() -> Unit
+) =
+    path(
+        fill = SolidColor(Color.Black),
+        fillAlpha = fillAlpha,
+        stroke = null,
+        strokeAlpha = strokeAlpha,
+        strokeLineWidth = 1f,
+        strokeLineCap = StrokeCap.Butt,
+        strokeLineJoin = StrokeJoin.Bevel,
+        strokeLineMiter = 1f,
+        pathFillType = pathFillType,
+        pathBuilder = pathBuilder
+    )
+
+// All Material icons (currently) are 24dp by 24dp, with a viewport size of 24 by 24.
+private const val MaterialIconDimension = 24f
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Strings.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Strings.kt
index 27ac520..d0e4575 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Strings.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/Strings.kt
@@ -19,6 +19,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ReadOnlyComposable
+import kotlin.jvm.JvmInline
 
 @Immutable
 @JvmInline
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/AlertDialog.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/AlertDialog.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/AlertDialog.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/AlertDialog.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/CalendarLocale.commonStubs.kt
similarity index 72%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/CalendarLocale.commonStubs.kt
index 02ed679..4639efb 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/CalendarLocale.commonStubs.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 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.
@@ -19,8 +19,20 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.ReadOnlyComposable
 
-/** Returns the default [CalendarLocale]. */
+@ExperimentalMaterial3Api
+actual class CalendarLocale {
+    init {
+        implementedInJetBrainsFork()
+    }
+}
+
 @Composable
 @ReadOnlyComposable
 @OptIn(ExperimentalMaterial3Api::class)
 internal actual fun defaultLocale(): CalendarLocale = implementedInJetBrainsFork()
+
+internal actual fun Int.toLocalString(
+    minDigits: Int,
+    maxDigits: Int,
+    isGroupingUsed: Boolean
+): String = implementedInJetBrainsFork()
diff --git a/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/DateInput.commonStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/DateInput.commonStubs.kt
new file mode 100644
index 0000000..83856230
--- /dev/null
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/DateInput.commonStubs.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 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
+
+import androidx.compose.material3.internal.CalendarDate
+import androidx.compose.material3.internal.DateInputFormat
+import androidx.compose.runtime.Stable
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Stable
+internal actual class DateInputValidator
+actual constructor(
+    yearRange: IntRange,
+    selectableDates: SelectableDates,
+    dateInputFormat: DateInputFormat,
+    dateFormatter: DatePickerFormatter,
+    errorDatePattern: String,
+    errorDateOutOfYearRange: String,
+    errorInvalidNotAllowed: String,
+    errorInvalidRangeInput: String
+) {
+    actual var currentStartDateMillis: Long? = implementedInJetBrainsFork()
+    actual var currentEndDateMillis: Long? = implementedInJetBrainsFork()
+
+    actual fun validate(
+        dateToValidate: CalendarDate?,
+        inputIdentifier: InputIdentifier,
+        locale: CalendarLocale
+    ): String = implementedInJetBrainsFork()
+}
diff --git a/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/DatePicker.commonStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/DatePicker.commonStubs.kt
new file mode 100644
index 0000000..f692c5e1
--- /dev/null
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/DatePicker.commonStubs.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 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
+
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun formatDatePickerNavigateToYearString(
+    template: String,
+    localizedYear: String
+): String = implementedInJetBrainsFork()
+
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun formatHeadlineDescription(
+    template: String,
+    verboseDateDescription: String
+): String = implementedInJetBrainsFork()
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/InteractiveComponentSize.commonStubs.kt
similarity index 63%
copy from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt
copy to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/InteractiveComponentSize.commonStubs.kt
index 02ed679..66e32fd 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/CalendarLocale.jvmStubs.kt
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/InteractiveComponentSize.commonStubs.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2024 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.
@@ -16,11 +16,5 @@
 
 package androidx.compose.material3
 
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.ReadOnlyComposable
-
-/** Returns the default [CalendarLocale]. */
-@Composable
-@ReadOnlyComposable
-@OptIn(ExperimentalMaterial3Api::class)
-internal actual fun defaultLocale(): CalendarLocale = implementedInJetBrainsFork()
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun identityHashCode(value: Any): Int = implementedInJetBrainsFork()
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/ModalBottomSheet.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/ModalBottomSheet.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/ModalBottomSheet.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/ModalBottomSheet.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/NavigationDrawer.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/NavigationDrawer.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/NavigationDrawer.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/NavigationDrawer.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/NotImplemented.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/NotImplemented.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/NotImplemented.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/NotImplemented.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/SkikoMenu.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/SkikoMenu.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/SkikoMenu.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/SkikoMenu.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/TimeFormat.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/TimeFormat.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/TimeFormat.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/TimeFormat.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/TimePicker.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/TimePicker.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/TimePicker.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/TimePicker.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/Tooltip.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/Tooltip.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/Tooltip.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/Tooltip.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/AccessibilityServiceStateProvider.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/AccessibilityServiceStateProvider.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/AccessibilityServiceStateProvider.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/AccessibilityServiceStateProvider.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.commonStubs.kt
similarity index 62%
copy from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt
copy to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.commonStubs.kt
index ab14c60..8b75665 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/AnchoredDraggable.commonStubs.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2022 The Android Open Source Project
+ * Copyright 2024 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.
@@ -16,15 +16,12 @@
 
 package androidx.compose.material3.internal
 
-import androidx.compose.material3.CalendarLocale
 import androidx.compose.material3.implementedInJetBrainsFork
+import kotlinx.coroutines.CancellationException
 
-internal actual fun createCalendarModel(locale: CalendarLocale): CalendarModel =
-    implementedInJetBrainsFork()
-
-internal actual fun formatWithSkeleton(
-    utcTimeMillis: Long,
-    skeleton: String,
-    locale: CalendarLocale,
-    cache: MutableMap<String, Any>
-): String = implementedInJetBrainsFork()
+internal actual class AnchoredDragFinishedSignal actual constructor() :
+    CancellationException("Anchored drag finished") {
+    init {
+        implementedInJetBrainsFork()
+    }
+}
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/BasicTooltip.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/BasicTooltip.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/BasicTooltip.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/BasicTooltip.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.commonStubs.kt
similarity index 80%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.commonStubs.kt
index ab14c60..30bc924 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.commonStubs.kt
@@ -17,14 +17,20 @@
 package androidx.compose.material3.internal
 
 import androidx.compose.material3.CalendarLocale
+import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.implementedInJetBrainsFork
 
+@OptIn(ExperimentalMaterial3Api::class)
 internal actual fun createCalendarModel(locale: CalendarLocale): CalendarModel =
     implementedInJetBrainsFork()
 
+@OptIn(ExperimentalMaterial3Api::class)
 internal actual fun formatWithSkeleton(
     utcTimeMillis: Long,
     skeleton: String,
     locale: CalendarLocale,
     cache: MutableMap<String, Any>
 ): String = implementedInJetBrainsFork()
+
+internal actual fun datePatternAsInputFormat(localeFormat: String): DateInputFormat =
+    implementedInJetBrainsFork()
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/DefaultPlatformTextStyle.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/DefaultPlatformTextStyle.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/DefaultPlatformTextStyle.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/DefaultPlatformTextStyle.commonStubs.kt
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/InternalMutatorMutex.commonStubs.kt
similarity index 61%
copy from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt
copy to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/InternalMutatorMutex.commonStubs.kt
index ab14c60..0d47281 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/CalendarModel.jvmStubs.kt
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/InternalMutatorMutex.commonStubs.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2022 The Android Open Source Project
+ * Copyright 2024 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.
@@ -16,15 +16,16 @@
 
 package androidx.compose.material3.internal
 
-import androidx.compose.material3.CalendarLocale
 import androidx.compose.material3.implementedInJetBrainsFork
 
-internal actual fun createCalendarModel(locale: CalendarLocale): CalendarModel =
-    implementedInJetBrainsFork()
+internal actual class InternalAtomicReference<V> actual constructor(value: V) {
+    actual fun get(): V = implementedInJetBrainsFork()
 
-internal actual fun formatWithSkeleton(
-    utcTimeMillis: Long,
-    skeleton: String,
-    locale: CalendarLocale,
-    cache: MutableMap<String, Any>
-): String = implementedInJetBrainsFork()
+    actual fun set(value: V) {
+        implementedInJetBrainsFork()
+    }
+
+    actual fun getAndSet(value: V): V = implementedInJetBrainsFork()
+
+    actual fun compareAndSet(expect: V, newValue: V): Boolean = implementedInJetBrainsFork()
+}
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/Strings.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/Strings.commonStubs.kt
similarity index 98%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/Strings.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/Strings.commonStubs.kt
index d83be33..a2c5526 100644
--- a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/Strings.jvmStubs.kt
+++ b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/Strings.commonStubs.kt
@@ -20,6 +20,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.ReadOnlyComposable
+import kotlin.jvm.JvmInline
 
 @Composable
 @ReadOnlyComposable
diff --git a/compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/SystemBarsDefaultInsets.jvmStubs.kt b/compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/SystemBarsDefaultInsets.commonStubs.kt
similarity index 100%
rename from compose/material3/material3/src/jvmStubsMain/kotlin/androidx/compose/material3/internal/SystemBarsDefaultInsets.jvmStubs.kt
rename to compose/material3/material3/src/commonStubsMain/kotlin/androidx/compose/material3/internal/SystemBarsDefaultInsets.commonStubs.kt
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Bezier.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Bezier.kt
index dd5fd27..4bd040c 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Bezier.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Bezier.kt
@@ -36,8 +36,9 @@
 private const val Epsilon = 1e-7
 // We use a fairly high epsilon here because it's post double->float conversion
 // and because we use a fast approximation of cbrt(). The epsilon we use here is
-// the max error of fastCbrt() in the -1f..1f range.
-private const val FloatEpsilon = 8.3446500e-7f
+// slightly larger than the max error of fastCbrt() in the -1f..1f range
+// (8.3446500e-7f) but smaller than 1.0f.ulp * 10.
+private const val FloatEpsilon = 1e-6f
 
 /**
  * Evaluate the specified [segment] at position [t] and returns the X coordinate of the segment's
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/UtilsTest.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/UtilsTest.kt
index 8f63be1..b6f81c1a 100644
--- a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/UtilsTest.kt
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/UtilsTest.kt
@@ -245,6 +245,8 @@
     }
 
     // Tests for Move Motion Event Creation <---------------
+    // Note: For tests with history, I am only checking the history count, not each history's x/y.
+    // One pointer/finger
     @Test
     fun createMoveMotionEvents_sixEventsOnePointerNegativeMoveDeltaWithoutHistory() {
         val y = (ItemHeightPx / 2)
@@ -272,11 +274,11 @@
 
         assertThat(moves.size).isEqualTo(numberOfEvents)
 
-        for ((index, move) in moves.withIndex()) {
-            val expectedTime = initialTime + (index * DefaultPointerInputTimeDelta)
+        for ((moveIndex, move) in moves.withIndex()) {
+            val expectedTime = initialTime + (moveIndex * DefaultPointerInputTimeDelta)
             assertThat(move.eventTime).isEqualTo(expectedTime)
 
-            val expectedX = xMoveInitial - (abs(index * DefaultPointerInputMoveAmountPx))
+            val expectedX = xMoveInitial - (abs(moveIndex * DefaultPointerInputMoveAmountPx))
             assertThat(move.x).isEqualTo(expectedX)
 
             assertThat(move.y).isEqualTo(y)
@@ -309,11 +311,11 @@
 
         assertThat(moves.size).isEqualTo(numberOfEvents)
 
-        for ((index, move) in moves.withIndex()) {
-            val expectedTime = initialTime + (index * DefaultPointerInputTimeDelta)
+        for ((moveIndex, move) in moves.withIndex()) {
+            val expectedTime = initialTime + (moveIndex * DefaultPointerInputTimeDelta)
             assertThat(move.eventTime).isEqualTo(expectedTime)
 
-            val expectedX = xMoveInitial + (index * DefaultPointerInputMoveAmountPx)
+            val expectedX = xMoveInitial + (moveIndex * DefaultPointerInputMoveAmountPx)
             assertThat(move.x).isEqualTo(expectedX)
 
             assertThat(move.y).isEqualTo(y)
@@ -321,8 +323,6 @@
         }
     }
 
-    // TODO(jjw): Add multi-pointer tests (next CL).
-
     @Test
     fun createMoveMotionEvents_sixEventsOnePointerPositiveMoveDeltaWithHistory() {
         val y = (ItemHeightPx / 2)
@@ -400,6 +400,221 @@
         }
     }
 
+    // Multiple pointers/fingers
+    @Test
+    fun createMoveMotionEvents_sixEventsThreePointerNegativeMoveDeltaWithoutHistory() {
+        val y = (ItemHeightPx / 2)
+        val xMoveInitial = 0f
+        val initialTime = 100
+        val numberOfEvents = 6
+        val numberOfPointers = 3 // fingers
+        val enableFlingStyleHistory = false
+
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val view = View(context)
+
+        val initialPointers =
+            Array(numberOfPointers) { simpleIndex ->
+                BenchmarkSimplifiedPointerInputPointer(
+                    id = simpleIndex,
+                    x = xMoveInitial + (simpleIndex * DefaultPointerInputMoveAmountPx),
+                    y = y
+                )
+            }
+
+        val moves =
+            createMoveMotionEvents(
+                initialTime = initialTime,
+                initialPointers = initialPointers,
+                rootView = view,
+                numberOfMoveEvents = numberOfEvents,
+                enableFlingStyleHistory = enableFlingStyleHistory,
+                timeDelta = 100,
+                moveDelta = -DefaultPointerInputMoveAmountPx
+            )
+
+        assertThat(moves.size).isEqualTo(numberOfEvents)
+
+        for ((index, move) in moves.withIndex()) {
+            val expectedTime = initialTime + (index * DefaultPointerInputTimeDelta)
+            assertThat(move.eventTime).isEqualTo(expectedTime)
+            assertThat(move.historySize).isEqualTo(0)
+
+            for (pointerIndex in 0 until move.pointerCount) {
+                val pointerId: Int = move.getPointerId(pointerIndex)
+                val localPointerCoords = MotionEvent.PointerCoords()
+                move.getPointerCoords(pointerId, localPointerCoords)
+
+                val expectedX =
+                    (xMoveInitial - (abs(index * DefaultPointerInputMoveAmountPx))) +
+                        (pointerIndex * DefaultPointerInputMoveAmountPx)
+                assertThat(localPointerCoords.x).isEqualTo(expectedX)
+
+                assertThat(localPointerCoords.y).isEqualTo(y)
+            }
+        }
+    }
+
+    @Test
+    fun createMoveMotionEvents_sixEventsThreePointerPositiveMoveDeltaWithoutHistory() {
+        val y = (ItemHeightPx / 2)
+        val xMoveInitial = 0f
+        val initialTime = 100
+        val numberOfEvents = 6
+        val numberOfPointers = 3 // fingers
+        val enableFlingStyleHistory = false
+
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val view = View(context)
+
+        val initialPointers =
+            Array(numberOfPointers) { simpleIndex ->
+                BenchmarkSimplifiedPointerInputPointer(
+                    id = simpleIndex,
+                    x = xMoveInitial + (simpleIndex * DefaultPointerInputMoveAmountPx),
+                    y = y
+                )
+            }
+
+        val moves =
+            createMoveMotionEvents(
+                initialTime = initialTime,
+                initialPointers = initialPointers,
+                rootView = view,
+                numberOfMoveEvents = numberOfEvents,
+                enableFlingStyleHistory = enableFlingStyleHistory
+            )
+
+        assertThat(moves.size).isEqualTo(numberOfEvents)
+
+        for ((index, move) in moves.withIndex()) {
+            val expectedTime = initialTime + (index * DefaultPointerInputTimeDelta)
+            assertThat(move.eventTime).isEqualTo(expectedTime)
+            assertThat(move.historySize).isEqualTo(0)
+
+            for (pointerIndex in 0 until move.pointerCount) {
+                val pointerId: Int = move.getPointerId(pointerIndex)
+                val localPointerCoords = MotionEvent.PointerCoords()
+                move.getPointerCoords(pointerId, localPointerCoords)
+
+                val expectedX =
+                    (xMoveInitial + (index * DefaultPointerInputMoveAmountPx)) +
+                        (pointerIndex * DefaultPointerInputMoveAmountPx)
+                assertThat(localPointerCoords.x).isEqualTo(expectedX)
+
+                assertThat(localPointerCoords.y).isEqualTo(y)
+            }
+        }
+    }
+
+    @Test
+    fun createMoveMotionEvents_sixEventsThreePointerNegativeMoveDeltaWithHistory() {
+        val y = (ItemHeightPx / 2)
+        val xMoveInitial = 0f
+        val initialTime = 100
+        val numberOfEvents = 6
+        val numberOfPointers = 3 // fingers
+        val enableFlingStyleHistory = true
+
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val view = View(context)
+
+        val initialPointers =
+            Array(numberOfPointers) { simpleIndex ->
+                BenchmarkSimplifiedPointerInputPointer(
+                    id = simpleIndex,
+                    x = xMoveInitial + (simpleIndex * DefaultPointerInputMoveAmountPx),
+                    y = y
+                )
+            }
+
+        val moves =
+            createMoveMotionEvents(
+                initialTime = initialTime,
+                initialPointers = initialPointers,
+                rootView = view,
+                numberOfMoveEvents = numberOfEvents,
+                enableFlingStyleHistory = enableFlingStyleHistory,
+                timeDelta = 100,
+                moveDelta = -DefaultPointerInputMoveAmountPx
+            )
+
+        assertThat(moves.size).isEqualTo(numberOfEvents)
+
+        for ((moveIndex, move) in moves.withIndex()) {
+            val expectedTime = initialTime + (moveIndex * DefaultPointerInputTimeDelta)
+            assertThat(move.eventTime).isEqualTo(expectedTime)
+
+            assertThat(move.historySize)
+                .isEqualTo(numberOfHistoricalEventsBasedOnArrayLocation(moveIndex))
+
+            for (pointerIndex in 0 until move.pointerCount) {
+                val pointerId: Int = move.getPointerId(pointerIndex)
+                val localPointerCoords = MotionEvent.PointerCoords()
+                move.getPointerCoords(pointerId, localPointerCoords)
+
+                val expectedX =
+                    (xMoveInitial - (abs(moveIndex * DefaultPointerInputMoveAmountPx))) +
+                        (pointerIndex * DefaultPointerInputMoveAmountPx)
+                assertThat(localPointerCoords.x).isEqualTo(expectedX)
+                assertThat(localPointerCoords.y).isEqualTo(y)
+            }
+        }
+    }
+
+    @Test
+    fun createMoveMotionEvents_sixEventsThreePointerPositiveMoveDeltaWithHistory() {
+        val y = (ItemHeightPx / 2)
+        val xMoveInitial = 0f
+        val initialTime = 100
+        val numberOfEvents = 6
+        val numberOfPointers = 3 // fingers
+        val enableFlingStyleHistory = true
+
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val view = View(context)
+
+        val initialPointers =
+            Array(numberOfPointers) { simpleIndex ->
+                BenchmarkSimplifiedPointerInputPointer(
+                    id = simpleIndex,
+                    x = xMoveInitial + (simpleIndex * DefaultPointerInputMoveAmountPx),
+                    y = y
+                )
+            }
+
+        val moves =
+            createMoveMotionEvents(
+                initialTime = initialTime,
+                initialPointers = initialPointers,
+                rootView = view,
+                numberOfMoveEvents = numberOfEvents,
+                enableFlingStyleHistory = enableFlingStyleHistory
+            )
+
+        assertThat(moves.size).isEqualTo(numberOfEvents)
+
+        for ((moveIndex, move) in moves.withIndex()) {
+            val expectedTime = initialTime + (moveIndex * DefaultPointerInputTimeDelta)
+            assertThat(move.eventTime).isEqualTo(expectedTime)
+
+            assertThat(move.historySize)
+                .isEqualTo(numberOfHistoricalEventsBasedOnArrayLocation(moveIndex))
+
+            for (pointerIndex in 0 until move.pointerCount) {
+                val pointerId: Int = move.getPointerId(pointerIndex)
+                val localPointerCoords = MotionEvent.PointerCoords()
+                move.getPointerCoords(pointerId, localPointerCoords)
+
+                val expectedX =
+                    (xMoveInitial + (moveIndex * DefaultPointerInputMoveAmountPx)) +
+                        (pointerIndex * DefaultPointerInputMoveAmountPx)
+                assertThat(localPointerCoords.x).isEqualTo(expectedX)
+                assertThat(localPointerCoords.y).isEqualTo(y)
+            }
+        }
+    }
+
     @Test
     fun testNumberOfHistoricalEventsBasedOnArrayLocation() {
         var numberOfEvents = numberOfHistoricalEventsBasedOnArrayLocation(0)
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt
index da69e38..84502d7 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt
@@ -15,6 +15,7 @@
  */
 package androidx.compose.ui.window
 
+import android.view.KeyEvent
 import android.view.View
 import android.view.View.MEASURED_STATE_TOO_SMALL
 import android.view.ViewGroup
@@ -282,6 +283,36 @@
     }
 
     @Test
+    fun isDismissedOnEscapePress() {
+        var showPopup by mutableStateOf(true)
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                if (showPopup) {
+                    Popup(
+                        properties =
+                            PopupProperties(
+                                // Needs to be focusable to intercept key press
+                                focusable = true
+                            ),
+                        alignment = Alignment.Center,
+                        onDismissRequest = { showPopup = false }
+                    ) {
+                        Box(Modifier.size(50.dp).testTag(testTag))
+                    }
+                }
+            }
+        }
+
+        // Popup should be visible
+        rule.onNodeWithTag(testTag).assertIsDisplayed()
+
+        UiDevice.getInstance(getInstrumentation()).pressKeyCode(KeyEvent.KEYCODE_ESCAPE)
+
+        // Popup should not exist
+        rule.onNodeWithTag(testTag).assertDoesNotExist()
+    }
+
+    @Test
     fun isNotDismissedOnTapOutside_dismissOnClickOutsideFalse() {
         var showPopup by mutableStateOf(true)
         rule.setContent {
@@ -346,6 +377,37 @@
     }
 
     @Test
+    fun isNotDismissedOnEscapePress_dismissOnBackPressFalse() {
+        var showPopup by mutableStateOf(true)
+        rule.setContent {
+            Box(Modifier.fillMaxSize()) {
+                if (showPopup) {
+                    Popup(
+                        properties =
+                            PopupProperties(
+                                // Needs to be focusable to intercept key press
+                                focusable = true,
+                                dismissOnBackPress = false
+                            ),
+                        alignment = Alignment.Center,
+                        onDismissRequest = { showPopup = false }
+                    ) {
+                        Box(Modifier.size(50.dp).testTag(testTag))
+                    }
+                }
+            }
+        }
+
+        // Popup should be visible
+        rule.onNodeWithTag(testTag).assertIsDisplayed()
+
+        UiDevice.getInstance(getInstrumentation()).pressKeyCode(KeyEvent.KEYCODE_ESCAPE)
+
+        // Popup should still be visible
+        rule.onNodeWithTag(testTag).assertIsDisplayed()
+    }
+
+    @Test
     fun canFillScreenWidth_dependingOnProperty() {
         var box1Width = 0
         var box2Width = 0
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 2269723..35431d0 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
@@ -98,10 +98,10 @@
  * @property inheritSecurePolicy Whether [WindowManager.LayoutParams.FLAG_SECURE] should be set
  *   according to [SecureFlagPolicy.Inherit]. Other [SecureFlagPolicy] behaviors should be set via
  *   [flags] directly.
- * @property dismissOnBackPress Whether the popup can be dismissed by pressing the back button. If
- *   true, pressing the back button will call onDismissRequest. Note that the popup must be
- *   [focusable] in order to receive key events such as the back button. If the popup is not
- *   [focusable], then this property does nothing.
+ * @property dismissOnBackPress Whether the popup can be dismissed by pressing the back or escape
+ *   buttons. If true, pressing the back or escape buttons will call onDismissRequest. Note that the
+ *   popup must be [focusable] in order to receive key events such as the back button. If the popup
+ *   is not [focusable], then this property does nothing.
  * @property dismissOnClickOutside Whether the popup can be dismissed by clicking outside the
  *   popup's bounds. If true, clicking outside the popup will call onDismissRequest.
  * @property excludeFromSystemGesture A flag to check whether to set the
@@ -157,10 +157,10 @@
      *
      * @param focusable Whether the popup is focusable. When true, the popup will receive IME events
      *   and key presses, such as when the back button is pressed.
-     * @param dismissOnBackPress Whether the popup can be dismissed by pressing the back button. If
-     *   true, pressing the back button will call onDismissRequest. Note that [focusable] must be
-     *   set to true in order to receive key events such as the back button. If the popup is not
-     *   focusable, then this property does nothing.
+     * @param dismissOnBackPress Whether the popup can be dismissed by pressing the back or escape
+     *   buttons. If true, pressing the back or escape buttons will call onDismissRequest. Note that
+     *   [focusable] must be set to true in order to receive key events such as the back button. If
+     *   the popup is not focusable, then this property does nothing.
      * @param dismissOnClickOutside Whether the popup can be dismissed by clicking outside the
      *   popup's bounds. If true, clicking outside the popup will call onDismissRequest.
      * @param securePolicy Policy for setting [WindowManager.LayoutParams.FLAG_SECURE] on the
@@ -625,17 +625,14 @@
 
     /** Taken from PopupWindow */
     override fun dispatchKeyEvent(event: KeyEvent): Boolean {
-        if (event.keyCode == KeyEvent.KEYCODE_BACK && properties.dismissOnBackPress) {
-            if (keyDispatcherState == null) {
-                return super.dispatchKeyEvent(event)
-            }
+        if (!properties.dismissOnBackPress) return super.dispatchKeyEvent(event)
+        if (event.keyCode == KeyEvent.KEYCODE_BACK || event.keyCode == KeyEvent.KEYCODE_ESCAPE) {
+            val state = keyDispatcherState ?: return super.dispatchKeyEvent(event)
             if (event.action == KeyEvent.ACTION_DOWN && event.repeatCount == 0) {
-                val state = keyDispatcherState
-                state?.startTracking(event, this)
+                state.startTracking(event, this)
                 return true
             } else if (event.action == KeyEvent.ACTION_UP) {
-                val state = keyDispatcherState
-                if (state != null && state.isTracking(event) && !event.isCanceled) {
+                if (state.isTracking(event) && !event.isCanceled) {
                     onDismissRequest?.invoke()
                     return true
                 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt
index c7ad7a4..2e0794b 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt
@@ -29,10 +29,10 @@
  *
  * @property focusable Whether the popup is focusable. When true, the popup will receive IME events
  *   and key presses, such as when the back button is pressed.
- * @property dismissOnBackPress Whether the popup can be dismissed by pressing the back button on
- *   Android or escape key on desktop. If true, pressing the back button will call onDismissRequest.
- *   Note that [focusable] must be set to true in order to receive key events such as the back
- *   button - if the popup is not focusable then this property does nothing.
+ * @property dismissOnBackPress Whether the popup can be dismissed by pressing the back or escape
+ *   buttons on Android or the escape key on desktop. If true, pressing the back button will call
+ *   onDismissRequest. Note that [focusable] must be set to true in order to receive key events such
+ *   as the back button - if the popup is not focusable then this property does nothing.
  * @property dismissOnClickOutside Whether the popup can be dismissed by clicking outside the
  *   popup's bounds. If true, clicking outside the popup will call onDismissRequest.
  * @property clippingEnabled Whether to allow the popup window to extend beyond the bounds of the
diff --git a/constraintlayout/constraintlayout-compose/build.gradle b/constraintlayout/constraintlayout-compose/build.gradle
index 5b810b4..f6ed5a1 100644
--- a/constraintlayout/constraintlayout-compose/build.gradle
+++ b/constraintlayout/constraintlayout-compose/build.gradle
@@ -35,13 +35,13 @@
     sourceSets {
         commonMain {
             dependencies {
-                implementation(project(":compose:ui:ui"))
-                implementation(project(":compose:ui:ui-unit"))
-                implementation(project(":compose:ui:ui-util"))
-                implementation(project(":compose:foundation:foundation"))
-                implementation(project(":compose:foundation:foundation-layout"))
+                implementation("androidx.compose.ui:ui:1.7.0-beta05")
+                implementation("androidx.compose.ui:ui-unit:1.7.0-beta05")
+                implementation("androidx.compose.ui:ui-util:1.7.0-beta05")
+                implementation("androidx.compose.foundation:foundation:1.7.0-beta05")
+                implementation("androidx.compose.foundation:foundation-layout:1.7.0-beta05")
                 implementation(project(":constraintlayout:constraintlayout-core"))
-                implementation(project(":collection:collection"))
+                implementation("androidx.collection:collection:1.4.1")
             }
         }
 
diff --git a/libraryversions.toml b/libraryversions.toml
index ab0d5b3..843d843 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -12,7 +12,7 @@
 BLUETOOTH = "1.0.0-alpha02"
 BROWSER = "1.9.0-alpha01"
 BUILDSRC_TESTS = "1.0.0-alpha01"
-CAMERA = "1.4.0-beta03"
+CAMERA = "1.4.0-rc01"
 CAMERA_PIPE = "1.0.0-alpha01"
 CAMERA_TESTING = "1.0.0-alpha01"
 CAMERA_VIEWFINDER = "1.4.0-alpha08"
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
index 37556ae..55b194c5e 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
@@ -779,7 +779,7 @@
 
 private fun nullableIntArgument(name: String, hasDefaultValue: Boolean = false) =
     navArgument(name) {
-        type = NullableIntType
+        type = IntNullableType
         nullable = true
         unknownDefaultValuePresent = hasDefaultValue
     }
@@ -790,31 +790,3 @@
         nullable = true
         unknownDefaultValuePresent = hasDefaultValue
     }
-
-private val NullableIntType: NavType<Int?> =
-    object : NavType<Int?>(true) {
-        override val name: String
-            get() = "nullable_integer"
-
-        override fun put(bundle: Bundle, key: String, value: Int?) {
-            value?.let { bundle.putInt(key, value) }
-        }
-
-        @Suppress("DEPRECATION")
-        override fun get(bundle: Bundle, key: String): Int? {
-            val value = bundle[key]
-            return value?.let { it as Int }
-        }
-
-        override fun parseValue(value: String): Int? {
-            return if (value == "null") {
-                null
-            } else if (value.startsWith("0x")) {
-                value.substring(2).toInt(16)
-            } else {
-                value.toInt()
-            }
-        }
-
-        override fun serializeAsValue(value: Int?): String = value?.toString() ?: "null"
-    }
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/NavTypeConverter.kt b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/NavTypeConverter.kt
index 690f73a..3a7cb68 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/serialization/NavTypeConverter.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/serialization/NavTypeConverter.kt
@@ -28,6 +28,7 @@
 /** Marker for Native Kotlin types with either full or partial built-in NavType support */
 private enum class InternalType {
     INT,
+    INT_NULLABLE,
     BOOL,
     FLOAT,
     LONG,
@@ -53,6 +54,7 @@
     val type =
         when (this.toInternalType()) {
             InternalType.INT -> NavType.IntType
+            InternalType.INT_NULLABLE -> IntNullableType
             InternalType.BOOL -> NavType.BoolType
             InternalType.FLOAT -> NavType.FloatType
             InternalType.LONG -> NavType.LongType
@@ -90,7 +92,8 @@
 private fun SerialDescriptor.toInternalType(): InternalType {
     val serialName = serialName.replace("?", "")
     return when {
-        serialName == "kotlin.Int" -> InternalType.INT
+        serialName == "kotlin.Int" ->
+            if (isNullable) InternalType.INT_NULLABLE else InternalType.INT
         serialName == "kotlin.Boolean" -> InternalType.BOOL
         serialName == "kotlin.Float" -> InternalType.FLOAT
         serialName == "kotlin.Long" -> InternalType.LONG
@@ -134,3 +137,33 @@
 
     override fun parseValue(value: String): String = "null"
 }
+
+internal object IntNullableType : NavType<Int?>(true) {
+    override val name: String
+        get() = "integer_nullable"
+
+    override fun put(bundle: Bundle, key: String, value: Int?) {
+        // store null as serializable inside bundle, so that decoder will use the null
+        // instead of default value
+        if (value == null) bundle.putSerializable(key, null) else bundle.putInt(key, value)
+    }
+
+    @Suppress("DEPRECATION")
+    override fun get(bundle: Bundle, key: String): Int? {
+        return bundle[key] as? Int
+    }
+
+    override fun parseValue(value: String): Int? {
+        return if (value == "null") {
+            null
+        } else if (value.startsWith("0x")) {
+            value.substring(2).toInt(16)
+        } else {
+            value.toInt()
+        }
+    }
+
+    override fun serializeAsValue(value: Int?): String {
+        return value?.toString() ?: "null"
+    }
+}
diff --git a/navigation/navigation-common/src/test/java/androidx/navigation/serialization/NavArgumentGeneratorTest.kt b/navigation/navigation-common/src/test/java/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
index 4d1190c..45f410e 100644
--- a/navigation/navigation-common/src/test/java/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
+++ b/navigation/navigation-common/src/test/java/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
@@ -53,14 +53,17 @@
     }
 
     @Test
-    fun convertToIntNullableIllegal() {
+    fun convertToIntNullable() {
         @Serializable class TestClass(val arg: Int?)
 
-        val exception =
-            assertFailsWith<IllegalArgumentException> {
-                serializer<TestClass>().generateNavArguments()
+        val converted = serializer<TestClass>().generateNavArguments()
+        val expected =
+            navArgument("arg") {
+                type = IntNullableType
+                nullable = true
             }
-        assertThat(exception.message).isEqualTo("integer does not allow nullable values")
+        assertThat(converted).containsExactlyInOrder(expected)
+        assertThat(converted[0].argument.isDefaultValueUnknown).isFalse()
     }
 
     @Test
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 bb37c66..029fe40 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
@@ -30,6 +30,7 @@
 import androidx.lifecycle.ViewModelStore
 import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.navigation.NavDestination.Companion.createRoute
+import androidx.navigation.NavDestination.Companion.hasRoute
 import androidx.navigation.serialization.generateHashCode
 import androidx.navigation.test.R
 import androidx.test.annotation.UiThreadTest
@@ -1153,6 +1154,37 @@
 
     @UiThreadTest
     @Test
+    fun testNavigateWithObjectNullableInt() {
+        @Serializable class TestClass(val arg: Int? = 10)
+        val navController = createNavController()
+        navController.graph =
+            navController.createGraph(startDestination = "start") {
+                test("start")
+                test<TestClass>()
+            }
+        assertThat(navController.currentDestination?.route).isEqualTo("start")
+
+        // passed in arg
+        navController.navigate(TestClass(15))
+        assertThat(navController.currentDestination?.hasRoute(TestClass::class)).isTrue()
+        assertThat(navController.currentBackStackEntry?.toRoute<TestClass>()?.arg).isEqualTo(15)
+        assertThat(navController.currentBackStack.value.size).isEqualTo(3)
+
+        // passed in null
+        navController.navigate(TestClass(null))
+        assertThat(navController.currentDestination?.hasRoute(TestClass::class)).isTrue()
+        assertThat(navController.currentBackStackEntry?.toRoute<TestClass>()?.arg).isNull()
+        assertThat(navController.currentBackStack.value.size).isEqualTo(4)
+
+        // use default
+        navController.navigate(TestClass())
+        assertThat(navController.currentDestination?.hasRoute(TestClass::class)).isTrue()
+        assertThat(navController.currentBackStackEntry?.toRoute<TestClass>()?.arg).isEqualTo(10)
+        assertThat(navController.currentBackStack.value.size).isEqualTo(5)
+    }
+
+    @UiThreadTest
+    @Test
     fun testNavigateWithPopUpToFurthestRoute() {
         val navController = createNavController()
         navController.graph = nav_singleArg_graph