Merge "Remove empty AndroidManifest.xml files" into androidx-main
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
index b1fcd9c..f3cb73c 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
@@ -209,12 +209,12 @@
                 )
                 .bindOptionalOutput(
                     "call",
-                    { output -> Optional.ofNullable(output.call) },
+                    Output::call,
                     ParamValueConverter.of(CALL_TYPE_SPEC)::toParamValue
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
index 61ceb00..f7318ef 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
@@ -211,12 +211,12 @@
                 )
                 .bindOptionalOutput(
                     "message",
-                    { output -> Optional.ofNullable(output.message) },
+                    Output::message,
                     ParamValueConverter.of(MESSAGE_TYPE_SPEC)::toParamValue
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-core/build.gradle b/appactions/interaction/interaction-capabilities-core/build.gradle
index 6683d10..5bca53c 100644
--- a/appactions/interaction/interaction-capabilities-core/build.gradle
+++ b/appactions/interaction/interaction-capabilities-core/build.gradle
@@ -25,8 +25,6 @@
 dependencies {
     api(project(path: ":appactions:interaction:interaction-proto", configuration: "shadowJar"))
 
-    annotationProcessor(libs.autoValue)
-
     api(libs.autoValueAnnotations)
     implementation(libs.guavaListenableFuture)
     implementation(libs.kotlinCoroutinesCore)
@@ -34,7 +32,6 @@
     implementation("androidx.concurrent:concurrent-futures:1.1.0")
     implementation("androidx.concurrent:concurrent-futures-ktx:1.1.0")
 
-    testAnnotationProcessor(libs.autoValue)
     testImplementation(project(":appactions:interaction:interaction-capabilities-testing"))
     testImplementation(libs.junit)
     testImplementation(libs.truth)
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt
index 3eece1d..8aaadae 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt
@@ -54,7 +54,7 @@
             ) {
                 null
             } else {
-                RequestMetadata.newBuilder().setRequestType(fulfillment.type).build()
+                RequestMetadata(fulfillment.type)
             }
         }
 
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.java
deleted file mode 100644
index 868a7d8..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents metadata from the Assistant FulfillmentRequest. */
-@AutoValue
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public abstract class RequestMetadata {
-
-    /** Create a Builder instance for building a RequestMetadata instance. */
-    @NonNull
-    public static Builder newBuilder() {
-        return new AutoValue_RequestMetadata.Builder();
-    }
-
-    /** The Type of request Assistant is sending on this FulfillmentRequest. */
-    @NonNull
-    public abstract Fulfillment.Type requestType();
-
-    /** Builder for RequestMetadata. */
-    @AutoValue.Builder
-    public abstract static class Builder {
-        /** Sets the FulfillmentRequest.Type. */
-        @NonNull
-        public abstract Builder setRequestType(@NonNull Fulfillment.Type requestType);
-
-        /** Builds the RequestMetadata instance. */
-        @NonNull
-        public abstract RequestMetadata build();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.kt
new file mode 100644
index 0000000..37be7ca
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl
+
+import androidx.annotation.RestrictTo
+import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment
+
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+data class RequestMetadata internal constructor(
+    val requestType: Fulfillment.Type
+) {
+    companion object {
+        @JvmStatic
+        fun create(requestType: Fulfillment.Type): RequestMetadata {
+            return RequestMetadata(requestType)
+        }
+    }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java
index 056c6e8..eba3f11 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java
@@ -37,7 +37,7 @@
      * @param <R>
      */
     @FunctionalInterface
-    public interface Function<T, R> {
+    interface Function<T, R> {
         R apply(T t) throws StructConversionException;
     }
 
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.java
deleted file mode 100644
index 2e2f22a..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl.converters;
-
-import androidx.appactions.interaction.protobuf.Value;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-import java.util.function.Function;
-
-@AutoValue
-abstract class FieldBinding<T, BuilderT> {
-
-    static <T, BuilderT> FieldBinding<T, BuilderT> create(
-            String name,
-            Function<T, Optional<Value>> valueGetter,
-            CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>> valueSetter) {
-        return new AutoValue_FieldBinding<>(name, valueGetter, valueSetter);
-    }
-
-    abstract String name();
-
-    abstract Function<T, Optional<Value>> valueGetter();
-
-    abstract CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>> valueSetter();
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.kt
new file mode 100644
index 0000000..2e97ad9
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.converters
+
+import androidx.appactions.interaction.protobuf.Value
+import java.util.Optional
+import java.util.function.Function
+
+internal data class FieldBinding<T, BuilderT> constructor(
+    val name: String,
+    val valueGetter: Function<T, Optional<Value>>,
+    val valueSetter: CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>>
+) {
+    companion object {
+        @JvmStatic
+        fun <T, BuilderT> create(
+            name: String,
+            valueGetter: Function<T, Optional<Value>>,
+            valueSetter: CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>>
+        ): FieldBinding<T, BuilderT> {
+            return FieldBinding(name, valueGetter, valueSetter)
+        }
+    }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
index 48f5a0c..f101314 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
@@ -74,9 +74,9 @@
     public Value toValue(@NonNull T obj) {
         Struct.Builder structBuilder = Struct.newBuilder();
         for (FieldBinding<T, BuilderT> binding : mBindings) {
-            binding.valueGetter()
+            binding.getValueGetter()
                     .apply(obj)
-                    .ifPresent(value -> structBuilder.putFields(binding.name(), value));
+                    .ifPresent(value -> structBuilder.putFields(binding.getName(), value));
         }
         return Value.newBuilder().setStructValue(structBuilder).build();
     }
@@ -101,8 +101,8 @@
         BuilderT builder = mBuilderSupplier.get();
         Map<String, Value> fieldsMap = struct.getFieldsMap();
         for (FieldBinding<T, BuilderT> binding : mBindings) {
-            Optional<Value> fieldValue = Optional.ofNullable(fieldsMap.get(binding.name()));
-            binding.valueSetter().accept(builder, fieldValue);
+            Optional<Value> fieldValue = Optional.ofNullable(fieldsMap.get(binding.getName()));
+            binding.getValueSetter().accept(builder, fieldValue);
         }
         return mBuilderFinalizer.apply(builder);
     }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.java
deleted file mode 100644
index eb8d0ad..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
-import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * A specification for an action, describing it from the app's point of view.
- *
- * @param <ArgumentsT> typed representation of action's arguments.
- * @param <OutputT>    typed action's execution output.
- */
-public interface ActionSpec<ArgumentsT, OutputT> {
-
-    /** Converts the property to the {@code AppAction} proto. */
-    @NonNull
-    AppAction convertPropertyToProto(@NonNull Map<String,
-            Property<?>> property);
-
-    /** Builds this action's arguments from an ArgumentsWrapper instance. */
-    @NonNull
-    ArgumentsT buildArguments(@NonNull Map<String, List<ParamValue>> args)
-            throws StructConversionException;
-
-    /** Converts the output to the {@code StructuredOutput} proto. */
-    @NonNull
-    StructuredOutput convertOutputToProto(OutputT output);
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.kt
new file mode 100644
index 0000000..450d3d3
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext
+import androidx.appactions.interaction.proto.FulfillmentResponse
+import androidx.appactions.interaction.proto.ParamValue
+
+/**
+ * A specification for an action, describing it from the app's point of view.
+ *
+ * @param ArgumentsT typed representation of action's arguments.
+ * @param OutputT    typed action's execution output.
+ */
+interface ActionSpec<ArgumentsT, OutputT> {
+
+    /** Converts the property to the `AppAction` proto.  */
+    fun convertPropertyToProto(property: Map<String, Property<*>>): AppActionsContext.AppAction
+
+    /** Builds this action's arguments from an ArgumentsWrapper instance.  */
+    @Throws(StructConversionException::class)
+    fun buildArguments(args: Map<String, List<ParamValue>>): ArgumentsT
+
+    /** Converts the output to the `StructuredOutput` proto.  */
+    fun convertOutputToProto(output: OutputT): FulfillmentResponse.StructuredOutput
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.java
deleted file mode 100644
index df268de..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter;
-import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter;
-import androidx.appactions.interaction.capabilities.core.impl.converters.SlotTypeConverter;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ParamBinding.ArgumentSetter;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/**
- * A builder for the {@code ActionSpec}.
- */
-public final class ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>,
-        OutputT> {
-
-    private final String mCapabilityName;
-    private final Supplier<ArgumentsBuilderT> mArgumentBuilderSupplier;
-    private final ArrayList<ParamBinding<ArgumentsT, ArgumentsBuilderT>>
-            mParamBindingList = new ArrayList<>();
-    private final Map<String, Function<OutputT, List<ParamValue>>> mOutputBindings =
-            new HashMap<>();
-
-    private ActionSpecBuilder(
-            String capabilityName, Supplier<ArgumentsBuilderT> argumentBuilderSupplier) {
-        this.mCapabilityName = capabilityName;
-        this.mArgumentBuilderSupplier = argumentBuilderSupplier;
-    }
-
-    /**
-     * Creates an empty {@code ActionSpecBuilder} with the given capability name. ArgumentsT is set
-     * to Object as a placeholder, which must be replaced by calling setArgument.
-     */
-    @NonNull
-    public static ActionSpecBuilder<Object, BuilderOf<Object>, Void> ofCapabilityNamed(
-            @NonNull String capabilityName) {
-        return new ActionSpecBuilder<>(capabilityName, () -> Object::new);
-    }
-
-    /** Sets the property type and returns a new {@code ActionSpecBuilder}. */
-
-    /** Sets the argument type and its builder and returns a new {@code ActionSpecBuilder}. */
-    @NonNull
-    public <NewArgumentsT, NewArgumentsBuilderT extends BuilderOf<NewArgumentsT>>
-    ActionSpecBuilder<NewArgumentsT, NewArgumentsBuilderT, OutputT> setArguments(
-            @NonNull Class<NewArgumentsT> unused,
-            @NonNull Supplier<NewArgumentsBuilderT> argumentBuilderSupplier) {
-        return new ActionSpecBuilder<>(this.mCapabilityName, argumentBuilderSupplier);
-    }
-
-    @NonNull
-    public <NewOutputT>
-    ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, NewOutputT> setOutput(
-            @NonNull Class<NewOutputT> unused) {
-        return new ActionSpecBuilder<>(this.mCapabilityName, this.mArgumentBuilderSupplier);
-    }
-
-    /**
-     * Binds the parameter name, getter and setter.
-     *
-     * @param paramName      the name of this action' parameter.
-     * @param paramGetter    a getter of the param-specific info from the property.
-     * @param argumentSetter a setter to the argument with the input from {@code ParamValue}.
-     * @return the builder itself.
-     */
-    @NonNull
-    private ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT>
-    bindParameterInternal(
-            @NonNull String paramName,
-            @NonNull Function<Map<String, Property<?>>,
-                    Optional<IntentParameter>> paramGetter,
-            @NonNull ArgumentSetter<ArgumentsBuilderT> argumentSetter) {
-        mParamBindingList.add(ParamBinding.create(paramName, paramGetter, argumentSetter));
-        return this;
-    }
-
-    /**
-     * Binds the parameter name, getter, and setter for a {@link Property}.
-     *
-     * <p>This parameter is required for any capability built from the generated {@link ActionSpec}.
-     *
-     * @param paramName the name of this action' parameter.
-     * @param propertyGetter a getter of the Property from the property, which must be able to
-     *     fetch a non-null {@code Property} from {@code PropertyT}.
-     * @param paramConsumer a setter to set the string value in the argument builder.
-     * @param paramValueConverter converter FROM assistant ParamValue proto
-     * @param entityConverter converter TO assistant Entity proto
-     * @return the builder itself.
-     */
-    @NonNull
-    public <T, PossibleValueT>
-    ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> bindParameter(
-            @NonNull String paramName,
-            @NonNull
-            Function<Map<String, Property<?>>,
-                    Property<PossibleValueT>>
-                    propertyGetter,
-            @NonNull BiConsumer<? super ArgumentsBuilderT, T> paramConsumer,
-            @NonNull ParamValueConverter<T> paramValueConverter,
-            @NonNull EntityConverter<PossibleValueT> entityConverter) {
-        return bindOptionalParameter(
-                paramName,
-                property -> Optional.of(propertyGetter.apply(property)),
-                paramConsumer,
-                paramValueConverter,
-                entityConverter);
-    }
-
-    /**
-     * Binds the parameter name, getter, and setter for a {@link Property}.
-     *
-     * <p>This parameter is optional for any capability built from the generated {@link ActionSpec}.
-     * If the Property Optional is not set, this parameter will not exist in the parameter
-     * definition of the capability.
-     *
-     * @param paramName the name of this action' parameter.
-     * @param optionalPropertyGetter an optional getter of the Property from the property,
-     *     which may be able to fetch a non-null {@code Property} from {@code PropertyT},
-     *     or get {@link Optional#empty}.
-     * @param paramConsumer a setter to set the string value in the argument builder.
-     * @param paramValueConverter converter FROM assistant ParamValue proto
-     * @param entityConverter converter TO assistant Entity proto
-     * @return the builder itself.
-     */
-    @NonNull
-    public <T, PossibleValueT>
-    ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT>
-    bindOptionalParameter(
-            @NonNull String paramName,
-            @NonNull
-            Function<
-                    Map<String, Property<?>>,
-                    Optional<Property<PossibleValueT>>>
-                    optionalPropertyGetter,
-            @NonNull BiConsumer<? super ArgumentsBuilderT, T> paramConsumer,
-            @NonNull ParamValueConverter<T> paramValueConverter,
-            @NonNull EntityConverter<PossibleValueT> entityConverter) {
-        return bindParameterInternal(
-                paramName,
-                property ->
-                        optionalPropertyGetter
-                                .apply(property)
-                                .map(p -> buildIntentParameter(paramName, p, entityConverter)),
-                (argBuilder, paramList) -> {
-                    if (!paramList.isEmpty()) {
-                        paramConsumer.accept(
-                                argBuilder,
-                                SlotTypeConverter.ofSingular(paramValueConverter)
-                                        .convert(paramList));
-                    }
-                });
-    }
-
-    /**
-     * This is similar to {@link ActionSpecBuilder#bindOptionalParameter} but for setting a list of
-     * entities instead.
-     *
-     * <p>This parameter is optional for any capability built from the generated {@link ActionSpec}.
-     * If the Property Optional is not set, this parameter will not exist in the parameter
-     * definition of the capability.
-     */
-    @NonNull
-    public <T, PossibleValueT>
-    ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT>
-    bindRepeatedParameter(
-            @NonNull String paramName,
-            @NonNull
-            Function<
-                    Map<String, Property<?>>,
-                    Optional<Property<PossibleValueT>>>
-                    optionalPropertyGetter,
-            @NonNull BiConsumer<? super ArgumentsBuilderT, List<T>> paramConsumer,
-            @NonNull ParamValueConverter<T> paramValueConverter,
-            @NonNull EntityConverter<PossibleValueT> entityConverter) {
-        return bindParameterInternal(
-                paramName,
-                property ->
-                        optionalPropertyGetter
-                                .apply(property)
-                                .map(p -> buildIntentParameter(paramName, p, entityConverter)),
-                (argBuilder, paramList) ->
-                        paramConsumer.accept(
-                                argBuilder,
-                                SlotTypeConverter.ofRepeated(paramValueConverter)
-                                        .convert(paramList)));
-    }
-
-    /**
-     * Binds an optional output.
-     *
-     * @param name         the BII output slot name of this parameter.
-     * @param outputGetter a getter of the output from the {@code OutputT} instance.
-     * @param converter    a converter from an output object to a ParamValue.
-     */
-    @NonNull
-    @SuppressWarnings("JdkCollectors")
-    public <T>
-    ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> bindOptionalOutput(
-            @NonNull String name,
-            @NonNull Function<OutputT, Optional<T>> outputGetter,
-            @NonNull Function<T, ParamValue> converter) {
-        mOutputBindings.put(
-                name,
-                output -> {
-                    Optional<T> optionalOut = outputGetter.apply(output);
-                    List<ParamValue> paramValues = new ArrayList<>();
-                    if (optionalOut.isPresent()) {
-                        paramValues.add(converter.apply(optionalOut.get()));
-                    }
-                    return Collections.unmodifiableList(paramValues);
-                });
-        return this;
-    }
-
-    /**
-     * Binds a repeated output.
-     *
-     * @param name         the BII output slot name of this parameter.
-     * @param outputGetter a getter of the output from the {@code OutputT} instance.
-     * @param converter    a converter from an output object to a ParamValue.
-     */
-    @NonNull
-    @SuppressWarnings("JdkCollectors")
-    public <T>
-    ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> bindRepeatedOutput(
-            @NonNull String name,
-            @NonNull Function<OutputT, List<T>> outputGetter,
-            @NonNull Function<T, ParamValue> converter) {
-        mOutputBindings.put(
-                name,
-                output ->
-                        outputGetter.apply(output).stream()
-                                .map(converter)
-                                .collect(toImmutableList()));
-        return this;
-    }
-
-    /** Builds an {@code ActionSpec} from this builder. */
-    @NonNull
-    public ActionSpec<ArgumentsT, OutputT> build() {
-        return new ActionSpecImpl<>(
-                mCapabilityName,
-                mArgumentBuilderSupplier,
-                Collections.unmodifiableList(mParamBindingList),
-                mOutputBindings);
-    }
-
-    /** Create IntentParameter proto from a Property. */
-    @NonNull
-    private static <T> IntentParameter buildIntentParameter(
-            @NonNull String paramName,
-            @NonNull Property<T> property,
-            @NonNull EntityConverter<T> entityConverter) {
-        IntentParameter.Builder builder = IntentParameter.newBuilder()
-                .setName(paramName)
-                .setIsRequired(property.isRequired())
-                .setEntityMatchRequired(property.isValueMatchRequired())
-                .setIsProhibited(property.isProhibited());
-        property.getPossibleValues().stream()
-                .map(entityConverter::convert)
-                .forEach(builder::addPossibleEntities);
-        return builder.build();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.kt
new file mode 100644
index 0000000..a523193
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.kt
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
+import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
+import androidx.appactions.interaction.capabilities.core.impl.converters.SlotTypeConverter
+import androidx.appactions.interaction.capabilities.core.impl.spec.ParamBinding.ArgumentSetter
+import androidx.appactions.interaction.capabilities.core.impl.spec.ParamBinding.Companion.create
+import androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext
+import androidx.appactions.interaction.proto.ParamValue
+import java.util.Optional
+import java.util.function.BiConsumer
+import java.util.function.Function
+import java.util.function.Supplier
+
+/**
+ * A builder for the `ActionSpec`.
+ */
+class ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>, OutputT>
+private constructor(
+    private val capabilityName: String,
+    private val argumentBuilderSupplier: Supplier<ArgumentsBuilderT>
+) {
+    private val paramBindingList: MutableList<ParamBinding<ArgumentsT, ArgumentsBuilderT>> =
+        ArrayList()
+    private val outputBindings: MutableMap<String, Function<OutputT, List<ParamValue>>> = HashMap()
+
+    /** Sets the property type and returns a new `ActionSpecBuilder`.  */
+    /** Sets the argument type and its builder and returns a new `ActionSpecBuilder`.  */
+    @Suppress("UNUSED_PARAMETER")
+    fun <NewArgumentsT, NewArgumentsBuilderT : BuilderOf<NewArgumentsT>> setArguments(
+        unused: Class<NewArgumentsT>,
+        argumentBuilderSupplier: Supplier<NewArgumentsBuilderT>
+    ): ActionSpecBuilder<NewArgumentsT, NewArgumentsBuilderT, OutputT> {
+        return ActionSpecBuilder(this.capabilityName, argumentBuilderSupplier)
+    }
+
+    @Suppress("UNUSED_PARAMETER")
+    fun <NewOutputT> setOutput(
+        unused: Class<NewOutputT>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, NewOutputT> {
+        return ActionSpecBuilder(this.capabilityName, this.argumentBuilderSupplier)
+    }
+
+    /**
+     * Binds the parameter name, getter and setter.
+     *
+     * @param paramName      the name of this action' parameter.
+     * @param paramGetter    a getter of the param-specific info from the property.
+     * @param argumentSetter a setter to the argument with the input from `ParamValue`.
+     * @return the builder itself.
+     */
+    private fun bindParameterInternal(
+        paramName: String,
+        paramGetter: Function<Map<String, Property<*>>,
+            Optional<AppActionsContext.IntentParameter>>,
+        argumentSetter: ArgumentSetter<ArgumentsBuilderT>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+        paramBindingList.add(create(paramName, paramGetter, argumentSetter))
+        return this
+    }
+
+    /**
+     * Binds the parameter name, getter, and setter for a [Property].
+     *
+     *
+     * This parameter is required for any capability built from the generated [ActionSpec].
+     *
+     * @param paramName the name of this action' parameter.
+     * @param propertyGetter a getter of the Property from the property, which must be able to
+     * fetch a non-null `Property` from `PropertyT`.
+     * @param paramConsumer a setter to set the string value in the argument builder.
+     * @param paramValueConverter converter FROM assistant ParamValue proto
+     * @param entityConverter converter TO assistant Entity proto
+     * @return the builder itself.
+     */
+    fun <T, PossibleValueT> bindParameter(
+        paramName: String,
+        propertyGetter: Function<Map<String, Property<*>>, Property<PossibleValueT>>,
+        paramConsumer: BiConsumer<in ArgumentsBuilderT, T>,
+        paramValueConverter: ParamValueConverter<T>,
+        entityConverter: EntityConverter<PossibleValueT>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+        return bindOptionalParameter(
+            paramName,
+            { propertyMap ->
+                Optional.of(propertyGetter.apply(propertyMap))
+            },
+            paramConsumer,
+            paramValueConverter,
+            entityConverter
+        )
+    }
+
+    /**
+     * Binds the parameter name, getter, and setter for a [Property].
+     *
+     *
+     * This parameter is optional for any capability built from the generated [ActionSpec].
+     * If the Property Optional is not set, this parameter will not exist in the parameter
+     * definition of the capability.
+     *
+     * @param paramName the name of this action' parameter.
+     * @param optionalPropertyGetter an optional getter of the Property from the property,
+     * which may be able to fetch a non-null `Property` from `PropertyT`,
+     * or get [Optional.empty].
+     * @param paramConsumer a setter to set the string value in the argument builder.
+     * @param paramValueConverter converter FROM assistant ParamValue proto
+     * @param entityConverter converter TO assistant Entity proto
+     * @return the builder itself.
+     */
+    fun <T, PossibleValueT> bindOptionalParameter(
+        paramName: String,
+        optionalPropertyGetter: Function<Map<String, Property<*>>,
+            Optional<Property<PossibleValueT>>>,
+        paramConsumer: BiConsumer<in ArgumentsBuilderT, T>,
+        paramValueConverter: ParamValueConverter<T>,
+        entityConverter: EntityConverter<PossibleValueT>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+        return bindParameterInternal(
+            paramName,
+            { propertyMap ->
+                optionalPropertyGetter
+                    .apply(propertyMap)
+                    .map { property ->
+                        buildIntentParameter(paramName, property, entityConverter)
+                    }
+            }
+        ) { argBuilder: ArgumentsBuilderT, paramList: List<ParamValue?> ->
+            if (paramList.isNotEmpty()) {
+                paramConsumer.accept(
+                    argBuilder,
+                    SlotTypeConverter.ofSingular(paramValueConverter).convert(paramList)
+                )
+            }
+        }
+    }
+
+    /**
+     * This is similar to [ActionSpecBuilder.bindOptionalParameter] but for setting a list of
+     * entities instead.
+     *
+     *
+     * This parameter is optional for any capability built from the generated [ActionSpec].
+     * If the Property Optional is not set, this parameter will not exist in the parameter
+     * definition of the capability.
+     */
+    fun <T, PossibleValueT> bindRepeatedParameter(
+        paramName: String,
+        optionalPropertyGetter: Function<Map<String, Property<*>>,
+            Optional<Property<PossibleValueT>>>,
+        paramConsumer: BiConsumer<in ArgumentsBuilderT, List<T>>,
+        paramValueConverter: ParamValueConverter<T>,
+        entityConverter: EntityConverter<PossibleValueT>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+        return bindParameterInternal(
+            paramName,
+            { propertyMap ->
+                optionalPropertyGetter
+                    .apply(propertyMap)
+                    .map { property ->
+                        buildIntentParameter(paramName, property, entityConverter)
+                    }
+            }
+        ) { argBuilder: ArgumentsBuilderT, paramList: List<ParamValue?>? ->
+            paramConsumer.accept(
+                argBuilder,
+                SlotTypeConverter.ofRepeated(paramValueConverter).convert(paramList!!)
+            )
+        }
+    }
+
+    /**
+     * Binds an optional output.
+     *
+     * @param name         the BII output slot name of this parameter.
+     * @param outputFieldGetter a getter of the output from the `OutputT` instance.
+     * @param converter    a converter from an output object to a ParamValue.
+     */
+    fun <T> bindOptionalOutput(
+        name: String,
+        outputFieldGetter: Function<OutputT, T?>,
+        converter: Function<T, ParamValue>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+        outputBindings[name] = Function { output: OutputT ->
+            val outputField: T? = outputFieldGetter.apply(output)
+            val paramValues: MutableList<ParamValue> =
+                ArrayList()
+            if (outputField != null) {
+                paramValues.add(converter.apply(outputField))
+            }
+            paramValues.toList()
+        }
+        return this
+    }
+
+    /**
+     * Binds a repeated output.
+     *
+     * @param name         the BII output slot name of this parameter.
+     * @param outputGetter a getter of the output from the `OutputT` instance.
+     * @param converter    a converter from an output object to a ParamValue.
+     */
+    fun <T> bindRepeatedOutput(
+        name: String,
+        outputGetter: Function<OutputT, List<T>>,
+        converter: Function<T, ParamValue>
+    ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+        outputBindings[name] = Function { output: OutputT ->
+            outputGetter.apply(output).stream()
+                .map(converter)
+                .collect(ImmutableCollectors.toImmutableList())
+        }
+        return this
+    }
+
+    /** Builds an `ActionSpec` from this builder.  */
+    fun build(): ActionSpec<ArgumentsT, OutputT> {
+        return ActionSpecImpl(
+            capabilityName,
+            argumentBuilderSupplier,
+            paramBindingList.toList(),
+            outputBindings.toMap()
+        )
+    }
+
+    companion object {
+        /**
+         * Creates an empty `ActionSpecBuilder` with the given capability name. ArgumentsT is set
+         * to Object as a placeholder, which must be replaced by calling setArgument.
+         */
+        fun ofCapabilityNamed(
+            capabilityName: String
+        ): ActionSpecBuilder<Any, BuilderOf<Any>, Any> {
+            return ActionSpecBuilder(capabilityName) { BuilderOf { Object() } }
+        }
+
+        /** Create IntentParameter proto from a Property.  */
+        internal fun <T> buildIntentParameter(
+            paramName: String,
+            property: Property<T>,
+            entityConverter: EntityConverter<T>
+        ): AppActionsContext.IntentParameter {
+            val builder = AppActionsContext.IntentParameter.newBuilder()
+                .setName(paramName)
+                .setIsRequired(property.isRequired)
+                .setEntityMatchRequired(property.isValueMatchRequired)
+                .setIsProhibited(property.isProhibited)
+            property.possibleValues.stream()
+                .map { possibleValue ->
+                    entityConverter.convert(possibleValue)
+                }
+                .forEach { entityProto ->
+                    builder.addPossibleEntities(entityProto)
+                }
+            return builder.build()
+        }
+    }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
deleted file mode 100644
index 8dfdb19..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
-import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/** The implementation of {@code ActionSpec} interface. */
-final class ActionSpecImpl<
-        ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>, OutputT>
-        implements ActionSpec<ArgumentsT, OutputT> {
-
-    private final String mCapabilityName;
-    private final Supplier<ArgumentsBuilderT> mArgumentBuilderSupplier;
-    private final List<ParamBinding<ArgumentsT, ArgumentsBuilderT>> mParamBindingList;
-    private final Map<String, Function<OutputT, List<ParamValue>>> mOutputBindings;
-
-    ActionSpecImpl(
-            String capabilityName,
-            Supplier<ArgumentsBuilderT> argumentBuilderSupplier,
-            List<ParamBinding<ArgumentsT, ArgumentsBuilderT>> paramBindingList,
-            Map<String, Function<OutputT, List<ParamValue>>> outputBindings) {
-        this.mCapabilityName = capabilityName;
-        this.mArgumentBuilderSupplier = argumentBuilderSupplier;
-        this.mParamBindingList = paramBindingList;
-        this.mOutputBindings = outputBindings;
-    }
-
-    @NonNull
-    @Override
-    public AppAction convertPropertyToProto(@NonNull Map<String, Property<?>> property) {
-        return AppAction.newBuilder()
-                .setName(mCapabilityName)
-                .addAllParams(
-                        mParamBindingList.stream()
-                                .map(binding -> binding.paramGetter().apply(property))
-                                .filter(Optional::isPresent)
-                                .map(Optional::get)
-                                .collect(toImmutableList()))
-                .build();
-    }
-
-    @NonNull
-    @Override
-    public ArgumentsT buildArguments(@NonNull Map<String, List<ParamValue>> args)
-            throws StructConversionException {
-        ArgumentsBuilderT argumentBuilder = mArgumentBuilderSupplier.get();
-        for (ParamBinding<ArgumentsT, ArgumentsBuilderT> binding : mParamBindingList) {
-            List<ParamValue> paramValues = args.get(binding.name());
-            if (paramValues == null) {
-                continue;
-            }
-            try {
-                binding.argumentSetter().setArguments(argumentBuilder, paramValues);
-            } catch (StructConversionException e) {
-                // Wrap the exception with a more meaningful error message.
-                throw new StructConversionException(
-                        String.format(
-                                "Failed to parse parameter '%s' from assistant because of "
-                                        + "failure: %s",
-                                binding.name(), e.getMessage()));
-            }
-        }
-        return argumentBuilder.build();
-    }
-
-    @NonNull
-    @Override
-    public StructuredOutput convertOutputToProto(OutputT output) {
-        StructuredOutput.Builder outputBuilder = StructuredOutput.newBuilder();
-        for (Map.Entry<String, Function<OutputT, List<ParamValue>>> entry :
-                mOutputBindings.entrySet()) {
-            List<ParamValue> values = entry.getValue().apply(output);
-            if (!values.isEmpty()) {
-                outputBuilder.addOutputValues(
-                        StructuredOutput.OutputValue.newBuilder()
-                                .setName(entry.getKey())
-                                .addAllValues(values)
-                                .build());
-            }
-        }
-        return outputBuilder.build();
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.kt
new file mode 100644
index 0000000..552b6b7
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext
+import androidx.appactions.interaction.proto.FulfillmentResponse
+import androidx.appactions.interaction.proto.ParamValue
+import java.util.function.Function
+import java.util.function.Supplier
+
+/** The implementation of `ActionSpec` interface.  */
+internal class ActionSpecImpl<ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>, OutputT>(
+    private val capabilityName: String,
+    private val argumentBuilderSupplier: Supplier<ArgumentsBuilderT>,
+    private val paramBindingList: List<ParamBinding<ArgumentsT, ArgumentsBuilderT>>,
+    private val outputBindings: Map<String, Function<OutputT, List<ParamValue>>>
+) : ActionSpec<ArgumentsT, OutputT> {
+
+    override fun convertPropertyToProto(
+        property: Map<String, Property<*>>
+    ): AppActionsContext.AppAction {
+        return AppActionsContext.AppAction.newBuilder()
+            .setName(capabilityName)
+            .addAllParams(
+                paramBindingList.stream()
+                    .map { binding -> binding.paramGetter.apply(property) }
+                    .filter { optional -> optional.isPresent }
+                    .map { optional -> optional.get() }
+                    .collect(ImmutableCollectors.toImmutableList())
+            )
+            .build()
+    }
+
+    @Throws(StructConversionException::class)
+    override fun buildArguments(args: Map<String, List<ParamValue>>): ArgumentsT {
+        val argumentBuilder = argumentBuilderSupplier.get()
+        paramBindingList.forEach { binding ->
+            val paramValues = args[binding.name] ?: return@forEach
+            try {
+                binding.argumentSetter.setArguments(argumentBuilder, paramValues)
+            } catch (e: StructConversionException) {
+                // Wrap the exception with a more meaningful error message.
+                throw StructConversionException(
+                    "Failed to parse parameter '${binding.name}' from assistant because of" +
+                        " failure: ${e.message}"
+                )
+            }
+        }
+        return argumentBuilder.build()
+    }
+
+    override fun convertOutputToProto(output: OutputT): FulfillmentResponse.StructuredOutput {
+        val outputBuilder = FulfillmentResponse.StructuredOutput.newBuilder()
+        outputBindings.entries.forEach { entry ->
+            val paramValues = entry.value.apply(output)
+            if (paramValues.isNotEmpty()) {
+                outputBuilder.addOutputValues(
+                    FulfillmentResponse.StructuredOutput.OutputValue.newBuilder()
+                        .setName(entry.key)
+                        .addAllValues(paramValues)
+                        .build()
+                )
+            }
+        }
+        return outputBuilder.build()
+    }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.java
deleted file mode 100644
index 87ce323..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-
-/**
- * A binding between a parameter and its Property converter / Argument setter.
- */
-@AutoValue
-public abstract class ParamBinding<
-        ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>> {
-
-    static <ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>>
-    ParamBinding<ArgumentsT, ArgumentsBuilderT> create(
-            String name,
-            Function<Map<String, Property<?>>,
-                    Optional<IntentParameter>> paramGetter,
-            ArgumentSetter<ArgumentsBuilderT> argumentSetter) {
-        return new AutoValue_ParamBinding<>(name, paramGetter, argumentSetter);
-    }
-
-    /** Returns the name of this param. */
-    @NonNull
-    public abstract String name();
-
-    /**
-     * Converts a {@code Property Map} to an {@code IntentParameter} proto. The resulting proto is
-     * the
-     * format which we send the current params to Assistant (via. app actions context).
-     */
-    @NonNull
-    public abstract Function<Map<String, Property<?>>,
-            Optional<IntentParameter>> paramGetter();
-
-    /**
-     * Populates the {@code ArgumentsBuilderT} for this param with the {@code ParamValue} sent from
-     * Assistant in Fulfillment.
-     */
-    @NonNull
-    public abstract ArgumentSetter<ArgumentsBuilderT> argumentSetter();
-
-    /**
-     * Given a {@code List<ParamValue>}, convert it to user-visible type and set it into
-     * ArgumentBuilder.
-     *
-     * @param <ArgumentsBuilderT>
-     */
-    @FunctionalInterface
-    public interface ArgumentSetter<ArgumentsBuilderT> {
-
-        /** Conversion from protos to user-visible type. */
-        void setArguments(@NonNull ArgumentsBuilderT builder, @NonNull List<ParamValue> paramValues)
-                throws StructConversionException;
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.kt
new file mode 100644
index 0000000..ffe3807
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter
+import androidx.appactions.interaction.proto.ParamValue
+import java.util.Optional
+import java.util.function.Function
+
+data class ParamBinding<ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>>
+internal constructor(
+    val name: String,
+    val paramGetter: Function<Map<String, Property<*>>, Optional<IntentParameter>>,
+    val argumentSetter: ArgumentSetter<ArgumentsBuilderT>
+) {
+    /**
+     * Given a `List<ParamValue>`, convert it to user-visible type and set it into
+     * ArgumentBuilder.
+     */
+    fun interface ArgumentSetter<ArgumentsBuilderT> {
+        /** Conversion from protos to user-visible type.  */
+        @Throws(StructConversionException::class)
+        fun setArguments(builder: ArgumentsBuilderT, paramValues: List<ParamValue>)
+    }
+
+    companion object {
+        @JvmStatic
+        fun <ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>> create(
+            name: String,
+            paramGetter: Function<Map<String, Property<*>>, Optional<IntentParameter>>,
+            argumentSetter: ArgumentSetter<ArgumentsBuilderT>
+        ): ParamBinding<ArgumentsT, ArgumentsBuilderT> {
+            return ParamBinding(name, paramGetter, argumentSetter)
+        }
+    }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.java
deleted file mode 100644
index 9145141..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.impl.task;
-
-import androidx.appactions.interaction.proto.CurrentValue;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import com.google.auto.value.AutoOneOf;
-
-/**
- * Helper object to express if the grounding step of argument processing was successul for a single
- * ParamValue.
- */
-@AutoOneOf(AppGroundingResult.Kind.class)
-abstract class AppGroundingResult {
-    static AppGroundingResult ofSuccess(ParamValue paramValue) {
-        return AutoOneOf_AppGroundingResult.success(paramValue);
-    }
-
-    static AppGroundingResult ofFailure(CurrentValue currentValue) {
-        return AutoOneOf_AppGroundingResult.failure(currentValue);
-    }
-
-    public abstract Kind getKind();
-
-    abstract ParamValue success();
-
-    abstract CurrentValue failure();
-
-    enum Kind {
-        SUCCESS,
-        FAILURE
-    }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.kt
new file mode 100644
index 0000000..f2463cd
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.core.impl.task
+
+import androidx.appactions.interaction.proto.CurrentValue
+import androidx.appactions.interaction.proto.ParamValue
+
+data class AppGroundingResult private constructor(
+    val kind: Kind,
+    val success: ParamValue?,
+    val failure: CurrentValue?
+) {
+    enum class Kind {
+        SUCCESS,
+        FAILURE
+    }
+
+    companion object {
+        @JvmStatic
+        fun ofSuccess(paramValue: ParamValue) = AppGroundingResult(Kind.SUCCESS, paramValue, null)
+
+        @JvmStatic
+        fun ofFailure(currentValue: CurrentValue) =
+            AppGroundingResult(Kind.FAILURE, null, currentValue)
+    }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt
index 9a03e83..f39671e 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt
@@ -183,7 +183,7 @@
         val callback = assistantUpdateRequest.callbackInternal
         try {
             val fulfillmentResult: FulfillmentResult = when (
-                argumentsWrapper.requestMetadata?.requestType()
+                argumentsWrapper.requestMetadata?.requestType
             ) {
                 FulfillmentRequest.Fulfillment.Type.SYNC -> handleSync(argumentsWrapper)
                 FulfillmentRequest.Fulfillment.Type.CONFIRM -> handleConfirm()
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt
index 1ab2990..fee2fd0 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt
@@ -25,7 +25,6 @@
 import androidx.appactions.interaction.proto.CurrentValue
 import androidx.appactions.interaction.proto.DisambiguationData
 import androidx.appactions.interaction.proto.ParamValue
-import kotlin.IllegalStateException
 import kotlin.String
 import kotlin.Throws
 
@@ -114,7 +113,6 @@
                 )
             }
             AppGroundingResult.Kind.FAILURE -> AppGroundingResult.ofFailure(pendingValue)
-            else -> throw IllegalStateException("unreachable")
         }
 
     /** enqueues processing of a pending value that requires app-driven grounding. */
@@ -132,7 +130,6 @@
         when (groundingResult.kind) {
             AppGroundingResult.Kind.SUCCESS -> ground(pendingValue.value, taskParamBinding)
             AppGroundingResult.Kind.FAILURE -> AppGroundingResult.ofFailure(pendingValue)
-            else -> throw IllegalStateException("unreachable")
         }
 
     /**
@@ -149,9 +146,8 @@
         ungroundedValues: MutableList<CurrentValue>,
     ): AppGroundingResult {
         when (groundingResult.kind) {
-            AppGroundingResult.Kind.SUCCESS -> groundedValues.add(groundingResult.success())
-            AppGroundingResult.Kind.FAILURE -> ungroundedValues.add(groundingResult.failure())
-            else -> throw IllegalStateException("unreachable")
+            AppGroundingResult.Kind.SUCCESS -> groundedValues.add(groundingResult.success!!)
+            AppGroundingResult.Kind.FAILURE -> ungroundedValues.add(groundingResult.failure!!)
         }
         return groundingResult
     }
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
index 02055bb..1d81ebd 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
@@ -327,14 +327,12 @@
 
     companion object {
         val ACTION_SPEC: ActionSpec<Arguments, Output> =
-            ActionSpecBuilder.ofCapabilityNamed(
-                "actions.intent.TEST"
-            )
+            ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
                 .setArguments(Arguments::class.java, Arguments::Builder)
                 .setOutput(Output::class.java)
                 .bindParameter(
                     "requiredString",
-                    { properties -> properties["requiredEntity"] as Property<StringValue>? },
+                    { properties -> properties["requiredEntity"] as Property<StringValue> },
                     Arguments.Builder::setRequiredStringField,
                     TypeConverters.STRING_PARAM_VALUE_CONVERTER,
                     TypeConverters.STRING_VALUE_ENTITY_CONVERTER
@@ -353,7 +351,7 @@
                 )
                 .bindOptionalOutput(
                     "optionalStringOutput",
-                    { output -> Optional.ofNullable(output.optionalStringField) },
+                    Output::optionalStringField,
                     TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
index d3e23ae..ec07c27 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
@@ -50,7 +50,7 @@
 @SuppressWarnings("unchecked")
 public final class ActionSpecTest {
     private static final ActionSpec<Arguments, Output> ACTION_SPEC =
-            ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
+            ActionSpecBuilder.Companion.ofCapabilityNamed("actions.intent.TEST")
                     .setArguments(Arguments.class, Arguments.Builder::new)
                     .setOutput(Output.class)
                     .bindParameter(
@@ -85,7 +85,7 @@
                             TypeConverters.STRING_VALUE_ENTITY_CONVERTER)
                     .bindOptionalOutput(
                             "optionalStringOutput",
-                            output -> Optional.ofNullable(output.getOptionalStringField()),
+                            Output::getOptionalStringField,
                             TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue)
                     .bindRepeatedOutput(
                             "repeatedStringOutput",
@@ -124,7 +124,7 @@
                             .build();
 
     private static final ActionSpec<GenericEntityArguments, Output> GENERIC_TYPES_ACTION_SPEC =
-            ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
+            ActionSpecBuilder.Companion.ofCapabilityNamed("actions.intent.TEST")
                     .setArguments(GenericEntityArguments.class, GenericEntityArguments.Builder::new)
                     .setOutput(Output.class)
                     .bindParameter(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
index ae89933..899612d 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
@@ -201,7 +201,8 @@
             createCapability(
                 SINGLE_REQUIRED_FIELD_PROPERTY,
                 sessionFactory =
-                { _ -> object : ExecutionSession {
+                { _ ->
+                    object : ExecutionSession {
                         override fun onCreate(sessionConfig: SessionConfig) {
                             onCreateInvocationCount.incrementAndGet()
                         }
@@ -210,7 +211,8 @@
                             Futures.immediateFuture(
                                 ExecutionResult.Builder<Output>().build()
                             )
-                    } },
+                    }
+                },
                 sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
                 sessionUpdaterSupplier = ::EmptyTaskUpdater
             )
@@ -360,20 +362,23 @@
                 .build(),
             "stringSlotB" to Property.Builder<StringValue>()
                 .setRequired(true)
-                .build(),
+                .build()
         )
         val sessionFactory:
-                (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
+            (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
             { _ ->
                 object : CapabilityTwoStrings.ExecutionSession {
                     override suspend fun onExecute(
                         arguments: CapabilityTwoStrings.Arguments
-                    ): ExecutionResult<Void> = ExecutionResult.Builder<Void>().build()
+                    ): ExecutionResult<CapabilityTwoStrings.Output> =
+                        ExecutionResult.Builder<CapabilityTwoStrings.Output>().build()
                 }
             }
         val sessionBridge =
-            SessionBridge<CapabilityTwoStrings.ExecutionSession, Void> {
-                TaskHandler.Builder<Void>()
+            SessionBridge<
+                CapabilityTwoStrings.ExecutionSession,
+                CapabilityTwoStrings.Confirmation> {
+                TaskHandler.Builder<CapabilityTwoStrings.Confirmation>()
                     .registerValueTaskParam(
                         "stringSlotA",
                         AUTO_ACCEPT_STRING_VALUE,
@@ -446,23 +451,25 @@
                 .build(),
             "stringSlotB" to Property.Builder<StringValue>()
                 .setRequired(false)
-                .build(),
+                .build()
         )
         val sessionFactory:
-                (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
+            (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
             { _ ->
                 object : CapabilityTwoStrings.ExecutionSession {
                     override suspend fun onExecute(
                         arguments: CapabilityTwoStrings.Arguments
-                    ): ExecutionResult<Void> {
+                    ): ExecutionResult<CapabilityTwoStrings.Output> {
                         onExecuteInvocationCount.incrementAndGet()
-                        return ExecutionResult.Builder<Void>().build()
+                        return ExecutionResult.Builder<CapabilityTwoStrings.Output>().build()
                     }
                 }
             }
         val sessionBridge =
-            SessionBridge<CapabilityTwoStrings.ExecutionSession, Void> {
-                TaskHandler.Builder<Void>()
+            SessionBridge<
+                CapabilityTwoStrings.ExecutionSession,
+                CapabilityTwoStrings.Confirmation> {
+                TaskHandler.Builder<CapabilityTwoStrings.Confirmation>()
                     .registerValueTaskParam(
                         "stringSlotA",
                         AUTO_ACCEPT_STRING_VALUE,
@@ -531,7 +538,7 @@
             "optionalEnum" to Property.Builder<TestEnum>()
                 .setPossibleValues(TestEnum.VALUE_1, TestEnum.VALUE_2)
                 .setRequired(true)
-                .build(),
+                .build()
         )
         val capability: Capability =
             createCapability(
@@ -618,15 +625,15 @@
                 SessionBridge<ExecutionSession, Confirmation> { session ->
                     val builder = TaskHandler.Builder<Confirmation>()
                     session.requiredStringListener?.let {
-                        listener: AppEntityListener<String> ->
-                            builder.registerAppEntityTaskParam(
-                                "required",
-                                listener,
-                                TypeConverters.STRING_PARAM_VALUE_CONVERTER,
-                                EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
-                                getTrivialSearchActionConverter()
-                            )
-                        }
+                            listener: AppEntityListener<String> ->
+                        builder.registerAppEntityTaskParam(
+                            "required",
+                            listener,
+                            TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+                            EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
+                            getTrivialSearchActionConverter()
+                        )
+                    }
                     builder.build()
                 },
                 sessionUpdaterSupplier = ::EmptyTaskUpdater
@@ -720,13 +727,13 @@
     fun identifierOnly_refillsStruct() = runBlocking<Unit> {
         val property = mapOf(
             "listItem" to Property.Builder<
-                ListItem,
+                ListItem
                 >()
                 .setRequired(true)
                 .build(),
             "anyString" to Property.Builder<StringValue>()
                 .setRequired(true)
-                .build(),
+                .build()
         )
         val item1: ListItem = ListItem.Builder().setName("red apple").setIdentifier("item1").build()
         val item2: ListItem =
@@ -736,15 +743,15 @@
         val onExecuteStringDeferred = CompletableDeferred<String>()
 
         val sessionFactory:
-                (hostProperties: HostProperties?) -> CapabilityStructFill.ExecutionSession =
+            (hostProperties: HostProperties?) -> CapabilityStructFill.ExecutionSession =
             { _ ->
                 object : CapabilityStructFill.ExecutionSession {
                     override suspend fun onExecute(
                         arguments: CapabilityStructFill.Arguments
-                    ): ExecutionResult<Void> {
+                    ): ExecutionResult<CapabilityStructFill.Output> {
                         arguments.listItem?.let { onExecuteListItemDeferred.complete(it) }
                         arguments.anyString?.let { onExecuteStringDeferred.complete(it) }
-                        return ExecutionResult.Builder<Void>().build()
+                        return ExecutionResult.Builder<CapabilityStructFill.Output>().build()
                     }
 
                     override val listItemListener =
@@ -769,8 +776,10 @@
                 }
             }
         val sessionBridge =
-            SessionBridge<CapabilityStructFill.ExecutionSession, Void> { session ->
-                TaskHandler.Builder<Void>()
+            SessionBridge<
+                CapabilityStructFill.ExecutionSession,
+                CapabilityStructFill.Confirmation> { session ->
+                TaskHandler.Builder<CapabilityStructFill.Confirmation>()
                     .registerAppEntityTaskParam(
                         "listItem",
                         session.listItemListener,
@@ -976,7 +985,7 @@
                 property,
                 sessionFactory = sessionFactory,
                 sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
-                sessionUpdaterSupplier = ::EmptyTaskUpdater,
+                sessionUpdaterSupplier = ::EmptyTaskUpdater
             )
         val session = capability.createSession(fakeSessionId, hostProperties)
 
@@ -984,7 +993,7 @@
         val callback = FakeCallbackInternal()
         session.execute(
             buildRequestArgs(SYNC),
-            callback,
+            callback
         )
         assertThat(callback.receiveResponse()).isNotNull()
         assertThat(getCurrentValues("required", session.state!!)).isEmpty()
@@ -993,11 +1002,12 @@
         // TURN 2. Providing the required slots so that the task completes and the state gets cleared
         val callback2 = FakeCallbackInternal()
         session.execute(
-            buildRequestArgs(SYNC,
+            buildRequestArgs(
+                SYNC,
                 "required",
                 ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
             ),
-            callback2,
+            callback2
         )
         assertThat(callback2.receiveResponse().fulfillmentResponse).isNotNull()
         assertThat(session.isActive).isEqualTo(false)
@@ -1015,13 +1025,15 @@
                 }
             }
         var onReadyToConfirm =
-             object : OnReadyToConfirmListenerInternal<Confirmation> {
+            object : OnReadyToConfirmListenerInternal<Confirmation> {
                 override suspend fun onReadyToConfirm(args: Map<String, List<ParamValue>>):
                     ConfirmationOutput<Confirmation> {
                     return ConfirmationOutput.Builder<Confirmation>()
-                            .setConfirmation(Confirmation.Builder().setOptionalStringField("bar")
-                                .build())
-                            .build()
+                        .setConfirmation(
+                            Confirmation.Builder().setOptionalStringField("bar")
+                                .build()
+                        )
+                        .build()
                 }
             }
         val property = mapOf(
@@ -1032,21 +1044,23 @@
                 property,
                 sessionFactory = sessionFactory,
                 sessionBridge = SessionBridge {
-                                    TaskHandler.Builder<Confirmation>()
-                                        .setOnReadyToConfirmListenerInternal(onReadyToConfirm)
-                                        .build() },
-                sessionUpdaterSupplier = ::EmptyTaskUpdater,
+                    TaskHandler.Builder<Confirmation>()
+                        .setOnReadyToConfirmListenerInternal(onReadyToConfirm)
+                        .build()
+                },
+                sessionUpdaterSupplier = ::EmptyTaskUpdater
             )
         val session = capability.createSession(fakeSessionId, hostProperties)
 
         // TURN 1. Providing all the required slots in the SYNC Request
         val callback = FakeCallbackInternal()
         session.execute(
-            buildRequestArgs(SYNC,
+            buildRequestArgs(
+                SYNC,
                 "required",
                 ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
             ),
-            callback,
+            callback
         )
         assertThat(callback.receiveResponse()).isNotNull()
         assertThat(session.isActive).isEqualTo(true)
@@ -1080,18 +1094,19 @@
                 property,
                 sessionFactory = sessionFactory,
                 sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
-                sessionUpdaterSupplier = ::EmptyTaskUpdater,
+                sessionUpdaterSupplier = ::EmptyTaskUpdater
             )
         val session = capability.createSession(fakeSessionId, hostProperties)
 
         // TURN 1. Providing the required slots so that the task completes and the state gets cleared
         val callback = FakeCallbackInternal()
         session.execute(
-            buildRequestArgs(SYNC,
+            buildRequestArgs(
+                SYNC,
                 "required",
                 ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
             ),
-            callback,
+            callback
         )
         assertThat(callback.receiveResponse().fulfillmentResponse).isNotNull()
         assertThat(session.isActive).isEqualTo(false)
@@ -1099,11 +1114,12 @@
         // TURN 2. Trying to sync after the session is destroyed
         val callback2 = FakeCallbackInternal()
         session.execute(
-            buildRequestArgs(SYNC,
+            buildRequestArgs(
+                SYNC,
                 "required",
                 ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
             ),
-            callback2,
+            callback2
         )
         assertThat(session.isActive).isEqualTo(false)
         assertThat(callback2.receiveResponse().errorStatus)
@@ -1220,18 +1236,18 @@
         }
 
         override val sessionBridge: SessionBridge<ExecutionSession, Confirmation> = SessionBridge {
-            session ->
+                session ->
             val builder = TaskHandler.Builder<Confirmation>()
             session.requiredStringListener?.let {
-                listener: AppEntityListener<String> ->
-                    builder.registerAppEntityTaskParam(
-                        "required",
-                        listener,
-                        TypeConverters.STRING_PARAM_VALUE_CONVERTER,
-                        EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
-                        getTrivialSearchActionConverter()
-                    )
-                }
+                    listener: AppEntityListener<String> ->
+                builder.registerAppEntityTaskParam(
+                    "required",
+                    listener,
+                    TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+                    EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
+                    getTrivialSearchActionConverter()
+                )
+            }
             builder.build()
         }
     }
@@ -1299,9 +1315,7 @@
                 .bindParameter(
                     "required",
                     { properties ->
-                        properties["required"]
-                            as
-                            Property<StringValue>?
+                        properties["required"] as Property<StringValue>
                     },
                     Arguments.Builder::setRequiredStringField,
                     TypeConverters.STRING_PARAM_VALUE_CONVERTER,
@@ -1345,7 +1359,7 @@
                 )
                 .bindOptionalOutput(
                     "optionalStringOutput",
-                    { output -> Optional.ofNullable(output.optionalStringField) },
+                    Output::optionalStringField,
                     TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue
                 )
                 .bindRepeatedOutput(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt
index b4c159e..8415ed7 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt
@@ -73,7 +73,11 @@
         }
     }
 
-    interface ExecutionSession : BaseExecutionSession<Arguments, Void> {
+    class Output internal constructor()
+
+    class Confirmation internal constructor()
+
+    interface ExecutionSession : BaseExecutionSession<Arguments, Output> {
         val listItemListener: AppEntityListener<ListItem>
     }
 
@@ -81,6 +85,7 @@
         @Suppress("UNCHECKED_CAST")
         val ACTION_SPEC = ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
             .setArguments(Arguments::class.java, Arguments::Builder)
+            .setOutput(Output::class.java)
             .bindOptionalParameter(
                 "listItem",
                 { properties ->
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt
index 2114322..542807b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt
@@ -70,12 +70,17 @@
         }
     }
 
-    interface ExecutionSession : BaseExecutionSession<Arguments, Void>
+    class Output internal constructor()
+
+    class Confirmation internal constructor()
+
+    interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
         @Suppress("UNCHECKED_CAST")
         val ACTION_SPEC = ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
             .setArguments(Arguments::class.java, Arguments::Builder)
+            .setOutput(Output::class.java)
             .bindOptionalParameter(
                 "stringSlotA",
                 { properties ->
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
index adb2749..1d89b82 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
@@ -110,17 +110,17 @@
         @Suppress("UNCHECKED_CAST")
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
-                .setArguments(StartExercise.Arguments::class.java, StartExercise.Arguments::Builder)
-                .setOutput(StartExercise.Output::class.java)
+                .setArguments(Arguments::class.java, Arguments::Builder)
+                .setOutput(Output::class.java)
                 .bindOptionalParameter(
                     "exercise.duration",
                     { properties ->
                         Optional.ofNullable(
-                            properties[StartExercise.PropertyMapStrings.DURATION.key]
+                            properties[PropertyMapStrings.DURATION.key]
                                 as Property<Duration>
                         )
                     },
-                    StartExercise.Arguments.Builder::setDuration,
+                    Arguments.Builder::setDuration,
                     TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
                     TypeConverters.DURATION_ENTITY_CONVERTER
                 )
@@ -128,11 +128,11 @@
                     "exercise.name",
                     { properties ->
                         Optional.ofNullable(
-                            properties[StartExercise.PropertyMapStrings.NAME.key]
+                            properties[PropertyMapStrings.NAME.key]
                                 as Property<StringValue>
                         )
                     },
-                    StartExercise.Arguments.Builder::setName,
+                    Arguments.Builder::setName,
                     TypeConverters.STRING_PARAM_VALUE_CONVERTER,
                     TypeConverters.STRING_VALUE_ENTITY_CONVERTER
                 )
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
index 59ed86a..bf30c36 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
@@ -176,7 +176,7 @@
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue,
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
index e174668..fce016f 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
@@ -173,7 +173,7 @@
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
index a190cc8..76f3019 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
@@ -173,7 +173,7 @@
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
index 7d71c22..ea01afc 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
@@ -243,7 +243,7 @@
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue,
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
index 394935b..c6f55b5 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
@@ -173,7 +173,7 @@
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
index 9152d36..0f06ed6 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
@@ -32,7 +32,6 @@
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
 
 private const val CAPABILITY_NAME = "actions.intent.START_EMERGENCY_SHARING"
 
@@ -165,7 +164,7 @@
                 .setOutput(Output::class.java)
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue,
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
index 133dfde..81a7bdab 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
@@ -258,12 +258,12 @@
                 )
                 .bindOptionalOutput(
                     "safetyCheck",
-                    { output -> Optional.ofNullable(output.safetyCheck) },
+                    Output::safetyCheck,
                     ParamValueConverter.of(SAFETY_CHECK_TYPE_SPEC)::toParamValue
                 )
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
index 88fe5f2..2f631de 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
@@ -32,7 +32,6 @@
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
 
 private const val CAPABILITY_NAME = "actions.intent.STOP_EMERGENCY_SHARING"
 
@@ -166,7 +165,7 @@
                 .setOutput(Output::class.java)
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue,
                 )
                 .build()
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
index c1d9aef..295e995 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
@@ -32,7 +32,6 @@
 import androidx.appactions.interaction.proto.ParamValue
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
 
 private const val CAPABILITY_NAME = "actions.intent.STOP_SAFETY_CHECK"
 
@@ -162,7 +161,7 @@
                 .setOutput(Output::class.java)
                 .bindOptionalOutput(
                     "executionStatus",
-                    { output -> Optional.ofNullable(output.executionStatus) },
+                    Output::executionStatus,
                     ExecutionStatus::toParamValue
                 )
                 .build()
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt
index 38d9ab2..5d3fbee 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt
@@ -30,6 +30,7 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.TimeUnit
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,6 +54,7 @@
     }
 
     @Test
+    @Ignore("b/280630647")
     fun testConfigurationUpdatedOnLandscapeMode() {
         // Wait for the activity to fully start before rotating,
         // otherwise we won't receive onConfigurationChanged.
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt
index 45357c5..eba4c96 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt
@@ -32,6 +32,7 @@
 import java.util.concurrent.TimeUnit
 import org.junit.After
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -70,6 +71,7 @@
     }
 
     @Test
+    @Ignore("b/280630647")
     fun testConfigurationUpdatedOnLandscapeMode() {
         // Wait for the activity to fully start before rotating,
         // otherwise we won't receive onConfigurationChanged.
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
index 3164fcc..737b39d 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
@@ -29,6 +29,7 @@
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
 import org.junit.Assume.assumeTrue
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -189,7 +190,7 @@
         assumeTrue(
             CpuInfo.locked ||
                 IsolationActivity.sustainedPerformanceModeInUse ||
-                Errors.isEmulator
+                DeviceInfo.isEmulator
         )
         iterationCheck(checkingForThermalThrottling = false)
     }
@@ -380,6 +381,7 @@
     }
 
     @Test
+    @Ignore("b/278737712")
     fun experimentalIters() {
         validateIters(
             warmupCount = 1,
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
index b336117..19d5d66 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
@@ -32,8 +32,7 @@
         Build.MODEL.contains("google_sdk") ||
         Build.MODEL.contains("sdk_gphone64") ||
         Build.MODEL.contains("Emulator") ||
-        Build.MODEL.contains("Android SDK built for x86") ||
-        Build.MODEL.contains("Android SDK built for arm64") ||
+        Build.MODEL.contains("Android SDK built for") ||
         Build.MANUFACTURER.contains("Genymotion") ||
         Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") ||
         "google_sdk" == Build.PRODUCT
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt
index 9919011..6403312 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt
@@ -64,15 +64,6 @@
         return ret
     }
 
-    val isEmulator = Build.FINGERPRINT.startsWith("generic") ||
-        Build.FINGERPRINT.startsWith("unknown") ||
-        Build.MODEL.contains("google_sdk") ||
-        Build.MODEL.contains("Emulator") ||
-        Build.MODEL.contains("Android SDK built for x86") ||
-        Build.MANUFACTURER.contains("Genymotion") ||
-        Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") ||
-        "google_sdk" == Build.PRODUCT
-
     private val isDeviceRooted =
         arrayOf(
             "/system/app/Superuser.apk",
@@ -110,7 +101,7 @@
                 |    real user's experience (or even regress release performance).
             """.trimMarginWrapNewlines()
         }
-        if (isEmulator) {
+        if (DeviceInfo.isEmulator) {
             warningPrefix += "EMULATOR_"
             warningString += """
                 |WARNING: Running on Emulator
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt
index e6fcaba..a074e20 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt
@@ -64,7 +64,7 @@
             initNs == 0.0 && // first time
             !CpuInfo.locked && // CPU locked (presumably to stable values), should be no throttling
             !IsolationActivity.sustainedPerformanceModeInUse && // trust sustained perf
-            !Errors.isEmulator // don't bother with emulators, will always be unpredicatable
+            !DeviceInfo.isEmulator // don't bother with emulators, will always be unpredictable
         ) {
             initNs = measureWorkNs()
         }
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt
index 9e98054..dc048f2c 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt
@@ -48,6 +48,7 @@
 class StartupTimingMetricTest {
     @MediumTest
     @Test
+    @Ignore("b/258335082")
     fun noResults() {
         assumeTrue(isAbiSupported())
         val packageName = "fake.package.fiction.nostartups"
@@ -170,12 +171,14 @@
 
     @LargeTest
     @Test
+    @Ignore("b/258335082")
     fun startup_fullyDrawn_immediate() {
         validateStartup_fullyDrawn(delayMs = 0)
     }
 
     @LargeTest
     @Test
+    @Ignore("b/258335082")
     fun startup_fullyDrawn_delayed() {
         validateStartup_fullyDrawn(delayMs = 100)
     }
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
index e3ca786..611c856 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
@@ -697,6 +697,7 @@
                 }
 
                 class Bar {
+                    @get:Composable
                     val foo by Foo()
                 }
 
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
index 9211731..b198df57 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
@@ -1363,7 +1363,10 @@
             }
 
             class Bar {
-                val foo by Foo()
+                val <!COMPOSABLE_EXPECTED!>foo<!> by Foo()
+
+                @get:Composable
+                val foo2 by Foo()
             }
             """
         )
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt
index 848bf03..25c7023 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,8 +50,6 @@
 import org.jetbrains.kotlin.psi.KtTryExpression
 import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.kotlin.resolve.BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL
-import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
-import org.jetbrains.kotlin.resolve.calls.util.getValueArgumentForExpression
 import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
 import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
 import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
@@ -60,6 +58,8 @@
 import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
 import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
 import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
+import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
+import org.jetbrains.kotlin.resolve.calls.util.getValueArgumentForExpression
 import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinedArgument
 import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull
 import org.jetbrains.kotlin.types.KotlinType
@@ -243,6 +243,10 @@
                                 // setValue delegate is not allowed for now.
                                 illegalComposableDelegate(context, reportOn)
                             }
+                            if (descriptor is PropertyDescriptor &&
+                                descriptor.getter?.hasComposableAnnotation() != true) {
+                                composableExpected(context, node.nameIdentifier ?: node)
+                            }
                             return
                         }
                     }
@@ -318,10 +322,17 @@
     ) {
         context.trace.report(ComposeErrors.COMPOSABLE_INVOCATION.on(callEl))
         if (functionEl != null) {
-            context.trace.report(ComposeErrors.COMPOSABLE_EXPECTED.on(functionEl))
+            composableExpected(context, functionEl)
         }
     }
 
+    private fun composableExpected(
+        context: CallCheckerContext,
+        functionEl: PsiElement
+    ) {
+        context.trace.report(ComposeErrors.COMPOSABLE_EXPECTED.on(functionEl))
+    }
+
     private fun illegalCallMustBeReadonly(
         context: CallCheckerContext,
         callEl: PsiElement
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt
index 7bb80ae..fd4a4db 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt
@@ -34,7 +34,6 @@
 import org.jetbrains.kotlin.ir.declarations.IrFunction
 import org.jetbrains.kotlin.ir.declarations.IrLocalDelegatedProperty
 import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
-import org.jetbrains.kotlin.ir.declarations.IrProperty
 import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
 import org.jetbrains.kotlin.ir.declarations.IrValueParameter
 import org.jetbrains.kotlin.ir.declarations.copyAttributes
@@ -174,18 +173,6 @@
         return super.visitLocalDelegatedProperty(declaration)
     }
 
-    override fun visitProperty(declaration: IrProperty): IrStatement {
-        if (declaration.getter?.isComposableDelegatedAccessor() == true) {
-            declaration.getter!!.annotations += createComposableAnnotation()
-        }
-
-        if (declaration.setter?.isComposableDelegatedAccessor() == true) {
-            declaration.setter!!.annotations += createComposableAnnotation()
-        }
-
-        return super.visitProperty(declaration)
-    }
-
     private fun createComposableAnnotation() =
         IrConstructorCallImpl(
             startOffset = SYNTHETIC_OFFSET,
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
index fab47f7..9cabe4e 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
@@ -31,6 +31,7 @@
 import java.util.concurrent.TimeUnit
 import org.junit.After
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 
@@ -57,6 +58,7 @@
     @SdkSuppress(minSdkVersion = 22) // b/266742122
     @OptIn(ExperimentalLayoutApi::class)
     @Test
+    @Ignore("b/266742122")
     fun imeAnimationWhenShowingIme() {
         val imeAnimationSourceValues = mutableListOf<Int>()
         val imeAnimationTargetValues = mutableListOf<Int>()
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/DataIndex.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/DataIndex.kt
deleted file mode 100644
index 8a98269..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/DataIndex.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.foundation.lazy
-
-/**
- * Represents an index in the list of items of lazy layout.
- */
-@Suppress("NOTHING_TO_INLINE")
-@kotlin.jvm.JvmInline
-internal value class DataIndex(val value: Int) {
-    inline operator fun inc(): DataIndex = DataIndex(value + 1)
-    inline operator fun dec(): DataIndex = DataIndex(value - 1)
-    inline operator fun plus(i: Int): DataIndex = DataIndex(value + i)
-    inline operator fun minus(i: Int): DataIndex = DataIndex(value - i)
-    inline operator fun minus(i: DataIndex): DataIndex = DataIndex(value - i.value)
-    inline operator fun compareTo(other: DataIndex): Int = value - other.value
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index 4994b52..05949c7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -262,9 +262,9 @@
         ) { index, key, contentType, placeables ->
             // we add spaceBetweenItems as an extra spacing for all items apart from the last one so
             // the lazy list measuring logic will take it into account.
-            val spacing = if (index.value == itemsCount - 1) 0 else spaceBetweenItems
+            val spacing = if (index == itemsCount - 1) 0 else spaceBetweenItems
             LazyListMeasuredItem(
-                index = index.value,
+                index = index,
                 placeables = placeables,
                 isVertical = isVertical,
                 horizontalAlignment = horizontalAlignment,
@@ -281,10 +281,10 @@
         }
         state.premeasureConstraints = measuredItemProvider.childConstraints
 
-        val firstVisibleItemIndex: DataIndex
+        val firstVisibleItemIndex: Int
         val firstVisibleScrollOffset: Int
         Snapshot.withoutReadObservation {
-            firstVisibleItemIndex = DataIndex(state.firstVisibleItemIndex)
+            firstVisibleItemIndex = state.firstVisibleItemIndex
             firstVisibleScrollOffset = state.firstVisibleItemScrollOffset
         }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt
index 2631561..978d3a8 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt
@@ -70,7 +70,7 @@
         return null
     }
 
-    val measuredHeaderItem = itemProvider.getAndMeasure(DataIndex(currentHeaderListPosition))
+    val measuredHeaderItem = itemProvider.getAndMeasure(currentHeaderListPosition)
 
     var headerOffset = if (currentHeaderOffset != Int.MIN_VALUE) {
         maxOf(-beforeContentPadding, currentHeaderOffset)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
index 945b774..497ba6d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
@@ -140,7 +140,7 @@
             if (newIndex == -1) {
                 activeKeys.remove(key)
             } else {
-                val item = itemProvider.getAndMeasure(DataIndex(newIndex))
+                val item = itemProvider.getAndMeasure(newIndex)
                 // check if we have any active placement animation on the item
                 var inProgress = false
                 repeat(item.placeablesCount) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
index 0c97ea2..91d0350 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
@@ -44,7 +44,7 @@
     beforeContentPadding: Int,
     afterContentPadding: Int,
     spaceBetweenItems: Int,
-    firstVisibleItemIndex: DataIndex,
+    firstVisibleItemIndex: Int,
     firstVisibleItemScrollOffset: Int,
     scrollToBeConsumed: Float,
     constraints: Constraints,
@@ -81,10 +81,10 @@
     } else {
         var currentFirstItemIndex = firstVisibleItemIndex
         var currentFirstItemScrollOffset = firstVisibleItemScrollOffset
-        if (currentFirstItemIndex.value >= itemsCount) {
+        if (currentFirstItemIndex >= itemsCount) {
             // the data set has been updated and now we have less items that we were
             // scrolled to before
-            currentFirstItemIndex = DataIndex(itemsCount - 1)
+            currentFirstItemIndex = itemsCount - 1
             currentFirstItemScrollOffset = 0
         }
 
@@ -96,7 +96,7 @@
         currentFirstItemScrollOffset -= scrollDelta
 
         // if the current scroll offset is less than minimally possible
-        if (currentFirstItemIndex == DataIndex(0) && currentFirstItemScrollOffset < 0) {
+        if (currentFirstItemIndex == 0 && currentFirstItemScrollOffset < 0) {
             scrollDelta += currentFirstItemScrollOffset
             currentFirstItemScrollOffset = 0
         }
@@ -119,8 +119,8 @@
         // we had scrolled backward or we compose items in the start padding area, which means
         // items before current firstItemScrollOffset should be visible. compose them and update
         // firstItemScrollOffset
-        while (currentFirstItemScrollOffset < 0 && currentFirstItemIndex > DataIndex(0)) {
-            val previous = DataIndex(currentFirstItemIndex.value - 1)
+        while (currentFirstItemScrollOffset < 0 && currentFirstItemIndex > 0) {
+            val previous = currentFirstItemIndex - 1
             val measuredItem = measuredItemProvider.getAndMeasure(previous)
             visibleItems.add(0, measuredItem)
             maxCrossAxis = maxOf(maxCrossAxis, measuredItem.crossAxisSize)
@@ -151,7 +151,7 @@
         // then composing visible items forward until we fill the whole viewport.
         // we want to have at least one item in visibleItems even if in fact all the items are
         // offscreen, this can happen if the content padding is larger than the available size.
-        while (index.value < itemsCount &&
+        while (index < itemsCount &&
             (currentMainAxisOffset < maxMainAxis ||
                 currentMainAxisOffset <= 0 || // filling beforeContentPadding area
                 visibleItems.isEmpty())
@@ -159,7 +159,7 @@
             val measuredItem = measuredItemProvider.getAndMeasure(index)
             currentMainAxisOffset += measuredItem.sizeWithSpacings
 
-            if (currentMainAxisOffset <= minOffset && index.value != itemsCount - 1) {
+            if (currentMainAxisOffset <= minOffset && index != itemsCount - 1) {
                 // this item is offscreen and will not be placed. advance firstVisibleItemIndex
                 currentFirstItemIndex = index + 1
                 currentFirstItemScrollOffset -= measuredItem.sizeWithSpacings
@@ -178,9 +178,9 @@
             currentFirstItemScrollOffset -= toScrollBack
             currentMainAxisOffset += toScrollBack
             while (currentFirstItemScrollOffset < beforeContentPadding &&
-                currentFirstItemIndex > DataIndex(0)
+                currentFirstItemIndex > 0
             ) {
-                val previousIndex = DataIndex(currentFirstItemIndex.value - 1)
+                val previousIndex = currentFirstItemIndex - 1
                 val measuredItem = measuredItemProvider.getAndMeasure(previousIndex)
                 visibleItems.add(0, measuredItem)
                 maxCrossAxis = maxOf(maxCrossAxis, measuredItem.crossAxisSize)
@@ -305,7 +305,7 @@
         return LazyListMeasureResult(
             firstVisibleItem = firstItem,
             firstVisibleItemScrollOffset = currentFirstItemScrollOffset,
-            canScrollForward = index.value < itemsCount || currentMainAxisOffset > maxOffset,
+            canScrollForward = index < itemsCount || currentMainAxisOffset > maxOffset,
             consumedScroll = consumedScroll,
             measureResult = layout(layoutWidth, layoutHeight) {
                 positionedItems.fastForEach {
@@ -345,7 +345,7 @@
     fun addItem(index: Int) {
         if (list == null) list = mutableListOf()
         requireNotNull(list).add(
-            measuredItemProvider.getAndMeasure(DataIndex(index))
+            measuredItemProvider.getAndMeasure(index)
         )
     }
 
@@ -365,25 +365,25 @@
 }
 
 private fun createItemsBeforeList(
-    currentFirstItemIndex: DataIndex,
+    currentFirstItemIndex: Int,
     measuredItemProvider: LazyListMeasuredItemProvider,
     beyondBoundsItemCount: Int,
     pinnedItems: List<Int>
 ): List<LazyListMeasuredItem> {
     var list: MutableList<LazyListMeasuredItem>? = null
 
-    var start = currentFirstItemIndex.value
+    var start = currentFirstItemIndex
 
     fun addItem(index: Int) {
         if (list == null) list = mutableListOf()
         requireNotNull(list).add(
-            measuredItemProvider.getAndMeasure(DataIndex(index))
+            measuredItemProvider.getAndMeasure(index)
         )
     }
 
     start = maxOf(0, start - beyondBoundsItemCount)
 
-    for (i in currentFirstItemIndex.value - 1 downTo start) {
+    for (i in currentFirstItemIndex - 1 downTo start) {
         addItem(i)
     }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt
index 5ab0394..77ec076 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt
@@ -43,10 +43,10 @@
      * Used to subcompose items of lazy lists. Composed placeables will be measured with the
      * correct constraints and wrapped into [LazyListMeasuredItem].
      */
-    fun getAndMeasure(index: DataIndex): LazyListMeasuredItem {
-        val key = keyIndexMap.getKey(index.value) ?: itemProvider.getKey(index.value)
-        val contentType = itemProvider.getContentType(index.value)
-        val placeables = measureScope.measure(index.value, childConstraints)
+    fun getAndMeasure(index: Int): LazyListMeasuredItem {
+        val key = keyIndexMap.getKey(index) ?: itemProvider.getKey(index)
+        val contentType = itemProvider.getContentType(index)
+        val placeables = measureScope.measure(index, childConstraints)
         return measuredItemFactory.createItem(index, key, contentType, placeables)
     }
 
@@ -60,7 +60,7 @@
 // This interface allows to avoid autoboxing on index param
 internal fun interface MeasuredItemFactory {
     fun createItem(
-        index: DataIndex,
+        index: Int,
         key: Any,
         contentType: Any?,
         placeables: List<Placeable>
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt
index 4717a84..16eb1c7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt
@@ -19,7 +19,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.lazy.layout.findIndexByKey
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshots.Snapshot
 
@@ -31,9 +31,9 @@
     initialIndex: Int = 0,
     initialScrollOffset: Int = 0
 ) {
-    var index by mutableStateOf(DataIndex(initialIndex))
+    var index by mutableIntStateOf(initialIndex)
 
-    var scrollOffset by mutableStateOf(initialScrollOffset)
+    var scrollOffset by mutableIntStateOf(initialScrollOffset)
         private set
 
     private var hadFirstNotEmptyLayout = false
@@ -56,7 +56,7 @@
 
             Snapshot.withoutReadObservation {
                 update(
-                    DataIndex(measureResult.firstVisibleItem?.index ?: 0),
+                    measureResult.firstVisibleItem?.index ?: 0,
                     scrollOffset
                 )
             }
@@ -74,7 +74,7 @@
      * c) there will be not enough items to fill the viewport after the requested index, so we
      * would have to compose few elements before the asked index, changing the first visible item.
      */
-    fun requestPosition(index: DataIndex, scrollOffset: Int) {
+    fun requestPosition(index: Int, scrollOffset: Int) {
         update(index, scrollOffset)
         // clear the stored key as we have a direct request to scroll to [index] position and the
         // next [checkIfFirstVisibleItemWasMoved] shouldn't override this.
@@ -91,14 +91,14 @@
     fun updateScrollPositionIfTheFirstItemWasMoved(itemProvider: LazyListItemProvider) {
         Snapshot.withoutReadObservation {
             update(
-                DataIndex(itemProvider.findIndexByKey(lastKnownFirstItemKey, index.value)),
+                itemProvider.findIndexByKey(lastKnownFirstItemKey, index),
                 scrollOffset
             )
         }
     }
 
-    private fun update(index: DataIndex, scrollOffset: Int) {
-        require(index.value >= 0f) { "Index should be non-negative (${index.value})" }
+    private fun update(index: Int, scrollOffset: Int) {
+        require(index >= 0f) { "Index should be non-negative ($index)" }
         if (index != this.index) {
             this.index = index
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
index 1e5742f..3bd36be 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
@@ -103,7 +103,7 @@
      * derived state in order to only have recompositions when the derived value changes:
      * @sample androidx.compose.foundation.samples.UsingListScrollPositionInCompositionSample
      */
-    val firstVisibleItemIndex: Int get() = scrollPosition.index.value
+    val firstVisibleItemIndex: Int get() = scrollPosition.index
 
     /**
      * The scroll offset of the first visible item. Scrolling forward is positive - i.e., the
@@ -245,7 +245,7 @@
     }
 
     internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
-        scrollPosition.requestPosition(DataIndex(index), scrollOffset)
+        scrollPosition.requestPosition(index, scrollOffset)
         // placement animation is not needed because we snap into a new position.
         placementAnimator.reset()
         remeasurement?.forceRemeasure()
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/ItemIndex.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/ItemIndex.kt
deleted file mode 100644
index 7207064..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/ItemIndex.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.foundation.lazy.grid
-
-/**
- * Represents a line index in the lazy grid.
- */
-@Suppress("NOTHING_TO_INLINE")
-@kotlin.jvm.JvmInline
-internal value class LineIndex(val value: Int) {
-    inline operator fun inc(): LineIndex = LineIndex(value + 1)
-    inline operator fun dec(): LineIndex = LineIndex(value - 1)
-    inline operator fun plus(i: Int): LineIndex = LineIndex(value + i)
-    inline operator fun minus(i: Int): LineIndex = LineIndex(value - i)
-    inline operator fun minus(i: LineIndex): LineIndex = LineIndex(value - i.value)
-    inline operator fun compareTo(other: LineIndex): Int = value - other.value
-}
-
-/**
- * Represents an item index in the lazy grid.
- */
-@Suppress("NOTHING_TO_INLINE")
-@kotlin.jvm.JvmInline
-internal value class ItemIndex(val value: Int) {
-    inline operator fun inc(): ItemIndex = ItemIndex(value + 1)
-    inline operator fun dec(): ItemIndex = ItemIndex(value - 1)
-    inline operator fun plus(i: Int): ItemIndex = ItemIndex(value + i)
-    inline operator fun minus(i: Int): ItemIndex = ItemIndex(value - i)
-    inline operator fun minus(i: ItemIndex): ItemIndex = ItemIndex(value - i.value)
-    inline operator fun compareTo(other: ItemIndex): Int = value - other.value
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
index c752ea4..4f84478 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
@@ -286,26 +286,24 @@
                 spans = spans,
                 slots = resolvedSlots,
                 isVertical = isVertical,
-                slotsPerLine = slotsPerLine,
-                layoutDirection = layoutDirection,
                 mainAxisSpacing = mainAxisSpacing,
             )
         }
         state.prefetchInfoRetriever = { line ->
-            val lineConfiguration = spanLayoutProvider.getLineConfiguration(line.value)
-            var index = ItemIndex(lineConfiguration.firstItemIndex)
+            val lineConfiguration = spanLayoutProvider.getLineConfiguration(line)
+            var index = lineConfiguration.firstItemIndex
             var slot = 0
             val result = ArrayList<Pair<Int, Constraints>>(lineConfiguration.spans.size)
             lineConfiguration.spans.fastForEach {
                 val span = it.currentLineSpan
-                result.add(index.value to measuredLineProvider.childConstraints(slot, span))
+                result.add(index to measuredLineProvider.childConstraints(slot, span))
                 ++index
                 slot += span
             }
             result
         }
 
-        val firstVisibleLineIndex: LineIndex
+        val firstVisibleLineIndex: Int
         val firstVisibleLineScrollOffset: Int
 
         Snapshot.withoutReadObservation {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
index f77f284..fbd96ee 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
@@ -167,7 +167,7 @@
                 keyToItemInfoMap.remove(key)
             } else {
                 val item = itemProvider.getAndMeasure(
-                    ItemIndex(newIndex),
+                    newIndex,
                     constraints = if (isVertical) {
                         Constraints.fixedWidth(itemInfo.crossAxisSize)
                     } else {
@@ -199,7 +199,7 @@
         previousLineMainAxisSize = 0
         movingAwayToStartBound.sortByDescending { keyIndexMap.getIndex(it.key) }
         movingAwayToStartBound.fastForEach { item ->
-            val line = spanLayoutProvider.getLineIndexOfItem(item.index.value).value
+            val line = spanLayoutProvider.getLineIndexOfItem(item.index)
             if (line != -1 && line == previousLine) {
                 previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.mainAxisSize)
             } else {
@@ -227,7 +227,7 @@
         previousLineMainAxisSize = 0
         movingAwayToEndBound.sortBy { keyIndexMap.getIndex(it.key) }
         movingAwayToEndBound.fastForEach { item ->
-            val line = spanLayoutProvider.getLineIndexOfItem(item.index.value).value
+            val line = spanLayoutProvider.getLineIndexOfItem(item.index)
             if (line != -1 && line == previousLine) {
                 previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.mainAxisSize)
             } else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
index a2a11fe..d5fa3ec 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
@@ -47,7 +47,7 @@
     beforeContentPadding: Int,
     afterContentPadding: Int,
     spaceBetweenLines: Int,
-    firstVisibleLineIndex: LineIndex,
+    firstVisibleLineIndex: Int,
     firstVisibleLineScrollOffset: Int,
     scrollToBeConsumed: Float,
     constraints: Constraints,
@@ -92,7 +92,7 @@
         currentFirstLineScrollOffset -= scrollDelta
 
         // if the current scroll offset is less than minimally possible
-        if (currentFirstLineIndex == LineIndex(0) && currentFirstLineScrollOffset < 0) {
+        if (currentFirstLineIndex == 0 && currentFirstLineScrollOffset < 0) {
             scrollDelta += currentFirstLineScrollOffset
             currentFirstLineScrollOffset = 0
         }
@@ -112,8 +112,8 @@
         // we had scrolled backward or we compose items in the start padding area, which means
         // items before current firstLineScrollOffset should be visible. compose them and update
         // firstLineScrollOffset
-        while (currentFirstLineScrollOffset < 0 && currentFirstLineIndex > LineIndex(0)) {
-            val previous = LineIndex(currentFirstLineIndex.value - 1)
+        while (currentFirstLineScrollOffset < 0 && currentFirstLineIndex > 0) {
+            val previous = currentFirstLineIndex - 1
             val measuredLine = measuredLineProvider.getAndMeasure(previous)
             visibleLines.add(0, measuredLine)
             currentFirstLineScrollOffset += measuredLine.mainAxisSizeWithSpacings
@@ -143,7 +143,7 @@
         // then composing visible lines forward until we fill the whole viewport.
         // we want to have at least one line in visibleItems even if in fact all the items are
         // offscreen, this can happen if the content padding is larger than the available size.
-        while (index.value < itemsCount &&
+        while (index < itemsCount &&
             (currentMainAxisOffset < maxMainAxis ||
                 currentMainAxisOffset <= 0 || // filling beforeContentPadding area
                 visibleLines.isEmpty())
@@ -155,7 +155,7 @@
 
             currentMainAxisOffset += measuredLine.mainAxisSizeWithSpacings
             if (currentMainAxisOffset <= minOffset &&
-                measuredLine.items.last().index.value != itemsCount - 1) {
+                measuredLine.items.last().index != itemsCount - 1) {
                 // this line is offscreen and will not be placed. advance firstVisibleLineIndex
                 currentFirstLineIndex = index + 1
                 currentFirstLineScrollOffset -= measuredLine.mainAxisSizeWithSpacings
@@ -172,9 +172,9 @@
             currentFirstLineScrollOffset -= toScrollBack
             currentMainAxisOffset += toScrollBack
             while (currentFirstLineScrollOffset < beforeContentPadding &&
-                currentFirstLineIndex > LineIndex(0)
+                currentFirstLineIndex > 0
             ) {
-                val previousIndex = LineIndex(currentFirstLineIndex.value - 1)
+                val previousIndex = currentFirstLineIndex - 1
                 val measuredLine = measuredLineProvider.getAndMeasure(previousIndex)
                 visibleLines.add(0, measuredLine)
                 currentFirstLineScrollOffset += measuredLine.mainAxisSizeWithSpacings
@@ -205,8 +205,8 @@
         val visibleLinesScrollOffset = -currentFirstLineScrollOffset
         var firstLine = visibleLines.first()
 
-        val firstItemIndex = firstLine.items.firstOrNull()?.index?.value ?: 0
-        val lastItemIndex = visibleLines.lastOrNull()?.items?.lastOrNull()?.index?.value ?: 0
+        val firstItemIndex = firstLine.items.firstOrNull()?.index ?: 0
+        val lastItemIndex = visibleLines.lastOrNull()?.items?.lastOrNull()?.index ?: 0
         val extraItemsBefore = calculateExtraItems(
             pinnedItems,
             measuredItemProvider,
@@ -304,17 +304,16 @@
 private inline fun calculateExtraItems(
     pinnedItems: List<Int>,
     measuredItemProvider: LazyGridMeasuredItemProvider,
-    itemConstraints: (ItemIndex) -> Constraints,
+    itemConstraints: (Int) -> Constraints,
     filter: (Int) -> Boolean
 ): List<LazyGridMeasuredItem> {
     var items: MutableList<LazyGridMeasuredItem>? = null
 
     pinnedItems.fastForEach { index ->
         if (filter(index)) {
-            val itemIndex = ItemIndex(index)
-            val constraints = itemConstraints(itemIndex)
+            val constraints = itemConstraints(index)
             val measuredItem = measuredItemProvider.getAndMeasure(
-                itemIndex,
+                index,
                 constraints = constraints
             )
             if (items == null) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
index 9db0fd0..74a6896 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
@@ -28,7 +28,7 @@
  * if the user emit multiple layout nodes in the item callback.
  */
 internal class LazyGridMeasuredItem(
-    val index: ItemIndex,
+    val index: Int,
     val key: Any,
     private val isVertical: Boolean,
     /**
@@ -101,7 +101,7 @@
             } else {
                 IntOffset(mainAxisOffset, crossAxisOffset)
             },
-            index = index.value,
+            index = index,
             key = key,
             row = row,
             column = column,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt
index 6b161dc..c984631 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt
@@ -37,13 +37,13 @@
      * with the provided [constraints] and wrapped into [LazyGridMeasuredItem].
      */
     fun getAndMeasure(
-        index: ItemIndex,
+        index: Int,
         mainAxisSpacing: Int = defaultMainAxisSpacing,
         constraints: Constraints
     ): LazyGridMeasuredItem {
-        val key = keyIndexMap.getKey(index.value) ?: itemProvider.getKey(index.value)
-        val contentType = itemProvider.getContentType(index.value)
-        val placeables = measureScope.measure(index.value, constraints)
+        val key = keyIndexMap.getKey(index) ?: itemProvider.getKey(index)
+        val contentType = itemProvider.getContentType(index)
+        val placeables = measureScope.measure(index, constraints)
         val crossAxisSize = if (constraints.hasFixedWidth) {
             constraints.minWidth
         } else {
@@ -70,7 +70,7 @@
 // This interface allows to avoid autoboxing on index param
 internal fun interface MeasuredItemFactory {
     fun createItem(
-        index: ItemIndex,
+        index: Int,
         key: Any,
         contentType: Any?,
         crossAxisSize: Int,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
index b70f8bf..0b3f5e0 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
@@ -17,7 +17,6 @@
 package androidx.compose.foundation.lazy.grid
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.ui.unit.LayoutDirection
 
 /**
  * Represents one measured line of the lazy list. Each item on the line can in fact consist of
@@ -25,13 +24,11 @@
  */
 @OptIn(ExperimentalFoundationApi::class)
 internal class LazyGridMeasuredLine constructor(
-    val index: LineIndex,
+    val index: Int,
     val items: Array<LazyGridMeasuredItem>,
     private val slots: LazyGridSlots,
     private val spans: List<GridItemSpan>,
     private val isVertical: Boolean,
-    private val slotsPerLine: Int,
-    private val layoutDirection: LayoutDirection,
     /**
      * Spacing to be added after [mainAxisSize], in the main axis direction.
      */
@@ -80,8 +77,8 @@
                 crossAxisOffset = slots.positions[startSlot],
                 layoutWidth = layoutWidth,
                 layoutHeight = layoutHeight,
-                row = if (isVertical) index.value else startSlot,
-                column = if (isVertical) startSlot else index.value
+                row = if (isVertical) index else startSlot,
+                column = if (isVertical) startSlot else index
             ).also {
                 usedSpan += span
             }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
index c8fde9d..fe5ff54 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
@@ -48,9 +48,9 @@
         }
     }
 
-    fun itemConstraints(itemIndex: ItemIndex): Constraints {
+    fun itemConstraints(itemIndex: Int): Constraints {
         val span = spanLayoutProvider.spanOf(
-            itemIndex.value,
+            itemIndex,
             spanLayoutProvider.slotsPerLine
         )
         return childConstraints(0, span)
@@ -60,8 +60,8 @@
      * Used to subcompose items on lines of lazy grids. Composed placeables will be measured
      * with the correct constraints and wrapped into [LazyGridMeasuredLine].
      */
-    fun getAndMeasure(lineIndex: LineIndex): LazyGridMeasuredLine {
-        val lineConfiguration = spanLayoutProvider.getLineConfiguration(lineIndex.value)
+    fun getAndMeasure(lineIndex: Int): LazyGridMeasuredLine {
+        val lineConfiguration = spanLayoutProvider.getLineConfiguration(lineIndex)
         val lineItemsCount = lineConfiguration.spans.size
 
         // we add space between lines as an extra spacing for all lines apart from the last one
@@ -78,7 +78,7 @@
             val span = lineConfiguration.spans[it].currentLineSpan
             val constraints = childConstraints(startSlot, span)
             measuredItemProvider.getAndMeasure(
-                ItemIndex(lineConfiguration.firstItemIndex + it),
+                lineConfiguration.firstItemIndex + it,
                 mainAxisSpacing,
                 constraints
             ).also { startSlot += span }
@@ -102,7 +102,7 @@
 @OptIn(ExperimentalFoundationApi::class)
 internal fun interface MeasuredLineFactory {
     fun createLine(
-        index: LineIndex,
+        index: Int,
         items: Array<LazyGridMeasuredItem>,
         spans: List<GridItemSpan>,
         mainAxisSpacing: Int
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
index 32575e7..7b19619 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
@@ -19,7 +19,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.lazy.layout.findIndexByKey
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshots.Snapshot
 
@@ -32,10 +32,10 @@
     initialIndex: Int = 0,
     initialScrollOffset: Int = 0
 ) {
-    var index by mutableStateOf(ItemIndex(initialIndex))
+    var index by mutableIntStateOf(initialIndex)
         private set
 
-    var scrollOffset by mutableStateOf(initialScrollOffset)
+    var scrollOffset by mutableIntStateOf(initialScrollOffset)
         private set
 
     private var hadFirstNotEmptyLayout = false
@@ -58,9 +58,7 @@
 
             Snapshot.withoutReadObservation {
                 update(
-                    ItemIndex(
-                        measureResult.firstVisibleLine?.items?.firstOrNull()?.index?.value ?: 0
-                    ),
+                    measureResult.firstVisibleLine?.items?.firstOrNull()?.index ?: 0,
                     scrollOffset
                 )
             }
@@ -78,7 +76,7 @@
      * c) there will be not enough items to fill the viewport after the requested index, so we
      * would have to compose few elements before the asked index, changing the first visible item.
      */
-    fun requestPosition(index: ItemIndex, scrollOffset: Int) {
+    fun requestPosition(index: Int, scrollOffset: Int) {
         update(index, scrollOffset)
         // clear the stored key as we have a direct request to scroll to [index] position and the
         // next [checkIfFirstVisibleItemWasMoved] shouldn't override this.
@@ -94,14 +92,14 @@
     fun updateScrollPositionIfTheFirstItemWasMoved(itemProvider: LazyGridItemProvider) {
         Snapshot.withoutReadObservation {
             update(
-                ItemIndex(itemProvider.findIndexByKey(lastKnownFirstItemKey, index.value)),
+                itemProvider.findIndexByKey(lastKnownFirstItemKey, index),
                 scrollOffset
             )
         }
     }
 
-    private fun update(index: ItemIndex, scrollOffset: Int) {
-        require(index.value >= 0f) { "Index should be non-negative (${index.value})" }
+    private fun update(index: Int, scrollOffset: Int) {
+        require(index >= 0f) { "Index should be non-negative ($index)" }
         if (index != this.index) {
             this.index = index
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt
index c5c802a..ac6ac2a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt
@@ -167,13 +167,13 @@
     /**
      * Calculate the line of index [itemIndex].
      */
-    fun getLineIndexOfItem(itemIndex: Int): LineIndex {
+    fun getLineIndexOfItem(itemIndex: Int): Int {
         if (totalSize <= 0) {
-            return LineIndex(0)
+            return 0
         }
         require(itemIndex < totalSize)
         if (!gridContent.hasCustomSpans) {
-            return LineIndex(itemIndex / slotsPerLine)
+            return itemIndex / slotsPerLine
         }
 
         val lowerBoundBucket = buckets.binarySearch { it.firstItemIndex - itemIndex }.let {
@@ -207,7 +207,7 @@
             ++currentLine
         }
 
-        return LineIndex(currentLine)
+        return currentLine
     }
 
     fun spanOf(itemIndex: Int, maxSpan: Int): Int =
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
index b2115d2..f033df8 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
@@ -104,7 +104,7 @@
      * derived state in order to only have recompositions when the derived value changes:
      * @sample androidx.compose.foundation.samples.UsingGridScrollPositionInCompositionSample
      */
-    val firstVisibleItemIndex: Int get() = scrollPosition.index.value
+    val firstVisibleItemIndex: Int get() = scrollPosition.index
 
     /**
      * The scroll offset of the first visible item. Scrolling forward is positive - i.e., the
@@ -221,7 +221,7 @@
     /**
      * Finds items on a line and their measurement constraints. Used for prefetching.
      */
-    internal var prefetchInfoRetriever: (line: LineIndex) -> List<Pair<Int, Constraints>> by
+    internal var prefetchInfoRetriever: (line: Int) -> List<Pair<Int, Constraints>> by
         mutableStateOf({ emptyList() })
 
     internal val placementAnimator = LazyGridItemPlacementAnimator()
@@ -255,7 +255,7 @@
     }
 
     internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
-        scrollPosition.requestPosition(ItemIndex(index), scrollOffset)
+        scrollPosition.requestPosition(index, scrollOffset)
         // placement animation is not needed because we snap into a new position.
         placementAnimator.reset()
         remeasurement?.forceRemeasure()
@@ -359,7 +359,7 @@
                 this.wasScrollingForward = scrollingForward
                 this.lineToPrefetch = lineToPrefetch
                 currentLinePrefetchHandles.clear()
-                prefetchInfoRetriever(LineIndex(lineToPrefetch)).fastForEach {
+                prefetchInfoRetriever(lineToPrefetch).fastForEach {
                     currentLinePrefetchHandles.add(
                         prefetchState.schedulePrefetch(it.first, it.second)
                     )
@@ -414,7 +414,7 @@
         layoutInfoState.value = result
 
         canScrollForward = result.canScrollForward
-        canScrollBackward = (result.firstVisibleLine?.index?.value ?: 0) != 0 ||
+        canScrollBackward = (result.firstVisibleLine?.index ?: 0) != 0 ||
             result.firstVisibleLineScrollOffset != 0
 
         numMeasurePasses++
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt
index 1f62b814..9cce0ba 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt
@@ -32,6 +32,7 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
 import org.junit.Assume.assumeFalse
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -64,6 +65,7 @@
     }
 
     @Test
+    @Ignore("b/272301182")
     fun darkTheme() {
         assumeFalse("See b/272301182", Build.VERSION.SDK_INT == 33)
 
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt
index 3c05d96..3b58b83 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt
@@ -265,4 +265,4 @@
     }
 }
 
-private const val Tag = "NavigationBar"
\ No newline at end of file
+private const val Tag = "NavigationBar"
diff --git a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
index 58b53c0..7caf3e7 100644
--- a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
+++ b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
@@ -126,6 +126,7 @@
      * Test that spring animation can work with a single property without an object.
      */
     @Test
+    @Ignore("b/280665072")
     public void testFloatValueHolder() {
         final FloatValueHolder floatValueHolder = new FloatValueHolder(0f);
         DynamicAnimation.OnAnimationUpdateListener updateListener =
@@ -354,6 +355,7 @@
      */
     @LargeTest
     @Test
+    @Ignore("b/280665072")
     public void testStiffness() {
         float[] dampingRatios = {0.3f, 0.5f, 1f, 5f};
         final float[] stiffness = {50f, 500f, 1500f, 5000f};
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt
index 3f5283a..171a220 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt
@@ -17,22 +17,30 @@
 package androidx.glance.appwidget.demos
 
 import android.content.Context
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.dp
 import androidx.glance.GlanceId
 import androidx.glance.GlanceModifier
+import androidx.glance.GlanceTheme
 import androidx.glance.appwidget.CircularProgressIndicator
 import androidx.glance.appwidget.GlanceAppWidget
 import androidx.glance.appwidget.GlanceAppWidgetReceiver
 import androidx.glance.appwidget.LinearProgressIndicator
 import androidx.glance.appwidget.provideContent
 import androidx.glance.background
+import androidx.glance.color.ColorProvider
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Column
+import androidx.glance.layout.Row
 import androidx.glance.layout.Spacer
 import androidx.glance.layout.fillMaxSize
 import androidx.glance.layout.padding
 import androidx.glance.layout.size
+import androidx.glance.layout.width
+import androidx.glance.material3.ColorProviders
 import androidx.glance.unit.ColorProvider
 
 class ProgressIndicatorAppWidget : GlanceAppWidget() {
@@ -40,31 +48,97 @@
         context: Context,
         id: GlanceId
     ) = provideContent {
-        Column(
-            modifier = GlanceModifier.fillMaxSize()
-                .background(R.color.default_widget_background),
-            verticalAlignment = Alignment.CenterVertically,
-            horizontalAlignment = Alignment.CenterHorizontally
-        ) {
+        GlanceTheme(ProgressIndicatorDemoColorScheme.colors) {
+            Column(
+                modifier = GlanceModifier.fillMaxSize()
+                    .background(R.color.default_widget_background),
+                verticalAlignment = Alignment.CenterVertically,
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                Row {
+                    LinearProgressIndicatorsDemo(modifier = GlanceModifier.defaultWeight())
+                    Spacer(modifier = GlanceModifier.width(10.dp))
+                    CircularProgressIndicatorsDemo()
+                }
+            }
+        }
+    }
+
+    @Composable
+    private fun CircularProgressIndicatorsDemo(modifier: GlanceModifier = GlanceModifier) {
+        Column(modifier) {
+            CircularProgressIndicator()
+            Spacer(GlanceModifier.size(8.dp))
+            CircularProgressIndicator(
+                color = GlanceTheme.colors.primary
+            )
+            Spacer(GlanceModifier.size(8.dp))
+            CircularProgressIndicator(
+                color = ColorProvider(day = Color.White, night = Color.Red)
+            )
+            Spacer(GlanceModifier.size(8.dp))
+            CircularProgressIndicator(
+                color = ColorProvider(androidx.glance.R.color.glance_colorSecondary)
+            )
+            Spacer(GlanceModifier.size(8.dp))
+            CircularProgressIndicator(
+                color = ColorProvider(Color.Red)
+            )
+        }
+    }
+
+    @Composable
+    private fun LinearProgressIndicatorsDemo(modifier: GlanceModifier) {
+        Column(modifier) {
             LinearProgressIndicator()
             Spacer(GlanceModifier.size(8.dp))
-            LinearProgressIndicator(0.5f)
+            LinearProgressIndicator(
+                progress = 0.5f,
+                color = GlanceTheme.colors.primary,
+                backgroundColor = GlanceTheme.colors.onBackground
+            )
             Spacer(GlanceModifier.size(8.dp))
             LinearProgressIndicator(
                 progress = .66f,
                 modifier = GlanceModifier.padding(bottom = 8.dp),
                 color = ColorProvider(androidx.glance.R.color.glance_colorError),
-                backgroundColor = ColorProvider(androidx.glance.R.color.glance_colorSecondary)
+                backgroundColor = ColorProvider(
+                    resId = androidx.glance.R.color.glance_colorSecondary
+                )
             )
+            Spacer(GlanceModifier.size(8.dp))
+            LinearProgressIndicator(
+                progress = .66f,
+                modifier = GlanceModifier.padding(bottom = 8.dp),
+                color = ColorProvider(day = Color.White, night = Color.Red),
+                backgroundColor = ColorProvider(day = Color.Red, night = Color.White)
+            )
+            Spacer(GlanceModifier.size(8.dp))
             LinearProgressIndicator(progress = 0.8f, color = ColorProvider(Color.White))
-            Spacer(GlanceModifier.size(8.dp))
-            CircularProgressIndicator()
-            Spacer(GlanceModifier.size(8.dp))
-            CircularProgressIndicator(color = ColorProvider(Color.White))
         }
     }
 }
 
 class ProgressIndicatorAppWidgetReceiver : GlanceAppWidgetReceiver() {
     override val glanceAppWidget: GlanceAppWidget = ProgressIndicatorAppWidget()
+}
+
+internal object ProgressIndicatorDemoColorScheme {
+    private val md_theme_light_primary = Color(0xFF026E00)
+    private val md_theme_light_onBackground = Color(0xFF1E1C00)
+
+    private val md_theme_dark_primary = Color(0xFF02E600)
+    private val md_theme_dark_onBackground = Color(0xFFF2E720)
+
+    private val LightColors = lightColorScheme(
+        primary = md_theme_light_primary,
+        onBackground = md_theme_light_onBackground,
+    )
+
+    private val DarkColors = darkColorScheme(
+        primary = md_theme_dark_primary,
+        onBackground = md_theme_dark_onBackground,
+    )
+
+    val colors = ColorProviders(light = LightColors, dark = DarkColors)
 }
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt
index 0d7c717..33a20ed 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt
@@ -25,10 +25,13 @@
 import androidx.core.widget.RemoteViewsCompat.setProgressBarIndeterminateTintList
 import androidx.compose.ui.graphics.toArgb
 import android.content.res.ColorStateList
+import android.util.Log
 import androidx.glance.unit.FixedColorProvider
 import androidx.glance.unit.ResourceColorProvider
 
 import androidx.glance.appwidget.EmittableCircularProgressIndicator
+import androidx.glance.appwidget.GlanceAppWidgetTag
+import androidx.glance.color.DayNightColorProvider
 
 internal fun RemoteViews.translateEmittableCircularProgressIndicator(
     translationContext: TranslationContext,
@@ -49,9 +52,18 @@
         is ResourceColorProvider -> {
           setProgressBarIndeterminateTintList(
             viewId = viewDef.mainViewId,
-            tint = ColorStateList.valueOf(indicatorColor.resId)
+            resId = indicatorColor.resId
           )
         }
+        is DayNightColorProvider -> {
+          setProgressBarIndeterminateTintList(
+              viewId = viewDef.mainViewId,
+              notNightTint = ColorStateList.valueOf(indicatorColor.day.toArgb()),
+              nightTint = ColorStateList.valueOf(indicatorColor.night.toArgb())
+          )
+        }
+        else ->
+            Log.w(GlanceAppWidgetTag, "Unexpected progress indicator color: $indicatorColor")
       }
     }
     applyModifiers(translationContext, this, element.modifier, viewDef)
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt
index 0c1342b..5b9aca4 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt
@@ -26,10 +26,13 @@
 import androidx.core.widget.RemoteViewsCompat.setProgressBarProgressBackgroundTintList
 import androidx.compose.ui.graphics.toArgb
 import android.content.res.ColorStateList
+import android.util.Log
 import androidx.glance.unit.FixedColorProvider
 import androidx.glance.unit.ResourceColorProvider
 
 import androidx.glance.appwidget.EmittableLinearProgressIndicator
+import androidx.glance.appwidget.GlanceAppWidgetTag
+import androidx.glance.color.DayNightColorProvider
 
 internal fun RemoteViews.translateEmittableLinearProgressIndicator(
     translationContext: TranslationContext,
@@ -54,6 +57,15 @@
             resId = indicatorColor.resId
           )
         }
+        is DayNightColorProvider -> {
+            setProgressBarProgressTintList(
+                viewId = viewDef.mainViewId,
+                notNightTint = ColorStateList.valueOf(indicatorColor.day.toArgb()),
+                nightTint = ColorStateList.valueOf(indicatorColor.night.toArgb())
+            )
+        }
+        else ->
+            Log.w(GlanceAppWidgetTag, "Unexpected progress indicator color: $indicatorColor")
       }
 
       when (val backgroundColor = element.backgroundColor) {
@@ -69,6 +81,16 @@
             resId = backgroundColor.resId
           )
         }
+        is DayNightColorProvider -> {
+          setProgressBarProgressBackgroundTintList(
+            viewId = viewDef.mainViewId,
+            notNightTint = ColorStateList.valueOf(backgroundColor.day.toArgb()),
+            nightTint = ColorStateList.valueOf(backgroundColor.night.toArgb())
+          )
+        }
+        else ->
+            Log.w(GlanceAppWidgetTag,
+                "Unexpected progress indicator background color: $backgroundColor")
       }
     }
     applyModifiers(translationContext, this, element.modifier, viewDef)
diff --git a/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java b/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java
index 495d89f..1619734 100644
--- a/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java
+++ b/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java
@@ -33,6 +33,7 @@
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -208,6 +209,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testInfiniteLoop() throws Throwable {
         final String code = "while(true){}";
         Context context = ApplicationProvider.getApplicationContext();
@@ -236,6 +238,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testMultipleInfiniteLoops() throws Throwable {
         final String code = "while(true){}";
         final int num_of_evaluations = 10;
@@ -270,6 +273,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testSimpleArrayBuffer() throws Throwable {
         final String provideString = "Hello World";
         final byte[] bytes = provideString.getBytes(StandardCharsets.US_ASCII);
@@ -301,6 +305,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testArrayBufferWasmCompilation() throws Throwable {
         final String success = "success";
         // The bytes of a minimal WebAssembly module, courtesy of v8/test/cctest/test-api-wasm.cc
@@ -334,6 +339,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testPromiseReturn() throws Throwable {
         final String code = "Promise.resolve(\"PASS\")";
         final String expected = "PASS";
@@ -354,6 +360,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testPromiseReturnLaterResolve() throws Throwable {
         final String code1 = "var promiseResolve, promiseReject;"
                 + "new Promise(function(resolve, reject){"
@@ -381,6 +388,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testNestedConsumeNamedDataAsArrayBuffer() throws Throwable {
         final String success = "success";
         // The bytes of a minimal WebAssembly module, courtesy of v8/test/cctest/test-api-wasm.cc
@@ -424,6 +432,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testPromiseEvaluationThrow() throws Throwable {
         final String provideString = "Hello World";
         final byte[] bytes = provideString.getBytes(StandardCharsets.US_ASCII);
@@ -546,6 +555,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testHeapSizeAdjustment() throws Throwable {
         final String code = "\"PASS\"";
         final String expected = "PASS";
@@ -585,6 +595,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testHeapSizeEnforced() throws Throwable {
         // WebView versions < 110.0.5438.0 do not contain OOM crashes to a single isolate and
         // instead crash the whole sandbox process. This change is not tracked in a feature flag.
@@ -680,6 +691,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testIsolateCreationAfterCrash() throws Throwable {
         // WebView versions < 110.0.5438.0 do not contain OOM crashes to a single isolate and
         // instead crash the whole sandbox process. This change is not tracked in a feature flag.
@@ -759,6 +771,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testAsyncPromiseCallbacks() throws Throwable {
         // Unlike testPromiseReturn and testPromiseEvaluationThrow, this test is guaranteed to
         // exercise promises in an asynchronous way, rather than in ways which cause a promise to
@@ -827,6 +840,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testLargeScriptJsEvaluation() throws Throwable {
         String longString = "a".repeat(2000000);
         final String code = ""
@@ -851,6 +865,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testLargeScriptByteArrayJsEvaluation() throws Throwable {
         final String longString = "a".repeat(2000000);
         final String codeString = ""
@@ -876,6 +891,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testLargeReturn() throws Throwable {
         final String longString = "a".repeat(2000000);
         final String code = "'a'.repeat(2000000);";
@@ -898,6 +914,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testLargeError() throws Throwable {
         final String longString = "a".repeat(2000000);
         final String code = "throw \"" + longString + "\");";
@@ -924,6 +941,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testResultSizeEnforced() throws Throwable {
         final int maxSize = 100;
         Context context = ApplicationProvider.getApplicationContext();
@@ -974,6 +992,7 @@
 
     @Test
     @LargeTest
+    @Ignore("b/268212217")
     public void testConsoleLogging() throws Throwable {
         final class LoggingJavaScriptConsoleCallback implements JavaScriptConsoleCallback {
             private final Object mLock = new Object();
@@ -1126,6 +1145,7 @@
 
     @Test
     @MediumTest
+    @Ignore("b/268212217")
     public void testConsoleCallbackCanCallService() throws Throwable {
         // This checks that there is nothing intrinsically wrong with calling service APIs from a
         // console client. Note that, in theory, Binder will reuse the same threads if code recurses
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java
index 02e6d11..50f2fee 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java
@@ -59,6 +59,7 @@
 import androidx.test.rule.ActivityTestRule;
 
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -190,6 +191,7 @@
     }
 
     @Test
+    @Ignore("b/281082608")
     public void testPressRightBeforeMainFragmentCreated() throws Throwable {
         final long dataLoadingDelay = 1000;
         Intent intent = new Intent();
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java
index cd4bca8..897d008 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java
@@ -30,6 +30,7 @@
 import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
+import org.junit.Ignore;
 
 import android.app.Fragment;
 import androidx.leanback.test.R;
@@ -190,6 +191,7 @@
     }
 
     @Test
+    @Ignore("b/281082608")
     public void testFocusWithSpeechRecognizerEnabled() throws Exception {
 
         // Skip the test for devices which do not have SpeechRecognizer
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java
index 804ffa3..32d6e59 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java
@@ -27,6 +27,7 @@
 import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
+import org.junit.Ignore;
 
 import androidx.fragment.app.Fragment;
 import androidx.leanback.test.R;
@@ -187,6 +188,7 @@
     }
 
     @Test
+    @Ignore("b/281082608")
     public void testFocusWithSpeechRecognizerEnabled() throws Exception {
 
         // Skip the test for devices which do not have SpeechRecognizer
diff --git a/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt b/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt
index a615eb5..fe5a24b 100644
--- a/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt
+++ b/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt
@@ -36,6 +36,7 @@
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.withTimeout
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -50,6 +51,7 @@
 
     @OptIn(ExperimentalCoroutinesApi::class)
     @Test
+    @Ignore("b/278918559")
     fun onPagesUpdatedFlow() = runBlocking {
         val scenario = scenarioRule.scenario
 
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index fec6fdf..68b1459 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -26,5 +26,5 @@
 # Disable docs
 androidx.enableDocumentation=false
 androidx.playground.snapshotBuildId=10041883
-androidx.playground.metalavaBuildId=10009114
+androidx.playground.metalavaBuildId=10074764
 androidx.studio.type=playground
diff --git a/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt b/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt
index 84d3466..68778460 100644
--- a/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt
+++ b/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt
@@ -43,6 +43,7 @@
 import org.junit.Assert.assertTrue
 import org.junit.Assume
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -277,6 +278,7 @@
     }
 
     @Test
+    @Ignore("b/272324246")
     fun onConfigurationChangedTest() {
         val layout = activity.findViewById<LinearLayout>(R.id.mainlayout)
 
diff --git a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
index 5084dc1..a2ea2da 100644
--- a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
+++ b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
@@ -182,6 +182,7 @@
     }
 
     @Test
+    @Ignore("b/272324246")
     fun testConfigurationChanged() {
         val configChangedLatch = CountDownLatch(1)
         val adapter = TestSandboxedUiAdapter(
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java
index dd7781b..e5076f6 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.Build;
+import androidx.test.filters.FlakyTest;
 
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SdkSuppress;
@@ -92,6 +93,7 @@
 
     @MediumTest
     @Test
+    @FlakyTest(bugId = 281085288)
     public void cacheAndPrefetch() throws Throwable {
         final Config config = (Config) mConfig.clone();
         setupByConfig(config);
diff --git a/room/room-common/src/main/java/androidx/room/Delete.kt b/room/room-common/src/main/java/androidx/room/Delete.kt
index 176fd26..fbae415 100644
--- a/room/room-common/src/main/java/androidx/room/Delete.kt
+++ b/room/room-common/src/main/java/androidx/room/Delete.kt
@@ -34,7 +34,7 @@
  *     public fun deleteSongs(vararg songs: Song)
  *
  *     @Delete
- *     public fun deleteAlbumAndSongs(val album: Album, val songs: List<Song>)
+ *     public fun deleteAlbumAndSongs(album: Album, songs: List<Song>)
  * }
  * ```
  *
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java
index aa246e1..0e7dd93 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java
@@ -354,6 +354,7 @@
     }
 
     @Test
+    @Ignore("b/280669851")
     public void testSetOrientationLeft() throws Exception {
         launchTestActivity(KeycodeTestActivity.class);
         try {
@@ -372,6 +373,7 @@
     }
 
     @Test
+    @Ignore("b/280669851")
     public void testSetOrientationRight() throws Exception {
         launchTestActivity(KeycodeTestActivity.class);
         try {
@@ -401,6 +403,7 @@
     }
 
     @Test
+    @Ignore("b/280669851")
     public void testSetOrientationLandscape() throws Exception {
         launchTestActivity(KeycodeTestActivity.class);
         try {
diff --git a/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java b/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java
index 1e55554..08ea852 100644
--- a/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java
+++ b/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java
@@ -37,6 +37,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.ByteArrayOutputStream;
@@ -68,6 +69,7 @@
     }
 
     @Test
+    @Ignore("b/280041271")
     public void beginAndEndSection() throws IOException {
         startTrace();
         Trace.beginSection("beginAndEndSection");
@@ -79,6 +81,7 @@
     }
 
     @Test
+    @Ignore("b/280041271")
     public void beginAndEndTraceSectionLongLabel() throws IOException {
         StringBuilder builder = new StringBuilder();
         for (int i = 0; i < 20; i++) {
@@ -120,6 +123,7 @@
     }
 
     @Test
+    @Ignore("b/280041271")
     public void isEnabledDuringTrace() throws IOException {
         startTrace();
         boolean enabled = Trace.isEnabled();
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
index 79e4f0d..b3e2d09 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
@@ -42,6 +42,7 @@
 import org.hamcrest.Matchers.greaterThan
 import org.hamcrest.MatcherAssert.assertThat
 import org.junit.Assume.assumeThat
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -128,6 +129,7 @@
     }
 
     @Test
+    @Ignore("b/280670752")
     fun test_peekNextAndMoveBack() {
         // Roughly interpolates like this:
         //   |
diff --git a/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt b/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
index 57efd34..0b32c3e 100644
--- a/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
+++ b/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
@@ -57,6 +57,7 @@
 import kotlinx.coroutines.CompletableDeferred
 import org.junit.After
 import org.junit.Assert
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito
@@ -191,6 +192,7 @@
     }
 
     @Test
+    @Ignore("b/281083901")
     public fun listenableOpenComplicationDataSourceChooser() {
         ComplicationDataSourceChooserContract.useTestComplicationHelperActivity = true
         val chosenComplicationDataSourceInfo =
diff --git a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
index d8d78fc..53dddff 100644
--- a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
+++ b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
@@ -86,6 +86,7 @@
 import org.junit.Assert.fail
 import org.junit.Assume
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -378,6 +379,7 @@
 
     @SuppressLint("NewApi")
     @Test
+    @Ignore("b/274981990")
     public fun testCommandTakeOpenGLScreenShot() {
         val latch = CountDownLatch(1)
 
diff --git a/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java b/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java
index 2e2720a..36e4a604 100644
--- a/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java
+++ b/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.widget.Button;
+import org.junit.Ignore;
 
 import androidx.annotation.Nullable;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -56,6 +57,7 @@
             new ActivityTestRule<>(ConfirmationActivityTestActivity.class, true, true);
 
     @Test
+    @Ignore("b/272346886")
     public void testConfirmationDialogShownForDefaultDuration() throws Throwable {
         int testDuration = ConfirmationActivity.DEFAULT_ANIMATION_DURATION_MILLIS;
         // Check that the structure of the test is still valid
@@ -66,12 +68,14 @@
     }
 
     @Test
+    @Ignore("b/272346886")
     public void testConfirmationDialogShownForLongerDuration() throws Throwable {
         testConfirmationDialogShownForConfiguredDuration(
                 ConfirmationActivity.DEFAULT_ANIMATION_DURATION_MILLIS * 2, "A message");
     }
 
     @Test
+    @Ignore("b/272346886")
     public void testConfirmationDialogWithMissingMessage() throws Throwable {
         testConfirmationDialogShownForConfiguredDuration(
                 ConfirmationActivity.DEFAULT_ANIMATION_DURATION_MILLIS * 2, /* message= */null);
diff --git a/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt b/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt
index b03ecf3..3409862 100644
--- a/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt
+++ b/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt
@@ -58,6 +58,7 @@
 import org.hamcrest.CoreMatchers.any
 import org.hamcrest.Matcher
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -830,6 +831,7 @@
     }
 
     @Test(timeout = 5000)
+    @Ignore("b/280671279")
     fun testBasicTouch() {
         val context: Context = ApplicationProvider.getApplicationContext()
         // This views are the same as the test testTouchEvents()
@@ -873,6 +875,7 @@
     }
 
     @Test(timeout = 10000)
+    @Ignore("b/280671279")
     fun testMarginTouch() {
         val views = createTwoArcsWithMargin()
         testEventsFast("touch_fast_margin_screenshot", views)
diff --git a/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java b/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java
index 913e8b5..64b80a7 100644
--- a/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java
+++ b/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java
@@ -24,6 +24,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 import androidx.webkit.WebViewFeature;
+import org.junit.Ignore;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -42,6 +43,7 @@
             new ActivityScenarioRule<>(ProcessGlobalConfigActivity.class);
 
     @Test
+    @Ignore("b/280671406")
     public void testSetDataDirectorySuffix() throws Throwable {
         WebkitTestHelpers.assumeStartupFeature(
                 WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX,